深度学习笔记(八)—— 正则化[Regularization]

  这是深度学习笔记第八篇,完整的笔记目录可以点击这里查看。
  
  下面介绍几种可以控制神经网络的容量以防止过拟合(overfitting)的方法:

1. L2 regularization

  L2正则化可能是最常见的正则化形式。它可以通过直接惩罚(penalize)目标中所有参数的平方大小来实现。也就是说,对于网络中的每个权重w,我们将1/2λw2项添加到目标中,其中λ是正则化强度。使用系数1/2是为了使该项相对于参数w的梯度为λw而不是2λw。L2正则化具有严重惩罚峰值权重向量和偏好扩散权重向量的直观解释。由于权重和输入之间的乘法运算,这具有一个很好的特性,即鼓励网络少量使用其所有输入,而不是大量使用其部分输入。最后,请注意,在梯度下降参数更新过程中,使用L2正则化最终意味着每个权重都会线性衰减到0,W += -lambda * W

2. L1 regularization

  L1正则化是另一种相对常见的正则化形式,其中对于每个权重w,我们将λ∣w∣添加到目标。可以将L1正则化与L2正则化结合起来:λ1∣w∣+λ2w2(这称为弹性网正则化,Elastic net regularization)。L1正则化具有一个有趣的特性,即它会导致权重向量在优化过程中变得稀疏(即非常接近于零)。换句话说,具有L1正则化的神经元最终只使用其最重要输入的稀疏子集,并且对“噪声”输入几乎不变。相比之下,L2正则化的最终权重向量通常是分散的、小数量的。在实践中,如果不关心显式特征选择,L2正则化的性能往往优于L1正则化。
  对于L1正则化会产生稀疏性的一个直观解释是,L1正则化函数的图形有很多角(比如在二维情况下是一个棱形),损失函数J0与L1的顶点相交的概率比与边相交要大,而与顶点相交则会有很多权值为0(在坐标轴上)。而对于L2正则化,其图形是圆滑的(比如在二维情况下是一个圆),损失函数J0与L2所有部位都可能相交,而这些部位大概率不会落在坐标轴上,也就是不会出现很多权值为0的情况。因此说,L1正则化可以产生稀疏权值矩阵,即产生一个稀疏模型,可以用于特征选择;而L2正则化可以防止模型过拟合(overfitting)。因为L2正则化可以获得值很小的参数,而拟合过程中通常都倾向于让权值尽可能小,最后构造一个所有参数都比较小的模型。因为一般认为参数值小的模型比较简单,能适应不同的数据集,也在一定程度上避免了过拟合现象。当然一定程度上,L1也可以防止过拟合(当L1的正则化系数很小时)。参考

3. Max norm constraints

  正则化的另一种形式是对每个神经元的权向量的大小施加一个绝对上界,并使用投影梯度下降来施加约束。实际上,这相当于正常执行参数更新,然后通过钳制每个神经元的权重向量w来进行强制约束,以满足∥w∥2

4. Dropout

  Dropout是Srivastava等人引入的一种非常有效、简单的正则化技术。在训练过程中,Dropout是通过以某种概率p(一个超参数)来保持神经元处于激活状态的,否则就设置为零。
深度学习笔记(八)—— 正则化[Regularization]_第1张图片
  Dropout论文中的插图。在训练过程中,Dropout可以解释为在全部神经网络中对一个神经网络进行采样,并且只根据输入数据更新采样网络的参数。然而,采样到的网络可能并不是独立的,因为它们共享参数。
  Vanilla dropout在一个三层神经网络上的应用示例如下:

""" Vanilla Dropout: Not recommended implementation (see notes below) """

p = 0.5 # probability of keeping a unit active. higher = less dropout

def train_step(X):
  """ X contains the data """
  
  # forward pass for example 3-layer neural network
  H1 = np.maximum(0, np.dot(W1, X) + b1)
  U1 = np.random.rand(*H1.shape) < p # first dropout mask
  H1 *= U1 # drop!
  H2 = np.maximum(0, np.dot(W2, H1) + b2)
  U2 = np.random.rand(*H2.shape) < p # second dropout mask
  H2 *= U2 # drop!
  out = np.dot(W3, H2) + b3
  
  # backward pass: compute gradients... (not shown)
  # perform parameter update... (not shown)
  
