提前声明:以下内容是本人读《Python深度学习》的个人笔记

第一部分:基础

数据存储在多维 Numpy 数组中,也叫张量(tensor)

仅包含一个数字的张量叫作标量(scalar,也叫标量张量、零维张量、 0D 张量)。

在 Numpy中,一个 float32 或 float64 的数字就是一个标量张量(或标量数组)。

你可以用 ndim 属性来查看一个 Numpy 张量的轴的个数。

标量张量有 0 个轴(ndim == 0)。张量轴的个数也叫作阶(rank)。

数字组成的数组叫作向量(vector)或一维张量(1D 张量)。一维张量只有一个轴。

向量组成的数组叫作矩阵(matrix)或二维张量(2D 张量)。矩阵有 2 个轴(通常叫作行和

列)。你可以将矩阵直观地理解为数字组成的矩形网格。

将多个矩阵组合成一个新的数组,可以得到一个 3D 张量,你可以将其直观地理解为数字

组成的立方体。

matlablib显示图片

plt.imshow(digit, cmap=plt.cm.binary)

图像: 4D 张量,形状为 (samples, height, width, channels)

样本轴(samples axis,有时也叫样本维度),表示该图片是这batch样本中的第几个

图像通常具有三个维度:高度、宽度和颜色深度

128 张灰度图像组成的批量可以保存在一个形状为 (128, 256, 256, 1) 的张量中

128 张彩色图像组成的批量则可以保存在一个形状为 (128, 256, 256, 3) 的张量中

张量运算:张量的变换、旋转、缩放

keras.layers.Dense(512, activation='relu')

output = relu(dot(W, input) + b)

我们将上式拆开来看。这里有三个张量运算:输入张量和张量 W 之间的点积运算(dot)、

得到的 2D 张量与向量 b 之间的加法运算(+)、最后的 relu 运算。 relu(x) 是 max(x, 0)。

为什么通常Relu比sigmoid和tanh强,有什么不同?

主要是因为它们gradient特性不同。sigmoid和tanh的gradient在饱和区域非常平缓,接近于0,很容易造成vanishing gradient的问题,

减缓收敛速度。vanishing gradient在网络层数多的时候尤其明显,是加深网络结构的主要障碍之一。

相反,Relu的gradient大多数情况下是常数,有助于解决深层网络的收敛问题。Relu的另一个优势是在生物上的合理性,它是单边的,相比sigmoid和tanh,更符合生物神经元的特征。

而提出sigmoid和tanh,主要是因为它们全程可导。还有表达区间问题,sigmoid和tanh区间是0到1,或着-1到1,在表达上,尤其是输出层的表达上有优势

第一个问题:为什么引入非线性激励函数?

如果不用激励函数(其实相当于激励函数是f(x) = x),在这种情况下你每一层输出都是上层输入的线性函数,很容易验证,

无论你神经网络有多少层,输出都是输入的线性组合,与没有隐藏层效果相当,这种情况就是最原始的感知机(Perceptron)了。

正因为上面的原因,我们决定引入非线性函数作为激励函数,这样深层神经网络就有意义了(不再是输入的线性组合,可以逼近任意函数)。

最早的想法是sigmoid函数或者tanh函数,输出有界,很容易充当下一层输入(以及一些人的生物解释balabala)。

张量变形

x = x.reshape((6, 1))

x = np.transpose(x)

一个训练循环(training loop)

(1) 抽取训练样本 x 和对应目标 y 组成的数据批量。

(2) 在 x 上运行网络[这一步叫作前向传播(forward pass)],得到预测值 y_pred。

(3) 计算网络在这批数据上的损失,用于衡量 y_pred 和 y 之间的距离。

(4) 更新网络的所有权重,使网络在这批数据上的损失略微下降。

小批量随机梯度下降(mini-batch stochastic gradient descent,又称为小批量 SGD)

(1) 抽取训练样本 x 和对应目标 y 组成的数据批量。

(2) 在 x 上运行网络,得到预测值 y_pred。

(3) 计算网络在这批数据上的损失,用于衡量 y_pred 和 y 之间的距离。

(4) 计算损失相对于网络参数的梯度[一次反向传播(backward pass)]。

(5) 将参数沿着梯度的反方向移动一点,比如 W -= step * gradient,从而使这批数据

上的损失减小一点。

每一次迭代都在所有数据上运行,这叫作批量 SGD。

每次迭代时只抽取一个样本和目标,而不是抽取一批

数据,这叫作真 SGD

SGD 还有多种变体,其区别在于计算下一次权重更新时还要考虑上一次权重更新,

而不是仅仅考虑当前梯度值,比如带动量的 SGD、 Adagrad、 RMSProp 等变体。这些变体被称

