赞
踩
仿射变换:加权特征组合,带偏置项的线性组合
Softmax回归:通过单个仿射变换将我们的输入直接映射到输出,然后进行softmax操作
问题:如果我们的标签通过仿射变换后确实与我们的输入数据相关,那么这种方法确实足够了。 但是,仿射变换中的线性是一个很强的假设
想办法解决:数据可能会有一种表示,这种表示会考虑到我们在特征之间的相关交互作用,在此表示的基础上建立一个线性模型可能会是合适的, 但我们不知道如何手动计算这么一种表示
隐藏层
表示和应用于该表示的线性预测器隐藏层的意义:
我们可以通过在网络中加入一个或多个隐藏层来克服线性模型的限制, 使其能处理更普遍的函数关系类型
—》多层感知机:
最简单的方法是将许多全连接层堆叠在一起。 每一层都输出到上面的层,直到生成最后的输出。 我们可以把前层看作表示,把最后一层看作线性预测器
何谓全连接?
全连接,即每个输入都会影响隐藏层中的每个神经元, 而隐藏层中的每个神经元又会影响输出层中的每个神经元
这是3层的感知机模型,全连接层有两个,隐藏层和输出层
隐藏层的目的:使得多层感知机可以通过隐藏神经元,捕捉到输入之间复杂的相互作用
关于初始化权重为0,为1情形的数学证明
ReLu : ReLU函数通过将相应的活性值设为0,仅保留正元素并丢弃所有负元素,即 R e L u ( x ) = m a x ( x , 0 ) ReLu(x)=max(x,0) ReLu(x)=max(x,0)
它将范围(-inf, inf)中的任意输入压缩到区间(0, 1)中的某个值
s i g m o i d ( x ) = 1 1 + e − x sigmoid(x) = \frac{1}{1+e^{-x}} sigmoid(x)=1+e−x1
导数很有意思:
tanh(双曲正切)函数也能将其输入压缩转换到区间(-1, 1)上
t a n h ( x ) = 1 − e − 2 x 1 + e − 2 x tanh(x)=\frac{1-e^{-2x}}{1+e^{-2x}} tanh(x)=1+e−2x1−e−2x
函数的形状类似于sigmoid函数, 不同的是tanh函数关于坐标系原点中心对称。
导数:
首先,线性模型的过拟合不必多说,两点
但是神经网络的过拟合是个玄学
举个栗子:
即使我们有比特征多得多的样本,深度神经网络也有可能过拟合。 2017年,一组研究人员通过在随机标记的图像上训练深度网络。 这展示了神经网络的极大灵活性,因为人类很难将输入和随机标记的输出联系起来, 但通过随机梯度下降优化的神经网络可以完美地标记训练集中的每一幅图像。 想一想这意味着什么?
1.标签是随机均匀分布分配的,10个类别
2.基于1的假设,理论上分类器分对的概率应小等于0.1
分类器在测试数据上很难取得高于10%的精度, 那么这里的泛化差距就高达90%,如此严重的过拟合。
余所谓之,权值衰退,其实就是L2正则化
神经网络中的L2正则化,体现在隐藏层中,由于L2正则化会将某些特征压缩到很小,但没有扔弃掉这些特征。也就是当前层的某些神经元作用很小,逐层衰减,使得我们的学习算法偏向于在大量特征上均匀分布权重的模型
特征之间的不同:
补充一下:
初始化的W可以假设为均值为0的正态分布,框架默认W的初始化分布为随机初始化
现在,让我们假设层 x j x_j xj的输入也具有零均值和方差 σ 2 \sigma^2 σ2, 并且它们 w i j w_{ij} wij独立于并且彼此独立。 在这种情况下,我们可以按如下方式计算的平均值和方差
保持方差不变的一种方法是设置 n i n σ 2 = 1 n_{in}\sigma^2=1 ninσ2=1,但是不满足这个条件,梯度将会增加(因为梯度是N个X和W的矩阵乘积)
好像这是个不可能的问题$n_{in}\sigma^2$和$\gamma^2$同时减小,那总方差必然减小!
咋解决?
Xavier初始化:均值为0, σ 2 = 2 n i n + n o u t \sigma^2=\frac{2}{n_{in} + n_{out}} σ2=nin+nout2的正态分布,也可以是均匀分布
均匀分布:
U
(
−
a
,
a
)
U(-a,a)
U(−a,a) ,
σ
2
=
a
2
/
3
\sigma^2 =a^2/3
σ2=a2/3 ,
μ
=
0
\mu=0
μ=0 带入上式
平滑性:即函数不应该对其输入的微小变化敏感
当我们对图像进行分类时,我们预计向像素添加一些随机噪声应该是基本无影响的
如何将这个随机噪声加入隐藏层中呢?
在训练过程中,他们建议在计算后续层之前向网络的每一层注入噪声。 因为当训练一个有多层的深层网络时,注入噪声只会在输入-输出映射上增强平滑性
暂退法DropOut : 在前向传播过程中,计算每一内部层的同时注入噪声
DropOut的由来:
因为我们从表面上看是在训练过程中丢弃(drop out)一些神经元。 在整个训练过程的每一次迭代中,标准暂退法包括在计算下一层之前将当前层中的一些节点置零
问题又来了!
暂退法的原始论文提到了一个关于有性繁殖的类比: 神经网络过拟合与每一层都依赖于前一层激活值相关,称这种情况为“共适应性”。 那么,暂退法会破坏共适应性,就像有性生殖会破坏共适应的基因一样
接下来,噪声如何注入?
一种想法是以一种无偏向(unbiased)的方式注入噪声。 这样在固定住其他层时,每一层的期望值等于没有噪音时的值。
标准暂退法正则化中,通过按保留(未丢弃)的节点的分数进行规范化来消除每一层的偏差。
暂退概率:以多少的概率扔掉该神经元
为什么是h除以1-p?
如果暂退概率为p,随机变量为0,扔掉该神经元
如果暂退概率不为p,加入随机变量,保留该神经元
总结:
暂退法在前向传播过程中,计算每一内部层的同时丢弃一些神经元。
暂退法可以避免过拟合,它通常与控制权重向量的维数和大小结合使用的。
暂退法将活性值h替换为具有期望值的随机变量。
暂退法仅在训练期间使用。
暂退法可以打破隐藏层神经元的对称性,小批量随机梯度下降不行!
当数据分布突然改变时,模型在部署中会出现灾难性的失败
举个栗子:
我们训练了一个贷款申请人违约风险模型,用来预测谁将偿还贷款或违约。 这个模型发现申请人的鞋子与违约风险相关(穿牛津鞋申请人会偿还,穿运动鞋申请人会违约)。 此后,这个模型可能倾向于向所有穿着牛津鞋的申请人发放贷款,并拒绝所有穿着运动鞋的申请人
后果:
一旦模型开始根据鞋类做出决定,顾客就会理解并改变他们的行为。 不久,所有的申请者都会穿牛津鞋,而信用度却没有相应的提高
分布偏移的含义:
训练集是一个分布 , 测试集是另一个分布 ,然后一些有趣的事情就发生了
虽然输入的分布可能随时间而改变, 但标签函数 P ( y ∣ x ) P(y|x) P(y∣x)(即条件分布)没有改变
标签偏移(label shift)描述了与协变量偏移相反的问题.标签边缘概率 P ( y ) P(y) P(y)可以改变, 但是类别条件分布 P ( x ∣ y ) P(x|y) P(x∣y)在不同的领域之间保持不变
思考的栗子:
一所大学校园内的学生征集献血,作为开发测试的健康对照样本。 然后我们是否可以帮助他们建立一个用于检测疾病的分类器。
正如我们向他们解释的那样,用近乎完美的精度来区分健康和患病人群确实很容易。 然而,这可能是因为受试者在年龄、激素水平、体力活动、 饮食、饮酒以及其他许多与疾病无关的因素上存在差异。 这对检测疾病的分类器可能并不适用。 这些抽样可能会遇到极端的协变量偏移。 此外,这种情况不太可能通过常规方法加以纠正
当分布变化缓慢并且模型没有得到充分更新时,就会出现更微妙的情况: 非平稳分布
训练一个计算广告模型,但却没有经常更新(例如,一个2009年训练的模型不知道一个叫iPad的不知名新设备刚刚上市)。
建立一个垃圾邮件过滤器,它能很好地检测到所有垃圾邮件。但是,垃圾邮件发送者们变得聪明起来,制造出新的信息,看起来不像我们以前见过的任何垃圾邮件。
建立一个产品推荐系统,它在整个冬天都有效,但圣诞节过后很久还会继续推荐圣诞帽。
逼着我去学强化学习,呜呜呜~
协变量偏移的纠正:
需要根据数据来自正确分布与来自错误分布的概率之比, 来重新衡量每个数据样本的权重
标签偏移的纠正:
观测源数据上的标签,所以很容易估计原数据标签分布,再用原数据标签和目标数据的比率就行更正
优化提供了一种最大限度地减少深度学习损失函数的方法,但实质上,优化和深度学习的目标是根本不同的。
过拟合
经验风险是训练数据集的平均损失,而风险则是整个数据群的预期损失
深度学习模型的目标函数通常有许多局部最优解。
当优化问题的数值解接近局部最优值时,随着目标函数解的梯度接近或变为零,通过最终迭代获得的数值解可能仅使目标函数局部最优,而不是全局最优。
即,随机梯度下降
事实上,这是小批量随机梯度下降的有利特性之一,在这种情况下,小批量上梯度的自然变化能够将参数从局部极小值中移出
Hessian矩阵正定:当函数在零梯度位置处的Hessian矩阵的特征值全部为正值时,我们有该函数的局部最小值。
Hessian矩阵负定:当函数在零梯度位置处的Hessian矩阵的特征值全部为负值时,我们有该函数的局部最大值。
Hessian矩阵半正定:当函数在零梯度位置处的Hessian矩阵的特征值为负值和正值时,我们对函数有一个鞍点。
根源:链式求导
对激活函数进行求导,如果此部分大于1,那么层数增多的时候,最终的求出的梯度更新将以指数形式增加,即发生梯度爆炸,如果此部分小于1,那么随着层数增多,求出的梯度更新信息将会以指数形式衰减,即发生了梯度消失
w
1
的更新的结果是梯度累成的,如果每一层的梯度项均大于
1
,结果将成指数级别增加,反之小于
1
同理
w1的更新的结果是梯度累成的,如果每一层的梯度项均大于1,结果将成指数级别增加,反之小于1同理
w1的更新的结果是梯度累成的,如果每一层的梯度项均大于1,结果将成指数级别增加,反之小于1同理
在x=4之后,梯度几乎为0,但不为0,导致很长一段时间内无法取得较大进展
总结:
从深层网络角度来讲,不同的层学习的速度差异很大,表现为网络中靠近输出的层学习的情况很好,靠近输入的层学习的很慢,有时甚至训练了很久,前几层的权值和刚开始随机初始化的值差不多。
因此,梯度消失、爆炸,其根本原因在于反向传播训练法则,本质在于方法问题,另外多说一句,对于人来说,在大脑的思考机制里是没有反向传播的,Hinton提出capsule的原因就是为了彻底抛弃目前基于反向传播的深度学习算法,如果真能大范围普及,那真是一个革命。
解决方法:
梯度下降法,则每个自变量迭代的计算代价为 O ( n ) O(n) O(n),它随线性增长。因此,当训练数据集较大时,每次迭代的梯度下降计算代价将较高。
随机梯度下降(SGD)可降低每次迭代时的计算代价。在随机梯度下降的每次迭代中,我们对数据样本随机均匀采样一个索引 i i i, 也就是随机抽取一个数据然后计算梯度。
之前我们会理所当然地读取数据的小批量,而不是观测单个数据来更新参数
处理单个观测值需要我们执行许多单一矩阵-矢量(甚至矢量-矢量)乘法,这耗费相当大,而且对应深度学习框架也要巨大的开销。 这既存在于计算梯度以更新参数时,也适用于用神经网络预测。
单个梯度:
小批量:
统计性质:
然而,经过一段时间后,与计算代价的线性增长相比,标准差的额外减少是微乎其微的。 在实践中我们选择一个足够大的小批量,它可以提供良好的计算效率同时仍适合GPU的内存
对于嘈杂的梯度,我们在选择学习率需要格外谨慎。 如果衰减速度太快,收敛就会停滞。 相反,如果太宽松,我们可能无法收敛到最优解
较大的 β \beta β相当于长期平均值,而较小的 β \beta β相对于梯度法只是略有修正。 新的梯度替换不再指向特定实例下降最陡的方向,而是指向过去梯度的加权平均值的方向。 这使我们能够实现对单批量计算平均值的大部分好处,而不产生实际计算其梯度的代价
此外,它们允许我们对随后的梯度计算平均值,以获得更稳定的下降方向。 诚然,即使是对于无噪声凸问题,加速度这方面也是动量如此起效的关键原因之一
条件不佳:
优化问题条件不佳的情况下(例如,有些方向的进展比其他方向慢得多,类似狭窄的峡谷
动量法(momentum)使我们能够解决上面描述的梯度下降问题。 观察上面的优化轨迹,我们可能会直觉到计算过去的平均梯度效果会很好。 毕竟,在 x 1 x1 x1方向上,这将聚合非常对齐的梯度,从而增加我们在每一步中覆盖的距离。 相反,在梯度振荡的 x 2 x2 x2方向,由于相互抵消了对方的振荡,聚合梯度将减小步长大小。
这个栗子简直太香了!!!
将图像分割成多个区域,并为每个区域包含沃尔多的可能性打分
卷积神经网络正是将空间不变性(spatial invariance)的这一概念系统化,从而基于这个模型使用较少的参数来学习有用的表示
神经网络的架构设计:
平移不变性(translation invariance):不管检测对象出现在图像中的哪个位置,神经网络的前面几层应该对相同的图像区域具有相似的反应,即为“平移不变性”。
局部性(locality):神经网络的前面几层应该只探索输入图像中的局部区域,而不过度在意图像中相隔较远区域的关系,这就是“局部性”原则。最终,可以聚合这些局部特征,以在整个图像级别进行预测。
图像一般包含三个通道/三种原色(红色、绿色和蓝色)
图像不是二维张量,而是一个由高度、宽度和颜色组成的三维张量,比如包含个像素(1024x1024x3)
前两个轴与像素的空间位置有关,而第三个轴可以看作是每个像素的多维表示
严格卷积:需水平和垂直翻转二维卷积核张量,然后对输入张量执行互相关运算
由于卷积核是从数据中学习到的,因此无论这些层执行严格的卷积运算还是互相关运算,卷积层的输出都不会受到影响
何谓卷积?
我们看到输入层的宽度和高度对应于输入图像的宽度和高度,而它的深度为1。接着,第一个卷积层对这幅图像进行了卷积操作(后面我们会讲如何计算卷积),得到了三个Feature Map。这里的"3"可能是让很多初学者迷惑的地方,实际上,就是这个卷积层包含三个Filter,也就是三套参数,每个Filter都可以把原始输入图像卷积得到一个Feature Map,三个Filter就可以得到三个Feature Map。至于一个卷积层可以有多少个Filter,那是可以自由设定的。
在第一个卷积层之后,Pooling层对三个Feature Map做了下采样(后面我们会讲如何计算下采样),得到了三个更小的Feature Map。接着,是第二个卷积层,它有5个Filter。每个Fitler都把前面下采样之后的3个Feature Map卷积在一起,得到一个新的Feature Map。这样,5个Filter就得到了5个Feature Map。接着,是第二个Pooling,继续对5个Feature Map进行下采样,得到了5个更小的Feature Map。
最后两层是全连接层。第一个全连接层的每个神经元,和上一层5个Feature Map中的每个神经元相连,第二个全连接层(也就是输出层)的每个神经元,则和第一个全连接层的每个神经元相连,这样得到了整个网络的输出。
图像大小、步幅和卷积后的Feature Map大小是有关系的:
W
2
=
(
W
1
−
F
+
2
P
)
/
S
+
1
W_2=(W_1-F+2P)/S+1
W2=(W1−F+2P)/S+1
H
2
=
(
H
1
−
F
+
2
P
)
/
S
H_2=(H_1-F+2P)/S
H2=(H1−F+2P)/S
下图体现了多个卷积核一起做卷积的过程:
包含了局部连接和参数共享的思想
局部连接:每个神经元仅与输入神经元的一块区域连接,这块局部区域称作感受野(receptive field)。在图像卷积操作中,即神经元在空间维度(spatial dimension,即上图示例H和W所在的平面)是局部连接,但在深度上是全部连接。对于二维图像本身而言,也是局部像素关联较强。这种局部连接保证了学习后的过滤器能够对于局部的输入特征有最强的响应。局部连接的思想,也是受启发于生物学里面的视觉系统结构,视觉皮层的神经元就是局部接受信息的。
权重共享:计算同一个深度切片的神经元时采用的滤波器是共享的。例上图中计算o[:,:,0]的每个每个神经元的滤波器均相同,都为W0,这样可以很大程度上减少参数。共享权重在一定程度上讲是有意义的,例如图片的底层边缘特征与特征在图中的具体位置无关。
注意权重只是对于同一深度切片的神经元是共享的
,在卷积层,通常采用多组卷积核提取不同特征,即对应不同深度切片的特征,不同深度切片的神经元权重是不共享。另外,偏重对同一深度切片的所有神经元都是共享的。
FLOPs是模型的计算次数
( 2 ∗ C i ∗ K 2 − 1 ) ∗ H ∗ W ∗ C 0 (2*C_i*K^2-1)*H*W*C_0 (2∗Ci∗K2−1)∗H∗W∗C0
Ci = input channel,
k = kernel size,
H,W = output feature map size
Co = output channel.
公式理解:
括号内: 计算出output feature map的一个pixel,即相乘再相加的操作
( 2 ∗ C i ∗ K 2 − 1 ) = ( C i ∗ K 2 ) + ( C i ∗ K 2 − 1 ) (2*C_i * K^2 -1) = (C_i * K^2)+(C_i*K^2-1) (2∗Ci∗K2−1)=(Ci∗K2)+(Ci∗K2−1)
括号外:乘以HWCo拓展到整个output feature map。
( 2 ∗ I − 1 ) ∗ O (2*I-1)*O (2∗I−1)∗O
I=input neuron numbers, O=output neuron numbers.
2是因为一个MAC算2个operations。
括号内是一个输出神经元的计算量,拓展到O了输出神经元。
不考虑bias时有-1,有bias时没有-1。
( R + H ) ∗ H ∗ 4 ∗ 2 (R+H)*H*4*2 (R+H)∗H∗4∗2
E是embedding dimension, 也就是词向量维度(不是时间维度)
H是hidden state dimension, 也就是LSTM有多少cell4是4 个非线性变换块(3 个 门 + 1 个 tanh)
2是将MAC数转为FLOPsLSTM里其实还有三个乘法块,一个加法块和非线性部分,计算量占用不大,这里近似忽略。
params:
总参数量 = 138,344,128 = 138MB
参数占用内存:float32 占用4个字节
138,344,128 * 4 (字节数)/ (1024 * 1024)= 527.79MB = 528MB
layers:
每一层输出参数数量总和= 15,237,608 /(1024*1024)= 15.2MB
每一层输出所需内存总和:15,237,608 4 / (10241024) = 58.12MB
模型内存:528 * 3 = 1.54 GB
输出内存:batch_size * layer_memory * 2 = 14.53 GB
输入图片:32*32
卷积核大小:5*5
卷积核种类:6
输出featuremap大小:28*28 (32-5+1)=28
神经元数量:28286
可训练参数:(55+1) * 6(每个滤波器55=25个unit参数和一个bias参数,一共6个滤波器)
连接数:(55+1)62828=122304
详细说明:对输入图像进行第一次卷积运算(使用 6 个大小为 55 的卷积核),得到6个C1特征图(6个大小为2828的 feature maps, 32-5+1=28)。我们再来看看需要多少个参数,卷积核的大小为55,总共就有6(55+1)=156个参数,其中+1是表示一个核有一个bias。对于卷积层C1,C1内的每个像素都与输入图像中的55个像素和1个bias有连接,所以总共有1562828=122304个连接(connection)。有122304个连接,但是我们只需要学习156个参数,主要是通过权值共享实现的。
输入:28*28
采样区域:2*2
采样方式:4个输入相加,乘以一个可训练参数,再加上一个可训练偏置。结果通过sigmoid
采样种类:6
输出featureMap大小:14*14(28/2)
神经元数量:14146
连接数:(22+1)61414
S2中每个特征图的大小是C1中特征图大小的1/4。
详细说明:第一次卷积之后紧接着就是池化运算,使用 22核 进行池化,于是得到了S2,6个1414的 特征图(28/2=14)。S2这个pooling层是对C1中的2*2区域内的像素求和乘以一个权值系数再加上一个偏置,然后将这个结果再做一次映射。同时有5x14x14x6=5880个连接。
输入:(14 * 16 *6)S2中所有6个或者几个特征map组合
卷积核大小:5*5
卷积核种类:16
输出featureMap大小:10*10 (14-5+1)=10
神经元个数:1600 = 10* 10* 16
C3中的每个特征map是连接到S2中的所有6个或者几个特征map的,表示本层的特征map是上一层提取到的特征map的不同组合
存在的一个方式是:C3的前6个特征图以S2中3个相邻的特征图子集为输入。接下来6个特征图以S2中4个相邻特征图子集为输入。然后的3个以不相邻的4个特征图子集为输入。最后一个将S2中所有特征图为输入。
则:可训练参数:6*(355+1)+6*(455+1)+3*(455+1)+1*(655+1)=1516
连接数:10101516=151600
详细说明:第一次池化之后是第二次卷积,第二次卷积的输出是C3,16个10x10的特征图,卷积核大小是 55. 我们知道S2 有6个 1414 的特征图,怎么从6 个特征图得到 16个特征图了? 这里是通过对S2 的特征图特殊组合计算得到的16个特征图。
C3的前6个feature map(对应上图第一个红框的6列)与S2层相连的3个feature map相连接(上图第一个红框),后面6个feature map与S2层相连的4个feature map相连接(上图第二个红框),后面3个feature map与S2层部分不相连的4个feature map相连接,最后一个与S2层的所有feature map相连。卷积核大小依然为55,所以总共有6(355+1)+6*(455+1)+3*(455+1)+1*(655+1)=1516个参数。而图像大小为10*10,所以共有151600个连接。
为什么采用上述这样的组合了?论文中说有两个原因:
输入:S4层的全部16个单元特征map(与s4全相连)
卷积核大小:5*5
卷积核种类:120
输出featureMap大小:1*1(5-5+1)
可训练参数/连接:120*(1655+1)=48120
详细说明:C5层是一个卷积层。由于S4层的16个图的大小为5x5,与卷积核的大小相同,所以卷积后形成的图的大小为1x1。这里形成120个卷积结果。每个都与上一层的16个图相连。所以共有(5x5x16+1)x120 = 48120个参数,同样有48120个连接。
输入:c5 120维向量
神经元个数:84
计算方式:计算输入向量和权重向量之间的点积,再加上一个偏置,结果通过sigmoid函数输出。
可训练参数:84*(120+1)=10164
详细说明:6层是全连接层。F6层有84个节点,对应于一个7x12的比特图,-1表示白色,1表示黑色,这样每个符号的比特图的黑白色就对应于一个编码。该层的训练参数和连接数是(120 + 1)x84=10164。
比LeNet层数更多,更深
经典卷积神经网络的基本组成部分是下面的这个序列:
带填充以保持分辨率的卷积层;
非线性激活函数,如ReLU;
汇聚层,如最大汇聚层。
VGG神经网络连接几个VGG块(在vgg_block函数中定义)。其中有超参数变量conv_arch。该变量指定了每个VGG块里卷积层个数和输出通道数。全连接模块则与AlexNet中的相同
原始VGG网络有5个卷积块,其中前两个块各有一个卷积层,后三个块各包含两个卷积层。 第一个模块有64个输出通道,每个后续模块将输出通道数量翻倍,直到该数字达到512。
由于该网络使用8个卷积层和3个全连接层,因此它通常被称为VGG-11。
深层且窄的卷积(即)比较浅层且宽的卷积更有效。
ideas:
NiN的想法是在每个像素位置(针对每个高度和宽度)应用一个全连接层。 如果我们将权重连接到每个空间位置,我们可以将其视为卷积层,或作为在每个像素位置上独立作用的全连接层
从另一个角度看,即将空间维度中的每个像素视为单个样本,将通道维度视为不同特征(feature)。
NiN块以一个普通卷积层开始,后面是两个1x1的卷积层。这两个1x1卷积层充当带有ReLU激活函数的逐像素全连接层。 第一层的卷积窗口形状通常由用户设置。 随后的卷积窗口形状固定为1x1。
NiN和AlexNet之间的一个显著区别是NiN完全取消了全连接层。 相反,NiN使用一个NiN块,其输出通道数等于标签类别的数量。最后放一个全局平均汇聚层(global average pooling layer),生成一个对数几率 (logits)。NiN设计的一个优点是,它显著减少了模型所需参数的数量。然而,在实践中,这种设计有时会增加训练模型的时间。
优点:
有时使用不同大小的卷积核组合是有利的
在GoogLeNet中,基本的卷积块被称为Inception块(Inception block)。这很可能得名于电影《盗梦空间》(Inception),因为电影中的一句话“我们需要走得更深”(“We need to go deeper”)。
Inception块由四条并行路径组成。 前三条路径使用窗口大小为1x1、3x3和5x5的卷积层,从不同空间大小中提取信息。 中间的两条路径在输入上执行1x1卷积,以减少通道数,从而降低模型的复杂性。 第四条路径使用3x3最大汇聚层,然后使用1x1卷积层来改变通道数。 这四条路径都使用合适的填充来使输入与输出的高和宽一致,最后我们将每条线路的输出在通道维度上连结,并构成Inception块的输出。在Inception块中,通常调整的超参数是每层输出通道数。
那么为什么GoogLeNet这个网络如此有效呢?
GoogLeNet一共使用9个Inception块和全局平均汇聚层的堆叠来生成其估计值。Inception块之间的最大汇聚层可降低维度。 第一个模块类似于AlexNet和LeNet,Inception块的组合从VGG继承,全局平均汇聚层避免了在最后使用全连接层。
跨同一层中的单元,或是随着时间的推移,模型参数的随着训练更新变幻莫测
。 批量规范化的发明者非正式地假设,这些变量分布中的这种偏移可能会阻碍网络的收敛。 直观地说,我们可能会猜想,如果一个层的可变值是另一层的100倍,这可能需要对学习率进行补偿调整批量规范化应用于单个可选层(也可以应用到所有层)
其原理如下:
在每次训练迭代中,我们首先规范化输入,即通过减去其均值并除以其标准差,其中两者均基于当前小批量处理。 接下来,我们应用比例系数和比例偏移。 正是由于这个基于批量统计的标准化,才有了批量规范化的名称。
请注意,如果我们尝试使用大小为1的小批量应用批量规范化,我们将无法学到任何东西。
所以,只有使用足够大的小批量,批量规范化这种方法才是有效且稳定的。 请注意,在应用批量规范化时,批量大小的选择可能比没有批量规范化时更重要
估计值 μ \mu μ和 σ \sigma σ,通过使用平均值和方差的噪声(noise)估计来抵消缩放问题。 你可能会认为这种噪声是一个问题,而事实上它是有益的。
由于尚未在理论上明确的原因,优化中的各种噪声源通常会导致更快的训练和较少的过拟合:这种变化似乎是正则化的一种形式
另外,批量规范化层在”训练模式“(通过小批量统计数据规范化)和“预测模式”(通过数据集统计规范化)中的功能不同。
通常,我们将批量规范化层置于全连接层中的仿射变换和激活函数之间。 设全连接层的输入为x,权重参数和偏置参数分别
W
W
W为和
b
b
b,激活函数为
ϕ
\phi
ϕ,批量规范化的运算符为
B
N
BN
BN。 那么,使用批量规范化的全连接层的输出的计算详情如下:
h
=
ϕ
(
B
N
(
W
x
+
b
)
)
h = \phi (BN(Wx+b))
h=ϕ(BN(Wx+b))
均值和方差是根据小批量计算的,所以会随小批量的变化而变化
为了方便起见,我们并不担心在这里自动推断输入形状,因此我们需要指定整个特征的数量
target : f*
残差网络的核心思想是:每个附加层都应该更容易地包含原始函数作为其元素之一。 于是,残差块(residual blocks)便诞生了。
左图虚线框中的部分需要直接拟合出该映射 f ( x ) f(x) f(x),而右图虚线框中的部分则需要拟合出残差映射 f ( x ) − x f(x)-x f(x)−x。 残差映射在现实中往往更容易优化
右图虚线框内上方的加权运算(如仿射)的权重和偏置参数设成0,那么 f ( x ) f(x) f(x)即为恒等映射。 实际中,当理想映射 f ( x ) f(x) f(x)极接近于恒等映射时,残差映射也易于捕捉恒等映射的细微波动。 右图是ResNet的基础架构–残差块(residual block)。 在残差块中,输入可通过跨层数据线路更快地向前传播。
ResNet沿用了VGG完整的3x3卷积层设计。
此代码生成两种类型的网络:
Inception块
--》残差块
GoogLeNet在后面接了4个由Inception块组成的模块。 ResNet则使用4个由残差块组成的模块,每个模块使用若干个同样输出通道数的残差块。 第一个模块的通道数同输入通道数一致。 由于之前已经使用了步幅为2的最大汇聚层,所以无须减小高和宽。 之后的每个模块在第一个残差块里将上一个模块的通道数翻倍,并将高和宽减半。
ResNet将网络函数f分解为两部分( f ( x ) = x + g ( x ) f(x)=x+g(x) f(x)=x+g(x)):一个简单的线性项和一个复杂的非线性项。 那么再向前拓展一步,如果我们想将拓展成超过两部分的信息呢? 一种方案便是DenseNet。
稠密网络主要由2部分构成:
稠密块(dense block):定义如何连接输入和输出
过渡层(transition layer): 控制通道数量,使其不会太复杂。
稠密块:
DenseNet使用了ResNet改良版的“批量规范化、激活和卷积”架构
一个稠密块由多个卷积块组成,每个卷积块使用相同数量的输出通道。 然而,在前向传播中,我们将每个卷积块的输入和输出在通道维上连结。
过渡层:
由于每个稠密块都会带来通道数的增加,使用过多则会过于复杂化模型。 而过渡层可以用来控制模型复杂度。 它通过1x1卷积层来减小通道数,并使用步幅为2的平均汇聚层减半高和宽,从而进一步降低模型复杂度。
DenseNet首先使用同ResNet一样的单卷积层和最大汇聚层。
用处:
输入、输出为不等长的序列
这种结构是Encoder-Decoder,也叫Seq2Seq,是RNN的一个重要变种。原始的n-to-n的RNN要求序列等长,然而我们遇到的大部分问题序列都是不等长的,如机器翻译中,源语言和目标语言的句子往往并没有相同的长度。为此,Encoder-Decoder结构先将输入数据编码成一个上下文语义向量c:
语义向量c可以有多种表达方式:
Decoder的RNN可以与Encoder的一样,也可以不一样。具体做法就是将c当做之前的初始状态输入到Decoder中:
由于这种Encoder-Decoder结构不限制输入和输出的序列长度,因此应用的范围非常广泛,比如:
Encoder
:将 input序列 →转成→ 固定长度的向量
Decoder
:将 固定长度的向量 →转成→ output序列
Encoder
:与 Decoder 可以彼此独立使用,实际上经常一起使用
最大的局限性:
由于这个限制的存在,经典RNN的适用范围比较小,但也有一些问题适合用经典的RNN结构建模,如:计算视频中每一帧的分类标签。因为要对每一帧进行计算,因此输入和输出序列等长。
输入为字符,输出为下一个字符的概率。这就是著名的Char RNN(详细介绍请参考:The Unreasonable Effectiveness of Recurrent Neural Networks,Char RNN可以用来生成文章,诗歌,甚至是代码,非常有意思)。
我们将给 RNN 一大块文本,并要求它在给定一系列先前字符的情况下,对序列中下一个字符的概率分布进行建模。这将允许我们一次生成一个字符的新文本。
作为一个工作示例,假设我们只有四个可能的字母“helo”的词汇表,并且想在训练序列“hello”上训练 RNN。该训练序列实际上是 4 个独立训练示例的来源:
具体来说,我们将使用 1-of-k 编码将每个字符编码到一个向量中(即除了词汇表中字符索引处的单个 1 外全为 0),并使用函数一次一个地将它们送入 RNN . 然后我们将观察一系列 4 维输出向量(每个字符一维),我们将其解释为 RNN 当前分配给序列中下一个字符的置信度。这是一个图表:
Attention机制通过在每个时间输入不同的c来解决问题,下图是带有Attention机制的Decoder:
例子:
输入的序列是“我爱中国”,因此,Encoder中的就可以分别看做是“我”、“爱”、“中”、“国”所代表的信息。在翻译成英语时,即假设 a 1 i = [ 0.5 , 0.2 , 0.1 , 0.1 ] a_{1i}= [0.5,0.2,0.1,0.1] a1i=[0.5,0.2,0.1,0.1],第一个上下文(h1)应该和 “我” 这个字最相关,因此对应的 a 11 a_{11} a11就比较大,而相应的 a 12 , a 13 a_{12},a_{13} a12,a13 就比较小。第二个上下文(h2)应该和“爱”最相关,因此对应的 a 22 a_{22} a22 就比较大。最后的h3和“中国”最相关,因此 a 33 , 34 a_{33,34} a33,34的值就比较大。
事实上,同样是从模型中学出的,它实际和Decoder的第 i − 1 i-1 i−1阶段的隐状态、Encoder第 j j j个阶段的隐状态有关。
a
2
j
a_{2j}
a2j
Attention 的优点:
传统RNN:
RNN最大优点就是能利用之前的信息来预测当前内容。比如要对句子 “云朵漂浮在天空” 的最后一个词“天空”进行预测。其实,光靠“云朵”这个词就能明显的知道预测词是“天空”。如下图,“云朵”和“天空”的位置是很近的。这样的操作在短文本里是比较有效实用的。
短期预测:
但是还有很多是长文本的预测。比如,“我 从小在中国长大,我很喜欢那里的美食……我能说很流利的中文。” 对这个长文本进行最后一个词“中文”的预测。根据附近的文字“说很流利的”,预测词很可能是一个语种,至于是什么语种还需要回归到最初的文本才能确定下来,如下图。然而这个预测词与最初的文本的距离可能是非常大的。
然而,预测词与相关文本的间距越大,RNN就越难去获取相关信息。这就是Long-Term Dependencies 问题。
是用来决定在C线上丢弃哪些信息,由一个叫“forget gate layer”的sigmoid层构成,取决于 h t − 1 h_{t−1} ht−1和 x t x_t xt,它的输出是一个0-1的数值。比如在文本中,前一个句子的主角是个男性,后一个句子的主角是个女性,那么在前一个句子里获取的性别信息应该舍弃。
第二个门是用来确定保留哪些信息。这里由两部分组成
第一个是由一个叫“input gate layer”的sigmoid层来决定更新哪些数值
第二个是一个tanh层来创建一个候选C向量,这个向量可以被加到C线中。这两个的组合就形成了C线信息的更新。就像文本主角的性别信息更新。
现在来更新
C
t
−
1
→
C
t
C_{t−1}→C_t
Ct−1→Ct ,
f
t
×
C
t
−
1
f_t×C_{t−1}
ft×Ct−1
是丢弃信息操作,
i
t
×
C
t
′
i_t×C^′_t
it×Ct′是信息更新操作。这样就完成了主角性别信息的更新。
最后我们需要根据C线决定输出内容。
GRU:它将遗忘门和输入门组合成一个“更新门”。它还合并了细胞状态和隐藏状态
将注意力集中在给定的信息子集的一部分上。例如,一个 RNN 可以参与另一个 RNN 的输出。在每个时间步,它都关注另一个 RNN 中的不同位置。
注意力分布通常是由基于内容的注意力产生的。参与的 RNN 生成一个查询,描述它想要关注的内容。每个项目都与查询进行点积以产生分数,描述它与查询的匹配程度。分数被送入 softmax 以创建注意力分布。
用CNN取代RNN作机器翻译
RNN是链式结构,CNN是层级结构
CNN处理数据:常量个kernel和非线性处理
RNN: 变量个n步骤,第一个词非线性,最后一个词做单一处理
RNN的一般过程:
自主性的与非自主性的注意力提示解释了人类的注意力的方式
在注意力机制的背景下,自主性提示被称为查询(query)。
给定任何查询,注意力机制通过注意力汇聚(attention pooling) 将选择引导至感官输入(sensory inputs,例如中间特征表示)。
感官输入被称为值(value)。 更通俗的解释,每个值都与一个键(key)配对, 这可以想象为感官输入的非自主提示。
可以通过设计注意力汇聚的方式, 便于给定的查询(自主性提示)与键(非自主性提示)进行匹配, 这将引导得出最匹配的值(感官输入)。
平均汇聚层可以被视为输入的加权平均值, 其中各输入的权重是一样的。
实际上,注意力汇聚得到的是加权平均的总和值, 其中权重是在给定的查询和不同的键之间计算得出的。
第一步: query 和 key 进行相似度计算(注意力评分函数),得到权值
第二步:将权值进行归一化,得到直接可用的权重
第三步:将权重和 value 进行加权求和
将Source中的构成元素想象成是由一系列的<Key,Value>数据对构成。
此时给定Target中的某个元素Query,通过计算Query和各个Key的相似性或者相关性,得到每个Key对应Value的权重系数,然后对Value进行加权求和,即得到了最终的Attention数值。
所以本质上Attention机制是对Source中元素的Value值进行加权求和,而Query和Key用来计算对应Value的权重系数。即可以将其本质思想改写为如下公式:
直接平均汇聚的效果不行
利用对汇聚层进行加权,据输入的位置对输出进行加权。
对于任何查询,模型在所有键值对注意力权重都是一个有效的概率分布: 它们是非负的,并且总和为1。 这就印出来了概率分布了
效果就是高斯核函数进行平滑
高斯核函数可以用参数模型表示,训练过程中学习参数(带参型)
总结:高斯核来对查询和键之间的关系建模。 (10.2.6)中的 高斯核指数部分可以视为注意力评分函数(attention scoring function), 然后把这个函数的输出结果输入到softmax函数中进行运算。 通过上述步骤,将得到与键对应的值的概率分布(即注意力权重)。 最后,注意力汇聚的输出就是基于这些注意力权重的值的加权和。
选择不同的注意力评分函数会导致不同的注意力汇聚操作。
硬性注意力:只关注到某一个位置上的信息
软性注意力:注意力是一个概率分布
(2)另一种硬性注意力可以通过在注意力分布式上随机采样的方式实现。
softmax操作用于输出一个概率分布作为注意力权重。 在某些情况下,并非所有的值都应该被纳入到注意力汇聚中。
例如,为了高效处理小批量数据集, 某些文本序列被填充了没有意义的特殊词元。 为了仅将有意义的词元作为值来获取注意力汇聚, 可以指定一个有效序列长度(即词元的个数), 以便在计算softmax时过滤掉超出指定范围的位置。
下面的masked_softmax函数 实现了这样的掩蔽softmax操作(masked softmax operation), 其中任何超出有效长度的位置都被掩蔽并置为0。
考虑由两个2x4的矩阵表示的样本, 这两个样本的有效长度分别为2
和3。 经过掩蔽softmax操作,超出有效长度的值都被掩蔽为0。
将查询和键连结起来后输入到一个多层感知机(MLP)中, 感知机包含一个隐藏层,其隐藏单元数是一个超参数h。 通过使用 t a n h tanh tanh作为激活函数,并且禁用偏置项。
#@save class AdditiveAttention(nn.Module): """加性注意力""" def __init__(self, key_size, query_size, num_hiddens, dropout, **kwargs): super(AdditiveAttention, self).__init__(**kwargs) self.W_k = nn.Linear(key_size, num_hiddens, bias=False) self.W_q = nn.Linear(query_size, num_hiddens, bias=False) self.w_v = nn.Linear(num_hiddens, 1, bias=False) self.dropout = nn.Dropout(dropout) def forward(self, queries, keys, values, valid_lens): queries, keys = self.W_q(queries), self.W_k(keys) # 在维度扩展后, # queries的形状:(batch_size,查询的个数,1,num_hidden) # key的形状:(batch_size,1,“键-值”对的个数,num_hiddens) # 使用广播方式进行求和 features = queries.unsqueeze(2) + keys.unsqueeze(1) features = torch.tanh(features) # self.w_v仅有一个输出,因此从形状中移除最后那个维度。 # scores的形状:(batch_size,查询的个数,“键-值”对的个数) scores = self.w_v(features).squeeze(-1) self.attention_weights = masked_softmax(scores, valid_lens) # values的形状:(batch_size,“键-值”对的个数,值的维度) return torch.bmm(self.dropout(self.attention_weights), values)
使用点积可以得到计算效率更高的评分函数, 但是点积操作要求查询和键具有相同的长度d。
假设查询和键的所有元素都是独立的随机变量, 并且都满足零均值0和单位方差d, 那么两个向量的点积的均值为
0,方差为d。 为确保无论向量长度如何, 点积的方差在不考虑向量长度的情况下仍然是1, 我们再将点积除以
d
1
/
2
d^{1/2}
d1/2, 则缩放点积注意力(scaled dot-product attention)评分函数为:
机器翻译问题: 通过设计一个基于两个循环神经网络的编码器-解码器架构, 用于序列到序列学习。 具体来说,循环神经网络编码器将长度可变的序列转换为固定形状的上下文变量, 然后循环神经网络解码器根据生成的词元和上下文变量 按词元生成输出(目标)序列词元。 然而,即使并非所有输入(源)词元都对解码某个词元都有用, 在每个解码步骤中仍使用编码相同的上下文变量。 有什么方法能改变上下文变量呢?
在预测词元时,如果不是所有输入词元都相关,模型将仅对齐(或参与)输入序列中与当前预测相关的部分。这是通过将上下文变量视为注意力集中的输出来实现的。
上下文变量c 在任何解码时间步都会被
t
′
t'
t′替换。 假设输入序列中有T个词元, 解码时间步
c
t
′
c_{t^{'}}
ct′的上下文变量是注意力集中的输出:
当给定相同的查询、键和值的集合时, 我们希望模型可以基于相同的注意力机制学习到不同的行为, 然后将不同的行为作为知识组合起来, 捕获序列内各种范围的依赖关系 (例如,短距离依赖和长距离依赖关系)。 因此,允许注意力机制组合使用查询、键和值的不同 子空间表示(representation subspaces)可能是有益的。
在深度学习中,经常使用卷积神经网络(CNN)或循环神经网络(RNN)对序列进行编码。 想象一下,有了注意力机制之后,我们将词元序列输入注意力池化中, 以便同一组词元同时充当查询、键和值。 具体来说,每个查询都会关注所有的键-值对并生成一个注意力输出。 由于查询、键和值来自同一组输入,因此被称为 自注意力(self-attention)
在位置嵌入矩阵P中, 行代表词元在序列中的位置,列代表位置编码的不同维度。
对于任何一门语言,单词在句子中的位置以及排列顺序是非常重要的,它们不仅是一个句子的语法结构的组成部分,更是表达语义的重要概念。一个单词在句子的位置或排列顺序不同,可能整个句子的意思就发生了偏差。即,词序信息
位置编码(Positional Encoding)是一种用词的位置信息对序列中的每个词进行二次表示的方法,另一种表示位置的方法。
一种做法就是分配一个0到1之间的数值给每个时间步,其中,0表示第一个词,1表示最后一个词。这种方法虽然简单,但会带来很多问题。其中一个就是你无法知道在一个特定区间范围内到底存在多少个单词。换句话说,不同句子之间的时间步差值没有任何的意义。
另一种做法就是线性分配一个数值给每个时间步。也就是,1分配给第一个词,2分配给第二个词,以此类推。这种方法带来的问题是,不仅这些数值会变得非常大,而且模型也会遇到一些比训练中的所有句子都要长的句子。此外,数据集中不一定在所有数值上都会包含相对应长度的句子,也就是模型很有可能没有看到过任何一个这样的长度的样本句子,这会严重影响模型的泛化能力。
一种好的位置编码方案需要满足以下几条要求:
Transformer的作者们提出了一个简单但非常创新的位置编码方法,能够满足上述所有的要求。首先,这种编码不是单一的一个数值,而是包含句子中特定位置信息的d维向量(非常像词向量)。第二,这种编码没有整合进模型,而是用这个向量让每个词具有它在句子中的位置的信息。换句话说,通过注入词的顺序信息来增强模型输入。
Transformer的编码器是由多个相同的层叠加而成的,每个层都有两个子层(子层表示为sublayer)。
第一个子层是多头自注意力(multi-head self-attention)汇聚;
第二个子层是基于位置的前馈网络(positionwise feed-forward network)。
在计算编码器的自注意力时,查询、键和值都来自前一个编码器层的输出。受残差网络的启发,每个子层都采用了残差连接(residual connection)。在Transformer中,对于序列中任何位置的任何输入 x ∈ R d x \in R^d x∈Rd,都要求满足 s u b l a y e r ( x ) ∈ R d sublayer(x)\in R^d sublayer(x)∈Rd,以便残差连接满足 x + s u b l a y e r ( x ) x+sublayer(x) x+sublayer(x)。
在残差连接的加法计算之后,紧接着应用层规范化(layer normalization)
Transformer解码器也是由多个相同的层叠加而成的,并且层中使用了残差连接和层规范化。
除了编码器中描述的两个子层之外,解码器还在这两个子层之间插入了第三个子层,称为编码器-解码器注意力(encoder-decoder attention)层。
在解码器自注意力中,查询、键和值都来自上一个解码器层的输出。但是,解码器中的每个位置只能考虑该位置之前的所有位置。
这种掩蔽(masked)注意力保留了自回归(auto-regressive)属性,确保预测仅依赖于已生成的输出词元。
基于位置的前馈网络对序列中的所有位置的表示进行变换时使用的是同一个多层感知机(MLP),这就是称前馈网络是基于位置的(positionwise)的原因。
在下面的实现中,输入X的形状(批量大小,时间步数或序列长度,隐单元数或特征维度)将被一个两层的感知机转换成形状为(批量大小,时间步数,ffn_num_outputs)的输出张量。
class PositionWiseFFN(nn.Module):
"""基于位置的前馈网络"""
def __init__(self, ffn_num_input, ffn_num_hiddens, ffn_num_outputs,
**kwargs):
super(PositionWiseFFN, self).__init__(**kwargs)
self.dense1 = nn.Linear(ffn_num_input, ffn_num_hiddens)
self.relu = nn.ReLU()
self.dense2 = nn.Linear(ffn_num_hiddens, ffn_num_outputs)
def forward(self, X):
return self.dense2(self.relu(self.dense1(X)))
在一个小批量的样本内基于批量规范化对数据进行重新中心化和重新缩放的调整。层规范化和批量规范化(BN)的目标相同,但层规范化是基于特征维度进行规范化。尽管批量规范化在计算机视觉中被广泛应用,但在自然语言处理任务中(输入通常是变长序列)批量规范化通常不如层规范化的效果好。
在训练阶段,其输出序列的所有位置(时间步)的词元都是已知的;然而,在预测阶段,其输出序列的词元是逐个生成的。因此,在任何解码器时间步中,只有生成的词元才能用于解码器的自注意力计算中。为了在解码器中保留自回归的属性,其掩蔽自注意力设定了参数dec_valid_lens,以便任何查询都只会与解码器中所有已经生成词元的位置(即直到该查询位置为止)进行注意力计算。
input shape: (sampleNum,indim)
那么第一层神经元:(indim, neuralNum1)
下层神经元:(neuarlNum1, neuarlNum2)
图像的形状:(批量大小、通道、高度、宽度) = (Batchsize, channel, h, w)
如果是多通道输入输出:(in_channel, out_channel, h, w)
图像尺寸的变化:最开始:(60000,784)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。