def predict(X):
  # ensembled forward pass
  H1 = np.maximum(0, np.dot(W1, X) + b1) * p # NOTE: scale the activations
  H2 = np.maximum(0, np.dot(W2, H1) + b2) * p # NOTE: scale the activations
  out = np.dot(W3, H2) + b3

  在上面的代码中,在train_step函数中,我们执行了两次dropout:第一个隐藏层和第二个隐藏层。也可以在输入层上执行dropout,在这种情况下,我们还将为输入X创建一个二进制masks。反向传播保持不变,但当然必须考虑生成的masks U1U2
  关键的是,在predict函数中,我们不再执行dropout,而是使用参数p对两个隐层输出进行缩放。这一点很重要,因为在test的时候,所有神经元都能看到它们的所有输入,所以我们希望神经元在test时候的输出与训练时的预期输出相同。例如,在p=0.5的情况下,神经元必须在测试时将其输出减半,以获得与训练时相同的输出(预期)。要看到这一点,考虑一个神经元x的输出(在dropout之前)。在dropout时,该神经元的预期输出将变为px+(1−p)0,因为神经元的输出将有1−p的概率为零。在test的时候,当我们保持神经元始终处于激活状态时,我们必须调整x→px以保持相同的预期输出。
  上述方案的缺点是,我们必须在test的时候用参数p来缩放激活值。由于测试时间性能(test-time performance)非常关键,因此最好使用反向dropout(inverted dropout),它在train的时候执行缩放,使test-time的前向传播保持不变。此外,它还有一个良好的特性,即当你决定调整使用dropout的位置时,预测(prediction)部分的代码可以保持不变。Inverted dropout代码示例如下:

""" 
Inverted Dropout: Recommended implementation example.
We drop and scale at train time and don't do anything at test time.
"""

p = 0.5 # probability of keeping a unit active. higher = less dropout

def train_step(X):
  # forward pass for example 3-layer neural network
  H1 = np.maximum(0, np.dot(W1, X) + b1)
  U1 = (np.random.rand(*H1.shape) < p) / p # first dropout mask. Notice /p!
  H1 *= U1 # drop!
  H2 = np.maximum(0, np.dot(W2, H1) + b2)
  U2 = (np.random.rand(*H2.shape) < p) / p # second dropout mask. Notice /p!
  H2 *= U2 # drop!
  out = np.dot(W3, H2) + b3
  
  # backward pass: compute gradients... (not shown)
  # perform parameter update... (not shown)
  
def predict(X):
  # ensembled forward pass
  H1 = np.maximum(0, np.dot(W1, X) + b1) # no scaling necessary
  H2 = np.maximum(0, np.dot(W2, H1) + b2)
  out = np.dot(W3, H2) + b3

  在第一次引入dropout之后,人们对此进行了大量的研究,试图理解它在实践中的拥有这么的效果的原因,以及它与其他正则化技术的关系。感兴趣的读者推荐的进一步阅读:Dropout论文,Dropout Training as Adaptive Regularization。

5. Bias regularization

  调整bias参数并不常见,因为它们不会通过乘法与数据相互作用,因此不会控制数据维度对最终结果影响。然而,在实际应用中(并在适当的数据预处理后),正则化bias基本上不会对性能造成巨大的不良影响。这可能是因为与所有权重的数据量相比,bias项非常少。因此,如果分类器需要bias来获得更好的loss结果,它可以“负担得起”使用bias。

6. Summary

  在实际应用中,最常见的是使用交叉验证的单个全局L2正则化。将其与在所有层之后应用的dropout相结合也是很常见的。p=0.5是一个合理的默认值,但可以根据validation数据进行调整。



*本博客翻译总结自CS231n课程作业网站,该网站需要才能访问。

你可能感兴趣的:(CS231n课程笔记,神经网络,python,机器学习,人工智能,深度学习)