为优化方法(optimization method)或优化器(optimizer)。其中动量的概念尤其值得关注,它在

许多变体中都有应用。动量解决了 SGD 的两个问题:收敛速度和局部极小点。

损失函数(目标函数)——在训练过程中需要将其最小化。它能够衡量当前任务是否已成功完成。

优化器——决定如何基于损失函数对网络进行更新。它执行的是随机梯度下降(SGD)的某个变体。

对于二分类问题,你可以使用二元交叉熵(binary crossentropy)损

失函数;对于多分类问题,可以用分类交叉熵(categorical crossentropy)损失函数;对于回归

问题,可以用均方误差(mean-squared error)损失函数;对于序列学习问题,可以用联结主义

时序分类(CTC, connectionist temporal classification)损失函数,等等

Keras 是一个模型级(model-level)的库,为开发深度学习模型提供了高层次的构建模块。

它不处理张量操作、求微分等低层次的运算,这些操作由后端的Tensorflow、Theano等完成。

面对的是一个二分类问题,网络输出是一个概率值(网络最后一层使用 sigmoid 激活函数,

仅包含一个单元),那么最好使用 binary_crossentropy(二元交叉熵)损失。

第二部分:

如果要对 N 个类别的数据点进行分类,网络的最后一层应该是大小为 N 的 Dense 层。

对于单标签、多分类问题,网络的最后一层应该使用 softmax 激活,这样可以输出在 N

个输出类别上的概率分布。

如果你需要将数据划分到许多类别中,应该避免使用太小的中间层,以免在网络中造成

信息瓶颈。假如你最终输出46个类别,你的中间层的输出不能太小,如果中间层的输出太小,

相当于将大量信息压缩到小空间,会丢失部分信息,导致你的精度的acc最大值为某个数,造成瓶颈。

回归问题中,将取值范围差异很大的数据输入到神经网络中,这是有问题的。网络可能会自动适应这种

取值范围不同的数据,但学习肯定变得更加困难。对于这种数据,普遍采用的最佳实践是对每

个特征做标准化,即对于输入数据的每个特征(输入数据矩阵中的列),减去特征平均值,再除

以标准差。

神经网络的数据预处理

1、向量化

神经网络的所有输入和目标都必须是浮点数张量(在特定情况下可以是整数张量)。无论

处理什么数据(声音、图像还是文本),都必须首先将其转换为张量,这一步叫作数据向量化

(data vectorization)。

2、值标准化

一般来说,将取值相对较大的数据(比如多位整数,比网络权重的初始值大很多)或异质

数据(heterogeneous data,比如数据的一个特征在 0~1 范围内,另一个特征在 100~200 范围内)

输入到神经网络中是不安全的。这么做可能导致较大的梯度更新,进而导致网络无法收敛。为

了让网络的学习变得更容易,输入数据应该具有以下特征

取值较小:大部分值都应该在 0~1 范围内。

同质性(homogenous):所有特征的取值都应该在大致相同的范围内

此外,下面这种更严格的标准化方法也很常见,而且很有用,虽然不一定总是必需的:

将每个特征分别标准化,使其平均值为 0。

将每个特征分别标准化,使其标准差为 1。

3、处理缺失值

一般来说,对于神经网络,将缺失值设置为 0 是安全的,只要 0 不是一个有意义的值。网

络能够从数据中学到 0 意味着缺失数据,并且会忽略这个值。

注意,如果测试数据中可能有缺失值,而网络是在没有缺失值的数据上训练的,那么网络

不可能学会忽略缺失值。在这种情况下,你应该人为生成一些有缺失项的训练样本:多次复制

一些训练样本,然后删除测试数据中可能缺失的某些特征。

特征工程(feature engineering)

是指将数据输入模型之前,利用你自己关于数据和机器学

习算法(这里指神经网络)的知识对数据进行硬编码的变换(不是模型学到的),以改善模型的

效果。

特征工程的本质:用更简单的方式表述问题,从而使问题变得更容易。它通常需要

深入理解问题。

可以采用坐标变换 等等

过拟合和欠拟合

机器学习的根本问题是优化和泛化之间的对立。 优化(optimization)是指调节模型以在训

练数据上得到最佳性能(即机器学习中的学习),而泛化(generalization)是指训练好的模型在

前所未见的数据上的性能好坏。

训练开始时,优化和泛化是相关的:训练数据上的损失越小,测试数据上的损失也越小。

这时的模型是欠拟合(underfit)的,即仍有改进的空间,网络还没有对训练数据中所有相关模

式建模。但在训练数据上迭代一定次数之后,泛化不再提高,验证指标先是不变,然后开始变差,

即模型开始过拟合。这时模型开始学习仅和训练数据有关的模式,但这种模式对新数据来说是

