反向传播:
def backward(self, dout):
# 反向传播函数
# dout 表示输出层的误差
dx = np.dot(dout, self.W.T) # 计算输入 x 的梯度 dx = dout * W^T
self.dW = np.dot(self.x.T, dout) # 计算权重 W 的梯度 dW = x^T * dout
self.db = np.sum(dout, axis=0) # 计算偏置 b 的梯度 db = sum(dout, axis=0)
# 还原输入数据的形状(对应张量)
dx = dx.reshape(*self.original_x_shape) # 还原输入 x 的原始形状
return dx # 返回输入 x 的梯度
总结
out=W*x+b
- 计算输入 x 的梯度 dx:通过 dout与 W 的转置相乘得到。
- 计算权重 W 的梯度 dW:通过 x 的转置与 dout 相乘得到。
- 计算偏置 b 的梯度 db:通过对 dout 沿着样本轴求和得到。
1. Momentum
概念:
- Momentum 是一种加速梯度下降的方法,它通过引入动量的概念来加速收敛过程。在梯度下降中,每次更新权重时都会根据当前梯度的方向和大小来移动。Momentum 方法则会考虑之前几次梯度的方向,使得更新更加平滑和稳定。
工作原理:
- 在 Momentum 方法中,每次梯度更新时都会加上一个动量项,该动量项是前几次梯度更新方向的加权平均。
- 动量项的引入有助于减少震荡,尤其是在梯度方向频繁变化的情况下,它可以使得更新方向更加稳定,从而更快地收敛到最小值附近。
- 动量项通常由一个动量系数(momentum coefficient)乘以前一次的梯度更新量来计算。
2. AdaGrad
概念:
- AdaGrad(Adaptive Gradient)是一种自适应学习率优化算法,它可以根据每个参数的历史梯度来动态调整学习率。这意味着每个参数会有自己的学习率,而且随着训练的进行,学习率会逐渐减小。
工作原理:
- AdaGrad 为每个参数维护一个历史梯度平方的累加和,然后使用这个累加和来调整每个参数的学习率。
- 通过这种方式,AdaGrad 可以自动调整参数的学习率,对于经常被更新的参数,学习率会减小得更快,而对于较少被更新的参数,则保持较高的学习率。当参数被频繁更新时,这意味着该参数所在的特征可能对损失函数有较大影响,学习率减小可以防止这些参数过度调整,从而减少过拟合的风险。
3. Adam
概念:
- Adam(Adaptive Moment Estimation)结合了 Momentum 和 AdaGrad 的优点。它同时利用了动量的思想和自适应学习率的特点,既保持了 Momentum 的快速收敛特性,又具备了 AdaGrad 的自适应学习率的优点。
工作原理:
- Adam 通过计算梯度的一阶矩估计(即梯度的加权平均)和二阶矩估计(即梯度平方的加权平均)来动态调整学习率。
- Adam 方法中的一阶矩类似于 Momentum,二阶矩则类似于 AdaGrad 的累加梯度平方。
梯度消失:在使用反向传播算法训练深度神经网络时,当梯度从输出层向输入层反向传播时,梯度的值可能会变得越来越小,直到接近于零。这意味着在网络的早期层(即靠近输入的层)中,权重的更新几乎停止,这阻碍了网络的学习过程。
原因
-
激活函数的选择:
- 标准的激活函数如 sigmoid 或 tanh 在其输入较大或较小时,其导数非常接近于 0。当这些激活函数被用于深度网络时,多次乘以接近 0 的导数会导致梯度迅速减小。
-
权重初始化:
- 如果权重初始化不当,例如使用较小的值进行初始化,那么在反向传播过程中,这些小的权重值会进一步放大梯度消失的问题。
-
网络深度:
- 随着网络层数的增加,反向传播过程中梯度的乘积效应变得更加显著,导致梯度消失问题更加严重。
影响
-
学习缓慢:
- 梯度消失会导致网络的学习速率降低,因为权重更新的步长变得非常小。
-
训练停滞:
- 在最坏的情况下,梯度消失可能导致训练过程完全停滞,因为权重不再更新。
-
局部最优解:
- 由于梯度消失,模型可能被困在次优的局部极小值中,无法达到全局最优解。
ReLU(Rectified Linear Unit)激活函数在神经网络中非常常用,尤其是在卷积神经网络(CNNs)和全连接网络中。ReLU 的定义很简单:对于任何输入 x,其输出为 max(0,x)。这意味着对于所有负输入,ReLU 的输出为 0,而对于所有正输入,其输出等于输入值。
ReLU 的问题
ReLU 的主要问题之一是在负输入时导数为 0,这可能导致所谓的“死神经元”现象,即一旦神经元的输入变成负数,其梯度就变成了 0,权重将不再更新,神经元将永远处于不活跃状态。
权重初始化的重要性
权重初始化对于避免梯度消失或梯度爆炸至关重要。对于 ReLU 激活函数,权重初始化尤其重要,因为它直接影响到神经元是否会在训练初期就被“杀死”。
ReLU 的权重初始化
为了避免 ReLU 的“死神经元”问题,通常推荐使用特定的初始化方法来确保权重的分布有助于激活函数的正常工作。以下是几种常用的初始化方法:
He 初始化:
- 原理:
- He 初始化是专门为 ReLU 设计的一种初始化方法,它考虑到 ReLU 的非线性特性,通过保证权重的方差与输入节点的数量相匹配来避免梯度消失。
采用He之前的测试集准确率85.93% 之后的 89.66% 明显增加了一些