神经网络 基本知识整理
激活函数
我们知道神经网络中前一层与后面一层的连接可以用y = wx + b
表示,这其实就是一个线性表达,即便模型有无数的隐藏层,简化后依旧是上述的线性表达式,那么模型的拟合能力非常受限。因此引入了激活函数σ,y = σ(wx + b)
,使得模型能够拟合非线性的问题。常用的激活函数详解可参考👉激活函数详解 ///激活函数详解
sigmoid
sigmoid激活函数表达式是: f ( x ) = 1 1 + e − x f(x) = \frac{1}{1+e^{-x}} f(x)=1+e−x1
sigmoid常用于二分类中(输出层而非中间层),因为其能够很好的拟合0~1这个范围内的数。函数图像如下:
sigmoid函数的导数 为: f ′ ( x ) = f ( x ) ∗ ( 1 − f ( x ) ) f'(x) = f(x)*(1-f(x)) f′(x)=f(x)∗(1−f(x))
根据图像也能看出其导数在x极大or极小的时候,导数是趋近于0的;即便是x=0时,取其导数的最大值,依旧只有1/4,因此如果将sigmoid作为中间层的激活函数,在利用链式法则反向求导的过程中,很容易导致梯度消失。
根据sigmoid激活函数的特点,可以得到对应的优缺点。
优点:
- 可解释性强:Sigmoid 函数的输出在 0 到 1 之间,可以被解释为概率,特别适用于二分类问题。
- 平滑性:Sigmoid 函数是连续可导的,因此在梯度下降等优化算法中应用较为方便。
- 求导方便,不需要额外的计算量。
缺点:
- 以(0, 0.5)为对称中心,原点不对称,容易改变输出的数据分布;
- 梯度饱和:在输入较大或较小的情况下,Sigmoid 函数的梯度会非常接近于 0,导致梯度消失问题,影响模型的训练效果;导数取值范围为(0, 0.25],连乘后梯度呈指数级减小,所以当网络加深时,浅层网络梯度容易出现梯度消失;
- 输出不以 0 为中心:Sigmoid 函数的输出均值不为 0,可能导致在反向传播过程中出现偏移,影响模型的收敛速度;
tanh
tanh激活函数的表达式: f ( x ) = e x − e − x e x + e − x f(x) =\frac{e^{x}-e^{-x}}{e^{x}+e^{-x}} f(x)=ex+e−xex−e−x
tanh函数是奇函数,关于原点对称,导数为: f ′ ( x ) = 1 − ( f ( x ) 2 ) f'(x) = 1-(f(x)^{2}) f′(x)=1−(f(x)2)
tanh函数图像如下图所示👇。tanh和sigmoid非常相似,tanh可看作sigmoid放大平移的。
优点:
- 输出以 0 为中心:Tanh 函数的输出均值为 0,相比 Sigmoid 函数,Tanh 函数对数据的均值变化更为敏感,有助于模型的训练。
- 非线性特性:Tanh 函数是非线性的,可以帮助神经网络学习和表示复杂的函数关系。
缺点: - 梯度饱和:与 Sigmoid 函数类似,Tanh 函数在输入较大或较小的情况下,梯度会接近于 0,可能导致梯度消失问题。
- 计算复杂度:Tanh 函数的计算相对复杂,可能会增加模型的计算成本。
softmax
softmax是sigmoid的拓展,表达式: f ( x i ) = e x i ∑ j = 1 n e x j f(x_{i}) = \frac{e^{x_{i}}}{\sum_{j=1}^{n}e^{x_{j}}} f(xi)=∑j=1nexjexi
softmax激活函数常用于多分类场景 ,对最后一层神经网络的输出进行转换,同时常搭配交叉熵损失函数使用: L ( y , y ^ ) = − ∑ j = 1 n y j log ( y j ^ ) L(y,\hat{y}) = -\sum_{j=1}^{n}y_{j}\log(\hat{y_{j}}) L(y,y^)=−j=1∑nyjlog(yj^)
优点:
- 归一化:Softmax 函数可以将输出转化为概率分布,所有输出的和为 1,适用于多分类问题。
- 平滑性:Softmax 函数的输出相对平滑,有助于模型的训练和收敛。
缺点:
- 计算复杂度:Softmax 函数的计算相对复杂,尤其在类别数目很大时,可能会增加模型的计算成本。
- 容易受到异常值影响:在输入较大或较小的情况下,Softmax 函数的输出可能会非常接近 0 或 1,使得模型对异常值比较敏感。
Relu
Relu函数是一个分段函数,其每一段都是线性的,但由于分段使其在全局内是非线性的,音系Relu是一个非线性的函数。表达式: f ( x ) = m a x ( x , 0 ) f(x) = max(x,0) f(x)=max(x,0)
图像:
Relu两段导数都是固定的常数,因此常用于神经网络的中间层。但是Relu将x<0这一段直接设置为0,很多神经元阶段的输出为0,使得神经元失活。因此有很多Relu的变性,比如Leaky_Relu,在x<0的一段引入很小的斜率。
优点:
- 非饱和性:相比于 Sigmoid 和 Tanh 函数,ReLU 在正区间上不会饱和,减少了梯度消失问题,有助于训练深层网络。
- 计算简单:ReLU 函数的计算相对简单,只需判断输入是否大于 0,因此在实际应用中的计算速度较快。
- ReLU 函数广泛应用于隐藏层,特别是在深度卷积神经网络(CNN)中,有助于加速模型的训练。
缺点:
- 死亡 ReLU:在训练过程中,部分神经元可能永远不会被激活(输出恒为 0),导致这些神经元对应的权重无法更新,称为"死亡 ReLU"问题。
- 输出不以 0 为中心:与 Tanh 相比,ReLU 函数的输出不以 0 为中心,可能导致一些问题,如收敛速度较慢。
ReLU 的变体:
- Leaky ReLU:解决了"死亡 ReLU"问题,引入一个小的斜率(通常很小的斜率值,如0.01),使得负数输入时也有少量的输出。
- Parametric ReLU (PReLU):与 Leaky ReLU 类似,但斜率是一个可学习的参数,可以通过反向传播进行训练。
- Randomized Leaky ReLU (RReLU):斜率在训练过程中是随机的,但在测试时取平均值,有一定的正则化效果。
- Exponential Linear Unit (ELU):引入了负半轴的指数函数,解决了 ReLU 的输出不以 0 为中心的问题,并且对负数输入有非零输出。
梯度
梯度的物理含义
我们在学习y=f(x)这样的一元函数的导数 的时候,知道函数在某一点的导数其实就是在该点切线的斜率,反应了函数在该点的变化方向以及变化速率,注意这个方向其实是函数增加的方向。
在空间中一个点有无数个方向,一个多元函数在某一个点也必然有无线多个方向。此时引入了梯度,梯度是多元函数对每一个变元求偏导后组成的偏导向量 。多元函数对某一变元求偏导得到的是函数在某坐标轴的变化率 ,将这些偏导组合得到的梯度就代表多元函数在某一点变化最快的方向(该向量指向的方向)以及变化的速率(向量的模) ,同样这里的变化是指函数增长,那么反方向就是函数减小:
梯度下降
机器学习的目标函数/损失函数是关于可训练参数W的多元函数 ,这个函数在某一点的梯度(这里的某一点就是某一个数据点 [(x1,x2,x3,...,xn), y]
)反应了误差变化的方向与快慢,之后用这个梯度来更新参数W,使得损失函数值减少,直到找到全局最优or局部最优。 用梯度更新参数的过程其实就是梯度下降算法,多层网络从后往前逐层计算梯度的过程是误差反向传播,两者结合训练模型。 梯度下降具体可以用如下式子表示:
梯度下降是用➖,梯度上升就用➕。因为前面提到梯度是函数增加的方向,我们一般是需要损失函数最小(局部或者全局),因此是沿着梯度的反方向。 这里的W是所有参数组成的向量;α是学习率,学习率过高和过低都不行【过低更新缓慢,时间长且可能局部最优;过高变化太大,可能一直动荡不收敛,可能错过最优点,可能造成梯度爆炸】,可以去了解一下torch里面的优化器optimizer对lr的调整策略👉pytorch自适应学习率调整。
这里需要注意的是,对于每一个数据点都有一个梯度,我们实际是需要将目标函数在所有数据点上的梯度求均值 ,然后进行一次参数更新的(full-batch)。但训练数据是上万的,一次计算所有数据点的梯度计算量很大,因此在实际操作中会将数据集数据进行分批处理,每次对一个batch的数据点求目标函数的梯度均值 ,然后进行一次参数更新(mini-batch)。可参考👉mini-batch
梯度消失and梯度爆炸
梯度是根据链式法则,从后往前反向计算的。如果网络太深,前面层对应参数的偏导会极小或者极大,这就是梯度消失和梯度爆炸。
- 梯度消失:指在反向传播过程中,梯度逐渐变小,最终接近于零。这意味着底层神经元的权重几乎不会被更新,导致网络无法学习到底层特征,从而影响了整个网络的性能。梯度消失通常出现在使用 Sigmoid 或 Tanh 等饱和性激活函数时,因为这些函数在输入较大或较小的情况下梯度接近于零。
- 梯度爆炸:指梯度变得非常大,甚至超出了计算机可以表示的范围。这会导致参数的更新值非常大,模型的行为变得不稳定,甚至可能无法收敛。
以实际的例子讨论【参考梯度消失和梯度爆炸】:
要计算误差关于b1这个参数的偏导,通过链式法则得到看上面的式子,假设σ是sigmoid函数,上面分析了sigmoid的导数值在0~0.25之间:
- 随着网络层数的增加,前面层的偏导中会有越来越多的σ'的连乘,导数会越来越小;
- 如果一开始w初始化很大,使得
(σ' * wi)>1
,那么同样随着网络层数的增加,(σ' * wi)连乘使得偏导越来越大。
避免梯度消失or梯度爆炸的方法中,Batch normalization(批标准化)是非常重要的,后续再总结!