错误的或无关紧要的。

1、获取更多的训练数据

为了防止模型从训练数据中学到错误或无关紧要的模式, 最优解决方法是获取更多的训练

数据。模型的训练数据越多,泛化能力自然也越好。如果无法获取更多数据,次优解决方法是

调节模型允许存储的信息量,或对模型允许存储的信息加以约束。如果一个网络只能记住几个

模式,那么优化过程会迫使模型集中学习最重要的模式,这样更可能得到良好的泛化。

这种降低过拟合的方法叫作正则化(regularization)。

2、减小模型大小

防止过拟合的最简单的方法就是减小模型大小,即减少模型中可学习参数的个数(这由层

数和每层的单元个数决定)。在深度学习中,模型中可学习参数的个数通常被称为模型的容量

(capacity)。同时,你使用的模型应该具有足够多的参数,以防欠拟合,即模型应避免记忆资源不足。

在容量过大与容量不足之间要找到一个折中。

3、添加权重正则化

奥卡姆剃刀(Occam’s razor)原理:如果一件事情有两种解释,那么最可能正

确的解释就是最简单的那个,即假设更少的那个。

这里的简单模型(simple model)是指参数值分布的熵更小的模型。

因此,一种常见的降低过拟合的方法就是强制让模型权重只能取较小的值,

从而限制模型的复杂度,这使得权重值的分布更加规则(regular)。这种方法叫作权重正则化

(weight regularization),其实现方法是向网络损失函数中添加与较大权重值相关的成本(cost)。

L1 正则化(L1 regularization):添加的成本与权重系数的绝对值[权重的 L1 范数(norm)]

成正比。

L2 正则化(L2 regularization):添加的成本与权重系数的平方(权重的 L2 范数)成正比。

神经网络的 L2 正则化也叫权重衰减(weight decay)。不要被不同的名称搞混,权重衰减

与 L2 正则化在数学上是完全相同的。

4、添加 dropout 正则化

对某一层使用 dropout,就是在训练过程中随机将该层的一些输出特征舍

弃(设置为 0)。假设在训练过程中,某一层对给定输入样本的返回值应该是向量 [0.2, 0.5,

1.3, 0.8, 1.1]。使用 dropout 后,这个向量会有几个随机的元素变成 0,比如 [0, 0.5,

1.3, 0, 1.1]。

dropout 比率(dropout rate)是被设为 0 的特征所占的比例,通常在 0.2~0.5

范围内。测试时没有单元被舍弃,而该层的输出值需要按 dropout 比率缩小,因为这时比训练时

有更多的单元被激活,需要加以平衡。

训练时,我们随机将矩阵中一部分值设为 0。测试时,我们将输出按 dropout 比率缩小。

训练时:舍弃50%的输出单元

layer_output *= np.random.randint(0, high=2, size=layer_output.shape)

测试时:将输出按 dropout 比率缩小

layer_output *= 0.5

注意,为了实现这一过程,还可以让两个运算都在训练时进行,而测试时输出保持不变。

两步都在训练时:先舍弃 50%的输出单元,然后成比例放大

layer_output *= np.random.randint(0, high=2, size=layer_output.shape)

layer_output /= 0.5

机器学习的通用工作流程

1、定义问题,收集数据集

2、选择评估成功的指标

3、确定评估方法

4、准备数据

5、开发比基准更好的模型

6、扩大模型规模:开发过拟合的模型

7、模型正则化与调节超参数

评估指标:

精度(准确率(precision)和召回率(recall)),和接收者操作特征曲线下面积(area

under the receiver operating characteristic curve, ROC AUC)是常用的指标。

评估方法:

留出验证集

K 折交叉验证

重复的 K 折验证

准备数据(深度学习)

将数据格式化为张量

这些张量的取值通常应该缩放为较小的值,比如在 [-1, 1] 区间或 [0, 1] 区间。

如果不同的特征具有不同的取值范围(异质数据),那么应该做数据标准化。

开发比基准更好的模型

这一阶段的目标是获得统计功效(statistical power),即开发一个小型模型,它能够打败纯

随机的基准(dumb baseline)。

(1)最后一层的激活:

例如, IMDB 分类的例子在最后一层使用了 sigmoid,回归的例子在最后一层没有使用激活,等等。

(2)损失函数:

例如, IMDB 的例子使用 binary_

crossentropy、回归的例子使用 mse, 等等。

(3)优化配置:

你要使用哪种优化器?学习率是多少?大多数情况下,使用 rmsprop 及其

默认的学习率是稳妥的。

问题类型 最后一层激活 损失函数

二分类问题: sigmoid binary_crossentropy

多分类、单标签问题: softmax categorical_crossentropy

