# 从公式角度看深度学习
学习基于尚硅谷:https://www.bilibili.com/video/BV1MRJmzSEaa
# 损失函数
# 均方误差 MSE / L2 Loss(回归问题较适用)
Mean Squared Error(MSE)
L=n1∑i=1n(yi−ti)2
这个 ti 是目标标签 (向量),yi 是预测标签 (向量),n 是总个数。
往往我们在是实际使用的是时候,使用下面这个公式。
L=2n1∑i=1n(yi−ti)2
L2 Loss 对异常值敏感,遇到异常值时易发生梯度爆炸。
| def mean_squared_error(y, t): |
| return 0.5 * np.sum((y-t)**2) |
# 交叉熵误差 CEE(分类问题较适用)
Cross Entropy Error(CEE)
L=−n1∑i=1ntilog(yi)
yi 表示神经网络的输出,ti 表示正确解标签;而且,ti 中只有正确解标签对应的值为 1,其它均为 0(one-hot 表示)。
| def cross_entropy_error(y, t): |
| if y.ndim == 1: |
| t = t.reshape(1, t.size) |
| y = y.reshape(1, y.size) |
| |
| |
| if t.size == y.size: |
| t = t.argmax(axis=1) |
| |
| batch_size = y.shape[0] |
| return -np.sum(np.log(y[np.arange(batch_size), t] + 1e-7)) / batch_size |
# 二元交叉熵误差 BCEE
Binary Cross-Entropy Loss
L=−n1∑i=1ntilog(yi)+(1−ti)log(1−yi)
# 多类交叉熵误差 CCEE
Categorical Cross-Entropy Loss
L=−n1∑i=1n∑j=1Ctijlog(yij)
# 平均绝对误差 MAE / L1 Loss
Mean Absolute Erro
L=n1∑i=1n∣yi−ti∣
L1 Loss 对异常值鲁棒,但在 0 点处不可导。
# 平滑 L1 误差 / Smooth L1
Smooth L1
Smooth L1={21(yi−y^i)2,∣yi−y^i∣−21,if ∣yi−y^i∣<1if ∣yi−y^i∣≥1
# 梯度
梯度
∇L=∂w1∂L∂x∂w1+∂w2∂L∂x∂w2+⋯+∂wn∂L∂x∂wn
梯度是关于参数的导数,即对于参数 w1,w2,w3,w4,w5…wn,求关于 x 的导数,这些偏导数组成的向量就是梯度,如下面这个形式。
∇L=[∂w1∂L,∂w2∂L,∂w3∂L,∂w4∂L,∂w5∂L,⋯,∂wn∂L]
在极小值处、极大值处和鞍点处,梯度向量都为 0。
梯度代表的其实是函数值增大最快的方向;在实际应用中,我们需要寻找损失函数的最小值,所以一般选择负梯度
向量。同样地,负梯度代表的是函数值减小最快的方向,并不一定直接指向函数图像的最低点。
# 优化函数
# 随机梯度下降 SGD
stochastic Gradient Descent
wt+1=wt−η∇L(wt)
η 是学习率,一般取 0.01。
SGD 有以下问题:
- 局部最优解:陷入局部最优,尤其在非凸函数中,难以找到全局最优解。
- 鞍点:陷入鞍点,梯度为 0,导致训练停滞。
- 收敛速度慢:高维或非凸函数中,收敛速度较慢。
- 学习率选择:学习率过大导致震荡或不收敛,过小则收敛速度慢。
# 自适应梯度 AdaGrad
AdaGrad
wt+1=wt−η∑i=1n(wt,i)2+ϵ1∇L(wt)
AdaGrad 的优点是:
- 快速收敛:在非凸函数中,AdaGrad 能够快速收敛到全局最优解。
- 梯度加速:在凸函数中,AdaGrad 能够加速梯度下降,使得训练速度更快。
# 动量法 Momentum
Momentum
wt+1=wt+ηmt
mt=βmt−1+(1−β)∇L(wt)
β 是动量的超参数,一般取 0.9。
动量的作用是加速梯度下降,会保存历史梯度并给予一定的权重,使其也参与到参数更新中,使得梯度下降速度更快。
其中,mt-1 是历史梯度,mt 是当前梯度。
在当前梯度中,也包含了历史梯度,因此,mt-1 中的历史梯度也会被加入到当前梯度中,从而实现梯度加速。
# Adam
Adam
mt=β1mt−1+(1−β1)∇L(wt)
vt=β2vt−1+(1−β2)∇L(wt)2
wt+1=wt−v^t+ϵηm^t
β1 和β2 是 Adam 算法中的两个超参数,一般取 0.9 和 0.999。
ϵ 是 Adam 算法中的超参数,一般取 1e-8。
m^t 和v^t 是 Adam 算法中的两个中间变量,分别表示mt 和vt 的估计值。
m^t 和v^t 的计算公式如下:
m^t=1−β1tmt
v^t=1−β2tvt
# AdamW
AdamW
wt+1=wt−v^t+ϵηm^t+λwt
λ 是 AdamW 算法中的超参数,一般取 0.01。
m^t 和v^t 的计算公式如下:
m^t=1−β1tmt
v^t=1−β2tvt
# 学习率衰减机制
# 等间隔衰减
ηt=η0(1−Tt)p
η0 是初始学习率,T 是总迭代次数,p 是衰减因子,一般取 0.5。
等间隔衰减的缺点是,学习率衰减过快,导致训练效果变差。
# 指定间隔衰减
在指定的 epoch,让学习率按照一定的系数衰减,直到指定 epoch 结束,再按照初始学习率继续训练。
# 指数衰减
ηt=η0×(0.99)t/T
η0 是初始学习率,T 是总迭代次数。
指数衰减的缺点是,学习率衰减过慢,导致训练效果变差。
# 余弦退火
ηt=η0×(0.5(1+cos(Tπt)))
η0 是初始学习率,T 是总迭代次数。
余弦退火算法的优点是,学习率衰减速度适中,训练效果较好。
# 初始化
# He 初始化(Kaiming 初始化)
He 初始化的优点是,初始化后的权重分布更接近于标准正态分布,从而加速训练。
| import torch.nn as nn |
| |
| linear = nn.Linear(5, 2) |
| |
| |
| nn.init.kaiming_normal_(linear.weight) |
| print(linear.weight) |
| |
| |
| nn.init.kaiming_uniform_(linear.weight) |
| print(linear.weight) |
# 正则化
机器学习的问题中过拟合是一个很常见的问题。
过拟合指的是能较好拟合训练数据,但不能很好地拟合不包含在训练数据中的其他数据。机器学习的目标是提高泛化能力,希望即便是不包含在训练数据里的未观测数据,模型也可以进行正确的预测。因此可以通过
正则化方法来抑制过拟合。
常用的正则化方法有 Batch Normalization、权值衰减、Dropout、早停法等。
# Batch Normalization 批量标准化
Batch Normalization
y=σ2+ϵx−μ
其中,μ 是均值,σ2 是方差,ϵ 是一个很小的数,一般取 0.001。