# 从公式角度看深度学习

学习基于尚硅谷:https://www.bilibili.com/video/BV1MRJmzSEaa

# 损失函数

# 均方误差 MSE / L2 Loss(回归问题较适用)

Mean Squared Error(MSE)

L=1ni=1n(yiti)2\begin {array}{c} L=\frac{1}{n} \sum_{i=1}^{n}(y_{i}-t_{i})^{2} \end{array}

这个 ti 是目标标签 (向量),yi 是预测标签 (向量),n 是总个数。

往往我们在是实际使用的是时候,使用下面这个公式。

L=12ni=1n(yiti)2\begin {array}{c} L=\frac{1}{2n} \sum_{i=1}^{n}(y_{i}-t_{i})^{2} \end{array}

L2 Loss 对异常值敏感,遇到异常值时易发生梯度爆炸。

def mean_squared_error(y, t):
    return 0.5 * np.sum((y-t)**2)

# 交叉熵误差 CEE(分类问题较适用)

Cross Entropy Error(CEE)

L=1ni=1ntilog(yi)\begin {array}{c} L=-\frac{1}{n} \sum_{i=1}^{n} t_{i} \log (y_{i}) \end{array}

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)
        
    # 监督数据是 one-hot 向量的情况下,转换为正确解标签的索引
    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=1ni=1ntilog(yi)+(1ti)log(1yi)\begin {array}{c} L=-\frac{1}{n} \sum_{i=1}^{n} t_{i} \log (y_{i})+(1-t_{i}) \log (1-y_{i}) \end{array}

# 多类交叉熵误差 CCEE

Categorical Cross-Entropy Loss

L=1ni=1nj=1Ctijlog(yij)\begin {array}{c} L=-\frac{1}{n} \sum_{i=1}^{n} \sum_{j=1}^{C} t_{i j} \log (y_{i j}) \end{array}

# 平均绝对误差 MAE / L1 Loss

Mean Absolute Erro

L=1ni=1nyiti\begin {array}{c} L=\frac{1}{n} \sum_{i=1}^{n}|y_{i}-t_{i}| \end{array}

L1 Loss 对异常值鲁棒,但在 0 点处不可导。

# 平滑 L1 误差 / Smooth L1

Smooth L1