多分类、多标签问题 : sigmoid binary_crossentropy

回归到任意值: 无 mse

回归到 0~1 范围内的值: sigmoid mse 或 binary_crossentropy

扩大模型规模:开发过拟合的模型

(1) 添加更多的层。

(2) 让每一层变得更大。

(3) 训练更多的轮次。

模型正则化与调节超参数

添加 dropout

尝试不同的架构:增加或减少层数

添加 L1 和 / 或 L2 正则化

尝试不同的超参数(比如每层的单元个数或优化器的学习率),以找到最佳配置

第二部分:实践

一:图像

卷积神经网络简介

卷积神经网络接收形状(input_shape)为 (image_height, image_width, image_channels)

的输入张量(不包括批量维度)

宽度和高度两个维度的尺寸通常会随着网络加深而变小。通道数量由传入 Conv2D 层的第一个参数所控制

卷积运算

密集连接层和卷积层的根本区别在于, Dense 层从输入特征空间中学到的是全局模式(整张图片全部像素的模式),

而卷积层学到的是局部模式,对于图像来说,学到的就是在输入图像的卷积小窗口中发现的模式。

卷积神经网络的特性:

1、卷积神经网络学到的模式具有平移不变性(translation invariant)。

卷积神经网络在图像右下角学到某个模式之后,它可以在任何地方识别这个模式,比如左上角。对于密集连

接网络来说,如果模式出现在新的位置,它只能重新学习这个模式。这使得卷积神经网

络在处理图像时可以高效利用数据(因为视觉世界从根本上具有平移不变性),它只需

要更少的训练样本就可以学到具有泛化能力的数据表示。

2、卷积神经网络可以学到模式的空间层次结构(spatial hierarchies of patterns),见图 5-2。

第一个卷积层将学习较小的局部模式(比如边缘),第二个卷积层将学习由第一层特征

组成的更大的模式,以此类推。这使得卷积神经网络可以有效地学习越来越复杂、越来

越抽象的视觉概念(因为视觉世界从根本上具有空间层次结构)。

卷积由以下两个关键参数所定义。

Conv2D(output_depth,(kernel_size_w,kernel_size_h),(window_height, window_width))

1、从输入中提取的图块尺寸:这些图块的大小通常是 3×3 或 5×5。本例中为 3×3,这是

很常见的选择。

2、输出特征图的深度:卷积所计算的过滤器的数量。本例第一层的深度为 32,最后一层的

深度是 64。

注意,输出的宽度和高度可能与输入的宽度和高度不同。不同的原因可能有两点。

1、边界效应,可以通过对输入特征图进行填充来抵消。(padding)

对于 Conv2D 层,可以通过 padding 参数来设置填充,这个参数有两个取值: "valid" 表

示不使用填充(只使用有效的窗口位置);"same" 表示“填充后输出的宽度和高度与输入相同”。

padding 参数的默认值为 "valid"。

2、使用了步幅(stride),卷积核滑动的步长。默认值为 1

strides = 3

池化有最大池化和平均池化

最大池化通常使用 2×2 的窗口和步幅 2,其目的是将特征图下采样 2 倍。这样在每个 MaxPooling2D 层之后,

特征图的尺寸都会减半。与此相对的是,卷积通常使用 3×3 窗口和步幅 1。

为什么要用这种方式对特征图下采样?为什么不删除最大池化层,一直保留较大的特征图?

使用下采样的原因,一是减少需要处理的特征图的元素个数,二是通过让连续卷积层的观察窗口

越来越大(即窗口覆盖原始输入的比例越来越大),从而引入空间过滤器的层级结构。

猫狗数据集的数据预处理

(1) 读取图像文件。

(2) 将 JPEG 文件解码为 RGB 像素网格。

(3) 将这些像素网格转换为浮点数张量。

(4) 将像素值(0~255 范围内)缩放到 [0, 1] 区间(正如你所知,神经网络喜欢处理较小的输入值)

预训练网络

预训练网络(pretrained network)是一个保存好的网络,之前已在大型数据集(通常是大规模图

像分类任务)上训练好。如果这个原始数据集足够大且足够通用,那么预训练网络学到的特征

的空间层次结构可以有效地作为视觉世界的通用模型,因此这些特征可用于各种不同的计算机

视觉问题,即使这些新问题涉及的类别和原始任务完全不同。

使用预训练网络有两种方法: 特征提取(feature extraction)和微调模型(fine-tuning)。

1、特征提取

用于图像分类的卷积神经网络包含两部分:首先是一系列池化层和卷积层,最

后是一个密集连接分类器。第一部分叫作模型的卷积基(convolutional base)。对于卷积神经网

