目录
损失函数
指标选择
交叉熵
交叉熵代码
使用最大似然的优势
损失函数的具体形式
用于高斯输出分布的线性单元
用于Bernoulli输出分布的sigmoid单元
用于Multinoulli输出分布的softmax单元
Mixture Gaussian Distribution
总结
隐藏单元
架构设计
更深层的好处
反向传播
梯度
链式法则
仿射层
sigmoid
softmax
正则化
参数范数惩罚
L2 参数正则化
L1 正则化
数据集增强
噪声鲁棒性
多任务学习
提前终止Early stopping
概念
算法
优点
代价
应用
第二轮训练
稀疏表示
Bagging和其他集成方法
Dropout
概念
具体方法
和bagging方法比较
权重比例推断
优点
代价
对抗训练
我们到目前为止看到的线性模型和神经网络的最大区别,在于神经网络的非线性导致大多数我们感兴趣的代价函数都变得非凸。凸优化从任何一种初始参数出发都会收敛(理论上如此),而用于非凸损失函数的随机梯度下降没有这种收敛性保证,并且对参数的初始值很敏感,这意味着神经网络的训练通常使用迭代的、基于梯度的优化,仅仅使得代价函数达到一个非常小的值。对于前馈神经网络,将所有的权重值初始化为小随机数是很重要的,偏置可以初始化为零或者小的正值。
在进行神经网络的学习时,不能将识别精度作为指标。因为如果以识别精度为指标,则参数的导数在绝大多数地方都会变为 0。因为识别精度是不连续的、离散的值,对微小的参数变化基本上没有什么反应,即便有反应,它的值也是不连续地、突然地变化。
作为激活函数的阶跃函数也有同样的情况。出于相同的原因,如果使用阶跃函数作为激活函数,神经网络的学习将无法进行。阶跃函数的导数在绝大多数地方(除了 0 以外的地方)均为 0。也就是说,如果使用了阶跃函数,那么即便将损失函数作为指标,参数的微小变化也会被阶跃函数抹杀,导致损失函数的值不会产生任何变化。
对于损失函数,我们通常选择的是减小模型的概率分布与真实的概率分布之间的差异,即交叉熵(cross-entropy)。一般而言,如果我们定义了一个条件分布p(y|x;θ),最大似然原则建议我们使用-log p(y|x;θ ) 作为代价函数。
对于每一个样本(q指标签的类别数量):
y是one-hot 表示
监督数据是标签形式
1.减轻了为每个模型设计代价函数的负担:明确一个模型p(y|x)则自动地确定了一个代价函数log p(y|x)。
2.交叉熵中的log函数可以解决输出函数或激活函数的饱和问题。很多输出单元都会包含一个指数函数(如sigmoid函数),在它的变量取绝对值非常大的负值时会造成饱和,即梯度变得非常小,梯度下降算法很难更新。负对数似然代价函数中的对数函数消除了某些输出单元中的指数效果,使得模型可以较快更新纠正错误预测。相比之下,均方误差和平均绝对误差在使用基于梯度的优化方法时,一些饱和的输出单元会产生非常小的梯度。这就是交叉熵代价函数比均方误差或者平均绝对误差更受欢迎的原因之一了
损失函数的具体形式依赖于模型的概率分布 pmodel(y|x) ,对于不同的输出分布,会有不同的输出函数及损失函数。交叉熵展开形式通常会有一些项不依赖于模型的参数,我们可以舍去。
例如在前面章节提到,假如模型概率分布是高斯分布 pmodel(y|x) = N(y;f(x;θ);I) , 则损失函数就是均方误差的形式,其中舍弃的常数是基于高斯分布的方差,在这种情况下,我们选择不把它参数化。
下面,假设前馈网络提供了一组定义为h =f (x;θ)的隐藏特征,输出层的作用是随后对这些特征进行一些额外的变换
输出是高斯分布,输出层常常是线性的变换 y^=WTh+b ,而线性输出层用来得到高斯分布的均值 p(y|x)=N(y;y^,I) ,最小化交叉熵就转化为最小化均方差的形式。由于线性输出不存在饱和区间,所以能较好的应用梯度下降算法。
许多任务需要预测二值型变量y的值,比如具有两个类的分类问题,通常选择sigmoid函数σ(z),令z=wTh+b,我们的输出层函数即为 P(y=1)=σ(z), 令P(y=0)=σ(−z),可知P(y=1)+P(y=0)=1,得到一个有效的概率分布。书上给出了更详细的推导过程:假定非归一化的对数概率logP(y)对y和z是线性的,即logP(y)=yz,对它取指数和归一化,从而引入sigmoid变换。
P(y) = σ((2y−1)z) ,其对应的损失函数为 J(θ) = −logσ((2y−1)z) = ς((1−2y)z) ,其中 ς(x) = log(1+exp(x)) 为softplus function。softplus function的函数如下图所示
可以看出只有当 (1−2y)z 取绝对值非常大的负值时才会饱和,而这种情况只出现在模型已经能够做出准确预测的情况,即y=1且z极正,或者y=0而z极负,在这种情况下,梯度很小,但由于我们已经得到了足够准确的预测,并不需要更新网络。对于对z作出错误预测的情况,即y=1且z为负,或y=0且z为正,(1-2y)z可以简化为|z|,在此区间softplus function并不饱和,梯度较大,所以网络能够很快地改正错误的z
上面的分析解释了,代价函数中的log抵消了sigmoid中的exp。当我们使用其他的损失函数,例如均方误差之类的,损失函数就会在σ(z)饱和时饱和。sigmoid激活函数在z取非常小的负值时会饱和到0,当z取非常大的正值时会饱和到1。这种情况一旦发生,梯度会变得非常小以至于不能用来学习,无论此时模型给出的是正确还是错误的答案。因此,最大似然几乎总是训练sigmoid输出单元的优选方法。
如果我们需要描述目标是多个class的概率分布,常用Softmax函数作分类器的输出,来表示n个不同类上的概率分布。
神经网络中进行的处理有推理(inference)和学习两个阶段。当神经网络的推理只需要给出一个答案的情况下,因为此时只对得分最大值感兴趣,所以不需要 Softmax 层。不过,神经网络的学习阶段则需要 Softmax 层
对于目标是n个class的情况,我们需要矢量来表述 y^ ,其中 y^i=P(y=i|x) ,每一个 y^i 都需要满足在[0,1]区间内,且所有 y^i 的和为1,使得它表示一个有效的概率分布,所以我们需要用softmax函数,令logP(y)=z,通过指数化和归一化可以推导出softmax函数的形式:
和logistic sigmoid一样,当使用最大化对数似然训练softmax来输出目标值y时,使用指数函数工作地非常好。
为了最小化损失函数,对于y=i, 我们则希望最大化
其中第一项 zi 是当前直接贡献项,鼓励zi被推高。第二项则鼓励所有的z被压低,对任何明显小于max z的zk ,exp(zk)都是不重要的,所以log∑exp(zj)≈max z ,于是第二项可以理解为对最不正确的预测做出的惩罚,当然softmax输入中贡献最大的也可能是正确项,则两项可近似抵消, lossP(y)≈0,说明这个数据样本对整体的损失贡献较小,我们可以集中精力处理其他没有正确分类的数据。
像sigmoid一样,softmax激活函数可能会饱和(当其中一个输入是最大(zi =max z)并且zi 远大于其他的输入时,相应的输出softmax(z)i 会饱和到1。当zi 不是最大值并且最大值非常大时,相应的输出softmax(z)i 也会饱和到0),不使用对数来抵消softmax中的指数的目标函数,当指数函数的变量取非常小的负值时会造成梯度消失,从而无法学习,特别是平方误差,对于softmax单元来说,它是一个很差的损失函数,即使模型做出高度可信的不正确预测,也不能训练模型改变其输出
导数:
换句话说,导数是softmax模型分配的概率与实际发⽣的情况(由独热标签向量表⽰)之间的差异。从这个意义上讲,这与我们在回归中看到的⾮常相似,其中梯度是观测值y和估计值y^之间的差异。这不是巧合,在任何指数族分布模型中,对数似然的梯度正是由此得出的
我们经常想要执行多峰回归(multimodal regression),即预测条件分布p (y|x)的实值,该条件分布对于相同的 x 值在 y 空间中有多个不同的峰值 ,它的输出层也被称为混合密度层(Mixture of Density),具有n个分量的高斯混合输出由下面的条件分布定义:
其中 p(c=i|x) 是对于n个组分的multinoulli分布。
同样采取交叉熵作为其损失函数。
大多数的隐藏单元都可以描述为接受输入向量 x ,计算线性变换z=WTx+b ,然后使用一个逐元素的非线性函数g(z)。大多数隐藏单元的区别仅仅在于激活函数g(z)的形式
当必须要使用sigmoid激活函数时,双曲正切激活函数通常要比logistic sigmoid函数表现更好
sigmoid激活函数在除了前馈网络以外的情景中更为常见。循环网络、许多概率模型以及一些自编码器有一些额外的要求使得它们不能使用分段线性激活函数,并且使得sigmoid单元更具有吸引力,尽管它存在饱和性的问题
ReLu代码实现
sigmoid
架构(architecture)一词是指网络的整体结构:它应该具有多少单元,以及这些单元应该如何连接。主要的架构考虑是选择网络的深度和每一层的宽度。
universal approximation theorem万能近似定理证明:仅有一层隐藏层的前馈网络,只要给予足够数量的隐藏单元,就足够表示任何函数的近似到任意的精度。那我们为什么还经常要构建更深层次的网络呢?首先,仅有一层隐藏层的前馈网络可能大得不可实现,在最坏情况下,可能需要指数数量的隐藏单元。其次,训练算法可能由于过拟合而选择了错误的函数。通过使⽤更深(⽽不是更⼴)的⽹络,我们可以更容易地逼近许多函数。通常,我们选择2的若⼲次幂作为层的宽度。因为内存在硬件中的分配和寻址⽅式,这么做往往可以在计算上更⾼效。
设计模型的时候,有这样的两难:如果模型的容量大,那么在数据集大小不变的情况下容易过拟合;如果模型的容量小,那么表现力较差,不容易学到好的结果。深度神经网络可以做到“鱼与熊掌兼得”。当表示同一个函数时,深层网络对每一层使用更少的单元数和更少的参数,从而比浅层网络使用更少的参数,不容易过拟合。换句话说,深层网络可以用更少的参数达到同等水平(或者更强)的表现力。
这一点结合卷积运算中的滤波器大小来思考就好理解了。下图展示了由 5 × 5 的滤波器构成的卷积层,输出数据的各个节点感受野是5
重复两次 3 × 3 的卷积运算,输出数据的各个节点感受野也是5
一次 5 × 5 的卷积运算的区域可以由两次 3 × 3 的卷积运算抵充。并且,相对于前者的参数数量 25(5 × 5),后者一共是 18(2 × 3 × 3,这里都没有考虑偏置),通过叠加卷积层,参数数量减少了。而且,这个参数数量之差会随着层的加深而变大。比如,重复三次 3 × 3 的卷积运算时,参数的数量总共是 27。而为了用一次卷积运算“观察”与之相同的区域,需要一个 7 × 7 的滤波器,此时的参数数量是 49。
并且,通过叠加层,将 ReLU 等激活函数夹在卷积层的中间,进一步提高了网络的表现力。这是因为向网络添加了基于激活函数的“非线性”表现力,通过非线性函数的叠加,可以表现更加复杂的东西。
加深层的另一个好处就是使学习更加高效。在前面的卷积层中,神经元会对边缘等简单的形状有响应,随着层的加深,开始对纹理、物体部件等更加复杂的东西有响应。考虑一下“狗”的识别问题。要用浅层网络解决这个问题的话,卷积层需要一下子理解很多“狗”的特征。“狗”有各种各样的种类,根据拍摄环境的不同,外观变化也很大。因此,要理解“狗”的特征,需要大量富有差异性的学习数据,而这会导致学习需要花费很多时间。通过加深网络,就可以分层次地分解需要学习的问题,分层次地传递信息,各层需要学习的问题就变成了更简单的问题。比如,最开始的层只要专注于学习边缘就好,而和印有“狗”的照片相比,包含边缘的图像数量众多,并且边缘的模式比“狗”的模式结构更简单。提取了边缘的层的下一层能够使用边缘的信息,高效地学习更加高级的模式。也就是说,通过加深层,可以将各层要学习的问题分解成容易解决的简单问题,只需用较少的学习数据就可以高效地进行学习
Goodfellow的实验表明,增加卷积网络层中参数的数量,但是不增加它们的深度,在提升测试集性能方面几乎没有效果。图例标明了用于画出每条曲线的网络深度。可以观察到,在这个例子中,浅层模型在参数数量达到2000万时就过拟合,而深层模型在参数数量超过6000万时仍然表现良好。这表明,函数应该由许多更简单的函数复合在一起而得到,学到由更简单的表示所组成的表示(例如,由边所定义的角)或者学习具有顺序依赖步骤的程序(例如,首先定位一组对象,然后分割它们,之后识别它们)。
这部分内容主要参考了深度学习入门(鱼书)
反向传播就是从损失函数,使用链式法则计算梯度(gradient)的过程,最常需要计算的梯度是代价函数关于参数的梯度。
设x是实数,f和g是从实数映射到实数的函数。假设y=g(x)并且z=f(g(x))=f(y)。那么链式法则是说
假设向量x映射到向量y,向量y映射到标量z,那么
使用向量记法,可以等价地写成
式子左边第一项是g的n×m的Jacobian矩阵,第二项是值z关于向量y的梯度。反向传播算法由图中每一个这样的Jacobian梯度的乘积操作所组成。
梯度的数值微分
乘法层代码
加法层代码
如果考虑x为四维张量,代码如下
class Affine:
def __init__(self, W, b):
self.W =W
self.b = b
self.x = None
self.original_x_shape = None
# 权重和偏置参数的导数
self.dW = None
self.db = None
def forward(self, x):
# 对应张量
self.original_x_shape = x.shape
x = x.reshape(x.shape[0], -1)
self.x = x
out = np.dot(self.x, self.W) + self.b
return out
def backward(self, dout):
dx = np.dot(dout, self.W.T)
self.dW = np.dot(self.x.T, dout)
self.db = np.sum(dout, axis=0)
dx = dx.reshape(*self.original_x_shape) # 还原输入数据的形状(对应张量)
return dx
softmax的反向传播结果是y^-y
class SoftmaxWithLoss:
def __init__(self):
self.loss = None
self.y = None # softmax的输出
self.t = None # 监督数据
def forward(self, x, t):
self.t = t
self.y = softmax(x)
self.loss = cross_entropy_error(self.y, self.t)
return self.loss
def backward(self, dout=1):
batch_size = self.t.shape[0]
if self.t.size == self.y.size: # 监督数据是one-hot-vector的情况
dx = (self.y - self.t) / batch_size
else:
dx = self.y.copy()
dx[np.arange(batch_size), self.t] -= 1
dx = dx / batch_size
return dx
在计算机中计算梯度的代数表达式时,许多子表达式可能在梯度的整个表达式中重复若干次,计算梯度的程序都需要选择是存储子表达式产生的中间变量(第三行)还是重新计算它们(第四行),前者减少计算量,当存储这些表达式的值所需的存储较少时,这种方式是较优的;后者减少内存开销,当存储受限时它是有用的,不过由于这些重复子表达式的存在,简单的算法可能具有指数运行时间。
反向传播算法被设计为减少公共子表达式的数量而不考虑存储的开销。具体来说,在正向传播过程中计算了网络中每个节点的值,反向传播过程中利用这些值以及导数的链式法则结合动态规划的方法避免重复运算,极大的提高了梯度计算速度
反向传播算法:为了计算某个标量z关于图中它的一个祖先 x 的梯度,首先观察到它关于z的梯度由dz / dz = 1 给出。然后,用当前的梯度乘以产生z的操作的Jacobian矩阵,得到z关于其父节点的梯度,以这种方式向后穿过计算图,直到到达需要计算梯度的目标变量。在计算了这些梯度以后,梯度下降算法或者其他优化算法所要做的就是使用这些梯度来更新参数。
在机器学习中,许多策略被显式地设计来减少测试误差(可能会以增大训练误差为代价),这些策略被统称为正则化。在实际的深度学习场景中我们几乎总是会发现,最好的拟合模型(从最小化泛化误差的意义上)是一个适当正则化的大型模型。
许多正则化方法通过对目标函数J 添加一个参数范数惩罚Ω(θ) ,限制模型(如神经网络、线性回归或逻辑回归)的学习能力,将正则化后的目标函数记为J
其中α∈[0,∞) 是权衡惩罚项Ω 和标准目标函数J(X;θ) 相对贡献的超参数。将α 设为0表示没有正则化;α越大,对应正则化惩罚越大。当我们的训练算法最小化正则化后的目标函数 时,它会降低原始目标函数J 关于训练数据的误差并同时减小在某些衡量标准下参数θ (或参数子集)的规模。选择不同参数范数Ω 会偏好不同的解。
在神经网络中,参数包括每一层仿射变换的权重和偏置,我们通常只对权重做惩罚而不对偏置做正则惩罚。每个偏置仅控制一个单变量。这意味着,我们不对其进行正则化也不会导致太大的方差。另外,正则化偏置参数可能会导致明显的欠拟合。因此,我们使用向量w 表示所有应受范数惩罚影响的权重,而向量 θ 表示所有参数(包括 w 和无须正则化的参数,如偏置)
L2正则化的效果了减小权重的大小,所以它又被称为权重衰减 (weight decay)。该模型的目标函数:
梯度:
更新权重:
可以看到,每步执行梯度时包含了收缩权重向量(将权重向量乘以一个常数因子)的一项。
L2 正则化能让学习算法“感知”到具有较高方差的输入 x ,因此与输出目标的协方差较小(相对增加方差)的特征的权重将会收缩
可以看到,正则化对梯度的影响不再是线性地缩放每个wi;而是添加了一项与sign(wi)同号的常数。对于L2正则化,如果J的最优解不是0,那么的最优解也不是0。L1正则化在某些情况下会使wi推向0或变成0。相比L2 正则化,L1 正则化会产生更稀疏 (sparse)的解。由L1正则化导出的稀疏性质已经被广泛地用于特征选择(feature selection)机制(从可用的特征子集选择出有意义的特征),因为它可以使某些权重为零,说明相对应的特征可以安全地忽略掉。
实践中,我们拥有的数据量是很有限的,解决这个问题的一种方法是创建假数据并添加到训练集中。对分类来说这种方法是最简单的,因为分类面临的一个主要任务是要对各种各样的变换保持不变,可以通过转换训练集中的 x来生成新的( x ,y)对。对于其他许多任务来说并不那么容易,例如,除非我们已经解决了密度估计问题,否则在密度估计任务中生成新的假数据是很困难的。
数据集增强对对象识别特别有效。图像是高维的并包括各种巨大的变化因素,其中有许多可以轻易地模拟。沿训练图像每个方向平移几个像素的操作通常可以大大改善泛化。许多其他操作如旋转图像或缩放图像也已被证明非常有效。
我们必须要小心,不能使用会改变类别的转换。例如,光学字符识别任务需要认识到“b”和“d”以及“6”和“9”的区别,所以对这些任务来说,水平翻转和旋转180°并不是合适的数据集增强方式。
在神经网络的输入层注入噪声也可以看作数据增强的一种方式。然而,神经网络被证明对噪声不是非常健壮。正则化策略Dropout,可以看作通过与噪声相乘构建新输入的过程
对于某些模型而言,向输入添加方差极小的噪声等价于对权重施加范数惩罚。在一般情况下,注入噪声远比简单地收缩参数强大,特别是噪声被添加到隐藏单元时会更加强大,Dropout算法是这种做法的主要发展方向。我的理解:很多人说batchnorm有轻微的正则化效果,因为计算时使用了batch数据的平均值,引入了噪音,大概就是这个意思。
另一种正则化模型的噪声使用方式是将其加到的权重。这项技术主要用于循环神经网络
多任务学习也是希望令模型的参数能够进行很好的泛化,其原理是多个任务共享模型的一部分(输入及某些中间的表示层)时,通常会带来更好的泛化能力。
下图中,不同的监督任务(给定x预测y (i)) 共享相同的输入x以及一些中间层表示 h (share) , h(1) 和 h(2) 专用于每个任务(分别预测 y(1) 和 y(2) )
该模型通常可以分为两类相关的参数:
(1)具体任务的参数(只能从各自任务的样本中实现良好的泛化),如图中的上层。
(2)所有任务共享的通用参数(从所有任务的汇集数据中获益),如图中的下层。
因为共享参数,其统计强度可大大提高(共享参数的样本数量相对于单任务模式有所增加 ), 并能改善泛化误差的范围。当然,仅当不同的任务之间存在某些统计关系的假设是合理(意味着某些参数能通过不同任务共享)时才会发生这种情况。
通常对于较大的模型,我们会观察到训练集上的误差不断减小,但验证集上的误差会在某个点之后反而逐渐增大,这意味着为了减小泛化误差,可以在训练过程中不断的记录验证集上的误差及对应的模型参数,最终返回验证集上误差最小的模型参数,这个简单直观的方法就是early stopping。可以认为提前终止是非常高效的超参数选择算法。按照这种观点,训练步数仅是另一个超参数。
在每次验证集误差有所改善后,我们存储模型参数的副本,当训练算法终止时,我们返回这些参数而不是最新的参数。当验证集上的误差在事先指定的循环次数内没有进一步改善时,算法就会终止。
有效和简单,几乎不需要改变基本训练过程、目标函数或一组允许的参数值,并且限制训练的迭代次数而明显减少的计算成本。可能是深度学习中最常用的正则化形式。
训练期间要定期评估验证集。在理想情况下,这可以并行在与主训练过程分离的机器上,或独立的CPU(或GPU)上完成。如果没有这些额外的资源,可以使用比训练集小的验证集或较不频繁地评估验证集来减小评估代价,较粗略地估算取得最佳的训练时间。另一个代价是需要保持最佳的参数副本。这种代价一般是可忽略的,因为可以将它储存在较慢较大的存储器上(例如,在GPU内存中训练,但将最佳参数存储在主存储器或磁盘驱动器上)。由于最佳参数的写入很少发生而且从不在训练过程中读取,这些偶发的慢写入对总训练时间的影响不大
提前终止可单独使用或与其他的正则化策略结合使用。即使为鼓励更好泛化,使用正则化策略改进目标函数,在训练目标的局部极小点达到最好泛化也是非常罕见的。言外之意:训练集上达到的最优参数未必靠谱,还是应该在训练的时候还是应该在验证集上跑一跑
提前终止需要验证集,这意味着某些训练数据不能被馈送到模型。为此,可以在完成提前终止的首次训练之后,进行第二轮训练,将所有的训练数据包括在内。有两个基本的策略可以用于第二轮训练过程。一个策略是第二轮再次初始化模型,然后使用第一轮提前终止训练确定的最佳步数,以及所有数据再次训练。但是没有办法知道重新训练时,对参数进行相同次数的更新和对数据集进行相同次数的遍历哪一个更好。另一个策略是保持从第一轮训练获得的参数,然后使用全部的数据继
续训练。为终止训练,可以每过n步监控验证集的平均损失函数,直到它第一轮训练终止时的值。此策略避免了重新训练模型的高成本,但表现并没有那么好。例如,验证集的目标不一定能达到之前的目标值,所以这种策略甚至不能保证终止。
惩罚神经网络中的激活单元,稀疏化激活单元。这种策略间接地对模型参数施加了复杂惩罚。表示的范数惩罚正则化是通过向损失函数J添加对表示的范数惩罚来实现的
使表示稀疏的方法之一是对表示元素的L1 惩罚
Bagging (bootstrap aggregating)通过整合多个模型来减小泛化误差,主要想法是分别训练几个不同的模型,然后让所有模型表决测试样例的输出,被称为模型平均 (model averaging)。采用这种策略的技术被称为集成方法。
模型平均 (model averaging)奏效的原因是不同的模型通常不会在测试集上产生完全相同的误差。在错误完全不相关的情况下,集成平方误差的期望会随着集成规模增大而线性减小
集成ensemble方法以不同的方式构建集成模型,例如集成的每个成员可以使用不同的算法和目标函数训练成完全不同的模型。Bagging方法则是同一种模型和目标函数,但是产生k种不同的训练集。每个数据集从原始数据集中重复采样构成,与原训练集所含数据量相同,但会以某一概率去掉某些样本并以其他的重复样本代替,第i个模型就在第i个训练集上进行训练,每个数据集所含样本的差异导致了训练模型之间的差异。
神经网络能找到足够多的不同的解,意味着它们可以从模型平均中受益(即使所有模型都在同一数据集上训练)。神经网络中随机初始化的差异、小批量的随机选择、超参数的差异或不同输出的非确定性实现往往足以使得集成中的不同成员具有部分独立的误差。
Dropout在指数级数量的神经网络上近似Bagging方法。ensemble常常不太实际, Dropout提供了一个更便宜的解决方案:随机去掉一些节点的方法训练多个子网络,并平均多个随机决定进行预测,实现了一种参数共享的Bagging形式如下图所示:
噪声具有正则化的效果。Dropout强大的大部分原因来自施加到隐藏单元的掩码噪声,破坏提取的特征(而不是原始值),可以看作对输入内容背后信息进行高度智能化、自适应破坏。例如,如果模型学得通过鼻检测脸的隐藏单元 hi,那么丢失 hi 对应于擦除图像中有鼻子的信息。传统的噪声注入技术,在输入端加非结构化的噪声不能够随机地从脸部图像中抹去关于鼻子的信息。Dropout的另一个重要方面是噪声是乘性的。如果是固定规模的加性噪声,那么加了噪声 ϵ 的ReLu单元可以简单地学会使 hi 变得很大(使增加的噪声 ϵ 变得不显著)。乘性噪声不允许这样病态地解决噪声鲁棒性问题
另一种深度学习算法——批标准化,在训练时向隐藏单元引入加性和乘性噪声重新参数化模型,有时没必要再使用Dropout
随机选取一个binary mask(0表示节点输出为零,1表示正常输出该节点)决定哪些输入或隐藏层节点保留,每次的mask的选择是独立的。而mask为1的概率是我们可以调控的超参数。通常在每一个小批量训练的神经网络中,一个输入单元被包括的概率为 0:8,一个隐藏单元被包括的概率为 0:5。
bagging中每个模型是完全独立的,而dropout中,所有模型共享参数(每个模型继承父神经网络参数的不同子集),这使得在有限的存储空间中我们可以表示多个模型。除了这些, Dropout与Bagging算法一样。例如,每个子网络中遇到的训练集确实是有放回采样的原始训练集的一个子集。
因为我们通常使用 1/2 的包含概率,权重比例规则一般相当于在训练结束后将权重除 2,然后像平常一样使用模型,确保在测试时一个单元的期望总输入与在训练时该单元的期望总输入是大致相同的
计算方便:训练过程中使用Dropout产生 n 个随机二进制数与状态相乘,每个样本每次更新只需 O(n) 的计算复杂度。根据实现,也可能需要O(n) 的存储空间来持续保存这些二进制数(直到反向传播阶段)。另一个显著优点是不怎么限制适用的模型或训练过程,几乎在所有使用分布式表示且可以用随机梯度下降训练的模型上都表现很好。许多效果差不多的其他正则化策略对模型结构的限制更严格。Srivastava et al. (2014) 显示, Dropout比其他标准的计算开销小的正则化方法(如权重衰减、过滤器范数约束和稀疏激活的正则化)更有效
在一个完整的系统上使用Dropout的代价可能非常显著。Dropout是一个正则化技术,它减少了模型的有效容量,为了抵消这种影响,必须增大模型规模,也增加了训练算法的迭代次数。对于非常大的数据集, 正则化带来的泛化误差减少得很小。在这些情况下,使用Dropout和更大模型的计算代价可能超过正则化带来的好处。只有极少的训练样本可用时, Dropout不会很有效
这部分可以参考本书作者的一个专题讲座(笔记):
CS231n 笔记- 对抗模型和对抗训练_iwill323的博客-CSDN博客
本文参考:genehz神经网络损失函数、输出层、隐藏层详解——深度学习第六章(二) - 知乎,