Smooth L1={12(yiy^i)2,if yiy^i<1yiy^i12,if yiy^i1\begin {array}{c} \text{Smooth } L1 = \begin{cases} \frac{1}{2}(y_i - \hat{y}_i)^2, & \text{if } |y_i - \hat{y}_i| < 1 \\ |y_i - \hat{y}_i| - \frac{1}{2}, & \text{if } |y_i - \hat{y}_i| \geq 1 \end{cases} \end{array}

# 梯度

梯度

L=Lw1w1x+Lw2w2x++Lwnwnx\begin {array}{c} \nabla L=\frac{\partial L}{\partial w_{1}} \frac{\partial w_{1}}{\partial x}+\frac{\partial L}{\partial w_{2}} \frac{\partial w_{2}}{\partial x}+\cdots+\frac{\partial L}{\partial w_{n}} \frac{\partial w_{n}}{\partial x} \end{array}

梯度是关于参数的导数,即对于参数 w1,w2,w3,w4,w5…wn,求关于 x 的导数,这些偏导数组成的向量就是梯度,如下面这个形式。

L=[Lw1,Lw2,Lw3,Lw4,Lw5,,Lwn]\begin {array}{c} \nabla L=\left[\frac{\partial L}{\partial w_{1}}, \frac{\partial L}{\partial w_{2}}, \frac{\partial L}{\partial w_{3}}, \frac{\partial L}{\partial w_{4}}, \frac{\partial L}{\partial w_{5}}, \cdots, \frac{\partial L}{\partial w_{n}}\right] \end{array}

在极小值处、极大值处和鞍点处,梯度向量都为 0。

梯度代表的其实是函数值增大最快的方向;在实际应用中,我们需要寻找损失函数的最小值,所以一般选择负梯度
向量。同样地,负梯度代表的是函数值减小最快的方向,并不一定直接指向函数图像的最低点。

# 优化函数

# 随机梯度下降 SGD

stochastic Gradient Descent

wt+1=wtηL(wt)\begin {array}{c} w_{t+1}=w_{t}-\eta \nabla L(w_{t}) \end{array}

η\eta 是学习率,一般取 0.01。

SGD 有以下问题:

  1. 局部最优解:陷入局部最优,尤其在非凸函数中,难以找到全局最优解。
  2. 鞍点:陷入鞍点,梯度为 0,导致训练停滞。
  3. 收敛速度慢:高维或非凸函数中,收敛速度较慢。
  4. 学习率选择:学习率过大导致震荡或不收敛,过小则收敛速度慢。

# 自适应梯度 AdaGrad

AdaGrad

wt+1=wtη1i=1n(wt,i)2+ϵL(wt)\begin {array}{c} w_{t+1}=w_{t}-\eta \frac{1}{\sqrt{\sum_{i=1}^{n}\left(w_{t, i}\right)^{2}+\epsilon}} \nabla L(w_{t}) \end{array}

AdaGrad 的优点是:

  1. 快速收敛:在非凸函数中,AdaGrad 能够快速收敛到全局最优解。
  2. 梯度加速:在凸函数中,AdaGrad 能够加速梯度下降,使得训练速度更快。

# 动量法 Momentum

Momentum

wt+1=wt+ηmt\begin {array}{c} w_{t+1}=w_{t}+\eta m_{t} \end{array}

mt=βmt1+(1β)L(wt)\begin {array}{c} m_{t}=\beta m_{t-1}+\left(1-\beta\right) \nabla L(w_{t}) \end{array}

β\beta 是动量的超参数,一般取 0.9。

动量的作用是加速梯度下降,会保存历史梯度并给予一定的权重,使其也参与到参数更新中,使得梯度下降速度更快。
其中,mt-1 是历史梯度,mt 是当前梯度。
在当前梯度中,也包含了历史梯度,因此,mt-1 中的历史梯度也会被加入到当前梯度中,从而实现梯度加速。

# Adam

Adam

mt=β1mt1+(1β1)L(wt)\begin {array}{c} m_{t}=\beta_{1} m_{t-1}+(1-\beta_{1}) \nabla L(w_{t}) \end{array}

vt=β2vt1+(1β2)L(wt)2\begin {array}{c} v_{t}=\beta_{2} v_{t-1}+(1-\beta_{2}) \nabla L(w_{t})^{2} \end{array}

wt+1=wtηv^t+ϵm^t\begin {array}{c} w_{t+1}=w_{t}-\frac{\eta}{\sqrt{\hat{v}_{t}}+\epsilon} \hat{m}_{t} \end{array}

β1\beta_{1}β2\beta_{2} 是 Adam 算法中的两个超参数,一般取 0.9 和 0.999。
ϵ\epsilon 是 Adam 算法中的超参数,一般取 1e-8。
m^t\hat{m}_{t}v^t\hat{v}_{t} 是 Adam 算法中的两个中间变量,分别表示mtm_{t}vtv_{t} 的估计值。
m^t\hat{m}_{t}v^t\hat{v}_{t} 的计算公式如下:

m^t=mt1β1t\begin {array}{c} \hat{m}_{t}=\frac{m_{t}}{1-\beta_{1}^{t}} \end{array}

v^t=vt1β2t\begin {array}{c} \hat{v}_{t}=\frac{v_{t}}{1-\beta_{2}^{t}} \end{array}

# AdamW

AdamW

wt+1=wtηv^t+ϵm^t+λwt\begin {array}{c} w_{t+1}=w_{t}-\frac{\eta}{\sqrt{\hat{v}_{t}}+\epsilon} \hat{m}_{t}+\lambda w_{t} \end{array}

λ\lambda 是 AdamW 算法中的超参数,一般取 0.01。
m^t\hat{m}_{t}v^t\hat{v}_{t} 的计算公式如下:

m^t=mt1β1t\begin {array}{c} \hat{m}_{t}=\frac{m_{t}}{1-\beta_{1}^{t}} \end{array}

v^t=vt1β2t\begin {array}{c} \hat{v}_{t}=\frac{v_{t}}{1-\beta_{2}^{t}} \end{array}

# 学习率衰减机制

# 等间隔衰减

ηt=η0(1tT)p\begin {array}{c} \eta_{t}=\eta_{0}\left(1-\frac{t}{T}\right)^{p} \end{array}

η0\eta_{0} 是初始学习率,TT 是总迭代次数,pp 是衰减因子,一般取 0.5。
等间隔衰减的缺点是,学习率衰减过快,导致训练效果变差。

# 指定间隔衰减

在指定的 epoch,让学习率按照一定的系数衰减,直到指定 epoch 结束,再按照初始学习率继续训练。

# 指数衰减

ηt=η0×(0.99)t/T\begin {array}{c} \eta_{t}=\eta_{0} \times \left(0.99\right)^{t / T} \end{array}

η0\eta_{0} 是初始学习率,TT 是总迭代次数。
指数衰减的缺点是,学习率衰减过慢,导致训练效果变差。

# 余弦退火

ηt=η0×(0.5(1+cos(πtT)))\begin {array}{c} \eta_{t}=\eta_{0} \times \left(0.5\left(1+\cos\left(\frac{\pi t}{T}\right)\right)\right) \end{array}

η0\eta_{0} 是初始学习率,TT 是总迭代次数。
余弦退火算法的优点是,学习率衰减速度适中,训练效果较好。

# 初始化

# He 初始化(Kaiming 初始化)

He 初始化的优点是,初始化后的权重分布更接近于标准正态分布,从而加速训练。

import torch.nn as nn
linear = nn.Linear(5, 2)
# Kaiming 正态分布初始化
nn.init.kaiming_normal_(linear.weight)
print(linear.weight)
# Kaiming 均匀分布初始化
nn.init.kaiming_uniform_(linear.weight)
print(linear.weight)

# 正则化

机器学习的问题中过拟合是一个很常见的问题。

过拟合指的是能较好拟合训练数据,但不能很好地拟合不包含在训练数据中的其他数据。机器学习的目标是提高泛化能力,希望即便是不包含在训练数据里的未观测数据,模型也可以进行正确的预测。因此可以通过
正则化方法来抑制过拟合。

常用的正则化方法有 Batch Normalization、权值衰减、Dropout、早停法等。

# Batch Normalization 批量标准化

Batch Normalization

y=xμσ2+ϵ\begin {array}{c} y=\frac{x-\mu}{\sqrt{\sigma^{2}+\epsilon}} \end{array}

其中,μ\mu 是均值,σ2\sigma^{2} 是方差,ϵ\epsilon 是一个很小的数,一般取 0.001。

更新于 阅读次数

请我喝[茶]~( ̄▽ ̄)~*

KarryLiu 微信支付

微信支付

KarryLiu 支付宝

支付宝