络而言,特征提取就是取出之前训练好的网络的卷积基,在上面运行新数据,然后在卷积基的输出

训练一个新的分类器。

为什么仅重复使用卷积基?我们能否也重复使用密集连接分类器?一般来说,应该避免这

么做。原因在于卷积基学到的表示可能更加通用,因此更适合重复使用。卷积神经网络的特征

图表示通用概念在图像中是否存在,无论面对什么样的计算机视觉问题,这种特征图都可能很

有用。但是,分类器学到的表示必然是针对于模型训练的类别,其中仅包含某个类别出现在整

张图像中的概率信息。此外,密集连接层的表示不再包含物体在输入图像中的位置信息。密集

连接层舍弃了空间的概念,而物体位置信息仍然由卷积特征图所描述。如果物体位置对于问题

很重要,那么密集连接层的特征在很大程度上是无用的。

注意,某个卷积层提取的表示的通用性(以及可复用性)取决于该层在模型中的深度。

模型中更靠近底部的层提取的是局部的、高度通用的特征图(比如视觉边缘、颜色和纹理),而更

靠近顶部的层提取的是更加抽象的概念(比如“猫耳朵”或“狗眼睛”)。 因此,如果你的新数

据集与原始模型训练的数据集有很大差异,那么最好只使用模型的前几层来做特征提取,而不

是使用整个卷积基。

2、微调模型

另一种广泛使用的模型复用方法是模型微调(fine-tuning),与特征提取互为补充。对于用

于特征提取的冻结的模型基,微调是指将其顶部的几层“解冻”,并将这解冻的几层和新增加的

部分(本例中是全连接分类器)联合训练。

微调网络的步骤如下。

(1) 在已经训练好的基网络(base network)上添加自定义网络。

(2) 冻结基网络。

(3) 训练所添加的部分。

(4) 解冻基网络的一些层。

(5) 联合训练解冻的这些层和添加的部分。

为什么不微调更多层?为什么不微调整个卷积基?你当然可以这么做,但需要考虑以下几点。

卷积基中更靠底部的层编码的是更加通用的可复用特征,而更靠顶部的层编码的是更专

业化的特征。微调这些更专业化的特征更加有用,因为它们需要在你的新问题上改变用

途。微调更靠底部的层,得到的回报会更少。

训练的参数越多,过拟合的风险越大。卷积基有 1500 万个参数,所以在你的小型数据

集上训练这么多参数是有风险的。

因此,在这种情况下,一个好策略是仅微调卷积基最后的两三层。

卷积神经网络的可视化

1、可视化卷积神经网络的中间输出(中间激活)

可视化中间激活,是指对于给定输入,展示网络中各个卷积层和池化层输出的特征图(层

的输出通常被称为该层的激活,即激活函数的输出)

为了提取想要查看的特征图,我们需要创建一个 Keras 模型,以图像批量作为输入,并输出

所有卷积层和池化层的激活。为此,我们需要使用 Keras 的 Model 类。模型实例化需要两个参

数:一个输入张量(或输入张量的列表)和一个输出张量(或输出张量的列表)。得到的类是一个

Keras 模型,就像你熟悉的 Sequential 模型一样,将特定输入映射为特定输出。

第一层是各种边缘探测器的集合。在这一阶段,激活几乎保留了原始图像中的所有信息。

随着层数的加深,激活变得越来越抽象,并且越来越难以直观地理解。它们开始表示更

高层次的概念,比如“猫耳朵”和“猫眼睛”。层数越深,其表示中关于图像视觉内容

的信息就越少,而关于类别的信息就越多。

激活的稀疏度(sparsity)随着层数的加深而增大。在第一层里,所有过滤器都被输入图

像激活,但在后面的层里,越来越多的过滤器是空白的。也就是说,输入图像中找不到

这些过滤器所编码的模式。

2、可视化卷积神经网络的过滤器(滑动窗口)

想要观察卷积神经网络学到的过滤器,另一种简单的方法是显示每个过滤器所响应的视觉

模式。这可以通过在输入空间中进行梯度上升来实现:从空白输入图像开始,将梯度下降应用

于卷积神经网络输入图像的值,其目的是让某个过滤器的响应最大化。得到的输入图像是选定

过滤器具有最大响应的图像。

这个过程很简单:我们需要构建一个损失函数,其目的是让某个卷积层的某个过滤器的值最

大化;然后,我们要使用随机梯度下降来调节输入图像的值,以便让这个激活值最大化。

3、可视化图像中类激活的热力图

我还要介绍另一种可视化方法,它有助于了解一张图像的哪一部分让卷积神经网络做出了

最终的分类决策。

这种通用的技术叫作类激活图(CAM, class activation map)可视化,它是指对输入图像生

成类激活的热力图。类激活热力图是与特定输出类别相关的二维分数网格,对任何输入图像的

每个位置都要进行计算,它表示每个位置对该类别的重要程度。

举例来说,对于输入到猫狗分类卷积神经网络的一张图像, CAM 可视化可以生成类别“猫”的热力图,

表示图像的各个部分与“猫”的相似程度, CAM 可视化也会生成类别“狗”的热力图,表示图像的各个部分与“狗”的相似程度。

方法是:“Grad-CAM: visual explanations from deep networks via gradientbased localization”这篇论文中描述的方法。

给定一张输入图像,对于一个卷积层的输出特征图,用类别相对于通道的梯度对这个特征图中的每个通道进行加权。

直观上来看,理解这个技巧的一种方法是,你是用“每个通道对类别的重要程度”对“输入图像对不

同通道的激活强度”的空间图进行加权,从而得到了“输入图像对类别的激活强度”的空间图。

二、文本

将单词与向量相关联

1、one-hot

one-hot 编码是将标记转换为向量的最常用、最基本的方法。它将每个单词与一个唯一的整数索引相关联,

然后将这个整数索引 i 转换为长度为 N 的二进制向量(N 是词表大小),这个向量只有第 i 个元

素是 1,其余元素都为 0。

2、词嵌入(word embedding)

(个人理解:词嵌入:将每个单词映射为一个向量,用这些向量来代表单词之间的关系,而映射的过程就叫词嵌入)

将单词与向量相关联还有另一种常用的强大方法,就是使用密集的词向量(word vector),

也叫词嵌入(word embedding)。 one-hot 编码得到的向量是二进制的、稀疏的(绝大部分元素都

是 0)、维度很高的(维度大小等于词表中的单词个数),而词嵌入是低维的浮点数向量(即密

集向量,与稀疏向量相对)。

词向量之间的几何关系应该表示这些词之间的语义关系。词嵌入的作用

应该是将人类的语言映射到几何空间中。例如,在一个合理的嵌入空间中,同义词应该被嵌入

到相似的词向量中,一般来说,任意两个词向量之间的几何距离(比如 L2 距离)应该和这两个

词的语义距离有关(表示不同事物的词被嵌入到相隔很远的点,而相关的词则更加靠近)。除了

距离,你可能还希望嵌入空间中的特定方向也是有意义的。

获得word embeddings的两种方式:

方法一:从当前的任务中学习到word embeddings;

方法二:使用预训练的word embeddings

最好将 Embedding 层理解为一个字典,将整数索引(表示特定单词)映射为密集向量。它

接收整数作为输入,并在内部字典中查找这些整数,然后返回相关联的向量。 Embedding 层实

际上是一种字典查找: 单词索引 ---> Enbedding层 ---> 对应的词向量

Embedding 层的输入是一个二维整数张量,其形状为 (samples, sequence_length),

每个元素是一个整数序列。它能够嵌入长度可变的序列,例如,对于前一个例子中的

Embedding 层,你可以输入形状为 (32, 10)(32 个长度为 10 的序列组成的批量)或 (64,

15)(64 个长度为 15 的序列组成的批量)的批量。不过一批数据中的所有序列必须具有相同的

长度(因为需要将它们打包成一个张量),所以较短的序列应该用 0 填充,较长的序列应该被截断。

这 个 Embedding 层 返 回 一 个 形 状 为 (samples, sequence_length, embedding_

dimensionality) 的三维浮点数张量。然后可以用 RNN 层或一维卷积层来处理这个三维张量。

将一个 Embedding 层实例化时,它的权重(即标记向量的内部字典)最开始是随机的,与

其他层一样。在训练过程中,利用反向传播来逐渐调节这些词向量,改变空间结构以便下游模

型可以利用。一旦训练完成,嵌入空间将会展示大量结构,这种结构专门针对训练模型所要解

决的问题。

3、使用预训练的词嵌入

有许多预计算的词嵌入数据库,你都可以下载并在 Keras 的 Embedding 层中使用。

word2vec 就是其中之一。另一个常用的是 GloVe(global vectors for word representation,词表示

全局向量)

理解循环神经网络

密集连接网络和卷积神经网络 都有一个主要特点,那就是它们都没有记忆。

它们单独处理每个输入,在输入与输入之间没有保存任何状态。

对于这样的网络,要想处理数据点的序列或时间序列,你需要向网络同时展示整个序列,即将序列转

换成单个数据点。例如,你在 IMDB 示例中就是这么做的:将全部电影评论转换为一个大向量,

然后一次性处理。这种网络叫作前馈网络(feedforward network)。

与此相反,当你在阅读这个句子时,你是一个词一个词地阅读(或者说,眼睛一次扫视一

次扫视地阅读),同时会记住之前的内容。这让你能够动态理解这个句子所传达的含义。

生物智能以渐进的方式处理信息,同时保存一个关于所处理内容的内部模型,这个模型是根据过去的

信息构建的,并随着新信息的进入而不断更新。

循环神经网络(RNN, recurrent neural network):

它处理序列的方式是,遍历所有序列元素,并保存一个状态(state),其中包含与已查看

内容相关的信息。实际上, RNN 是一类具有内部环的神经网络。在处理两个不同的

独立序列(比如两条不同的 IMDB 评论)之间, RNN 状态会被重置,因此,你仍可以将一个序

列看作单个数据点,即网络的单个输入。真正改变的是,数据点不再是在单个步骤中进行处理,

相反,网络内部会对序列元素进行遍历。

为了将环(loop)和状态的概念解释清楚,我们用 Numpy 来实现一个简单 RNN 的前向传递。

这个 RNN 的输入是一个张量序列,我们将其编码成大小为 (timesteps, input_features)

的二维张量。它对时间步(timestep)进行遍历,在每个时间步,它考虑 t 时刻的当前状态与 t

时刻的输入[形状为 (input_ features,)],对二者计算得到 t 时刻的输出。然后,我们将

下一个时间步的状态设置为上一个时间步的输出。对于第一个时间步,上一个时间步的输出没

有定义,所以它没有当前状态。因此,你需要将状态初始化为一个全零向量,这叫作网络的初

始状态(initial state)。

RNN 的伪代码如下所示。

state_t = 0 # t 时刻的状态

for input_t in input_sequence: #对序列元素进行遍历

output_t = f(input_t, state_t) # t时刻的当前状态与t时刻的输入 计算得到 t 时刻的输出

state_t = output_t #前一次的输出变成下一次迭代的状态

keras 中的SimpleRNN 层能实现简单的RNN

SimpleRNN 层能够像其他 Keras 层一样处理序列批量,它接收形状为 (batch_size, timesteps,

input_features) 的输入。

与 Keras 中的所有循环层一样, SimpleRNN 可以在两种不同的模式下运行:一种是返回每

个时间步连续输出的完整序列,即形状为 (batch_size, timesteps, output_features)

的三维张量;另一种是只返回每个输入序列的最终输出,即形状为 (batch_size, output_

features) 的二维张量。这两种模式由 return_sequences 这个构造函数参数来控制。

理解 LSTM 层和 GRU 层

SimpleRNN 并不是 Keras 中唯一可用的循环层,还有另外两个: LSTM 和 GRU。在实践中

总会用到其中之一,因为 SimpleRNN 通常过于简化,没有实用价值。 SimpleRNN 的最大问题是,

在时刻 t,理论上来说,它应该能够记住许多时间步之前见过的信息,但实际上它是不可能学

到这种长期依赖的。其原因在于梯度消失问题(vanishing gradient problem),这一效应类似于

在层数较多的非循环网络(即前馈网络)中观察到的效应:随着层数的增加,网络最终变得无

法训练。

长短期记忆(LSTM, long short-term memory)算法是研究梯度消失问题的重要成果。

RNN 的关键点之一就是他们可以用来连接先前的信息到当前的任务上。

我们向simpleRNN中添加额外的数据流,其中携带着跨越时间步的信息。它在不同的时间步

的值叫作 Ct,其中 C 表示携带(carry)。因为Ct+1中包含着t时刻的信息,包含着以前的信息,因此具有长期记忆。

LSTM 层是 SimpleRNN 层的一种变体,它增加了一种携带信息跨越多个时间步的方法。假

设有一条传送带,其运行方向平行于你所处理的序列。序列中的信息可以在任意位置跳上传送带,

然后被传送到更晚的时间步,并在需要时原封不动地跳回来。这实际上就是 LSTM 的原理:它

保存信息以便后面使用,从而防止较早期的信号在处理过程中逐渐消失。

你只需要记住 LSTM 单元的作用:允许过去的信息稍后重新进入,从而解决梯度消失问题。

门控循环单元(GRU, gated recurrent unit)层的工作原理与 LSTM 相同。但它做了一些简化,

因此运行的计算代价更低(虽然表示能力可能不如 LSTM)。

循环神经网络的高级用法

循环 dropout(recurrent dropout)。

这是一种特殊的内置方法,在循环层中使用 dropout来降低过拟合。

堆叠循环层(stacking recurrent layers)。

这会提高网络的表示能力(代价是更高的计算负荷)。

双向循环层(bidirectional recurrent layer)。

将相同的信息以不同的方式呈现给循环网络,可以提高精度并缓解遗忘问题。

python书籍读后感_《Python深度学习》读书记录相关推荐

  1. 明日科技的python书籍怎么样_零基础学习Python不可错过的5本书籍

    3.Python基础教程(第3版) 作者:[挪]芒努斯·利·海特兰德(Magnus Lie Hetland) 出版社:人民邮电出版社 Python3.5编程从入门到实践,Python入门佳作,机器学习 ...

  2. python多分类混淆矩阵代码_深度学习自学记录(3)——两种多分类混淆矩阵的Python实现(含代码)...

    深度学习自学记录(3)--两种多分类混淆矩阵的Python实现(含代码),矩阵,样本,模型,类别,真实 深度学习自学记录(3)--两种多分类混淆矩阵的Python实现(含代码) 深度学习自学记录(3) ...

  3. python中如何移动图形工作站_六招教你用Python分分钟构建好玩的深度学习应用

    原标题:六招教你用Python分分钟构建好玩的深度学习应用 导读]深度学习是近来数据科学中研究和讨论最多的话题.得益于深度学习的发展,数据科学在近期得到了重大突破,深度学习也因此得到了很多关注.据预测 ...

  4. 使用RTX3080显卡搭建基于Pycharm+Python+Cuda+cuDNN+TensorFlow的深度学习开发环境

    本文链接:https://blog.csdn.net/tjhyx2012/article/details/112955582 作为一名新手,也是出于兴趣,我通过查找有关资料,使用RTX3080显卡搭建 ...

  5. 深度学习将灰度图着色_通过深度学习为视频着色

    深度学习将灰度图着色 零本地设置/ DeOldify / Colab笔记本 (Zero Local Setup / DeOldify / Colab Notebook) "Haal Kais ...

  6. 深度学习模型建立过程_所有深度学习都是统计模型的建立

    深度学习模型建立过程 Deep learning is often used to make predictions for data driven analysis. But what are th ...

  7. 深度学习:在图像上找到手势_使用深度学习的人类情绪和手势检测器:第1部分

    深度学习:在图像上找到手势 情感手势检测 (Emotion Gesture Detection) Has anyone ever wondered looking at someone and tri ...

  8. 深度学习读书笔记之RBM(限制波尔兹曼机)

    深度学习读书笔记之RBM 声明: 1)看到其他博客如@zouxy09都有个声明,老衲也抄袭一下这个东西 2)该博文是整理自网上很大牛和机器学习专家所无私奉献的资料的.具体引用的资料请看参考文献.具体的 ...

  9. 深度学习读书笔记之AE(自动编码)

    深度学习读书笔记之AE 声明: 1)该博文是整理自网上很大牛和机器学习专家所无私奉献的资料的.具体引用的资料请看参考文献.具体的版本声明也参考原文献. 2)本文仅供学术交流,非商用.所以每一部分具体的 ...

最新文章

  1. 【opus源码分析】celt_fir5函数
  2. 从user 登陆開始
  3. JAVA设计模式之【建造者模式】
  4. 利用passssh,批量远程修改机器密码
  5. Maven 配置文件 POM 的常用插件配置代码
  6. 在windows的某个文件夹下运行WSL中的docker容器
  7. java爬虫爬取主流房屋网站
  8. 大家有什么n刷的小说,可以推荐一下吗?
  9. 20180914 文件和目录的权限以及属性
  10. deepin创建快捷方式图标
  11. 乐符识别matlab,科学网—[原][Matlab][04] Midi音乐键盘 - 王楠的博文
  12. cocos2dx-lua项目的构建、编译细则
  13. 12、【股票策略】使用backtrader回测升级版的狗股策略-基于股息率和市净率两个因子
  14. 《网络运维基础知识手册》
  15. 孙陶然:只有不到十分之一的人适合创业
  16. Mac 远程连接树莓派-不使用拓展坞
  17. 使用rke部署k8s集群
  18. 加载的图片太多或太大如何优化
  19. g5905怎么样 相当于什么水平
  20. 机器学习16 -- Lifelong Learning 终生学习

热门文章

  1. python datetime函数介绍_Python datetime包函数简单介绍
  2. 马上就是圣诞节了,但是,没想到程序猿的圣诞节竟然是这样的?
  3. 基于激光雷达和单目视觉融合的SLAM和三维语义重建
  4. 阿里云轻量级GPU计算型实例规格族vgn5i配置性能详解
  5. Windows服务器补丁列表及介绍_Windows server 2012 R2 部署WSUS补丁服务
  6. 优化跟打器词语标记动态显示并解决二字叠词冲突
  7. 菜鸟带你仿APP之YP神器--《探探》(一)
  8. Spring中使用RabbitMQ
  9. 善于使用F12开发人员工具来快速调试js代码
  10. 操作csv格式文件之csv.reader()方法