梯度下降和反向传播:
- 简单理解就是把误差函数曲线比喻成下山,找局部误差最小的点相当于找此段山峰下山的最低谷位置,梯度的方向是误差变化最快的方向(上山最快的方向),所以要往梯度的反方向走(下山最快的方向)反向传播帮我们算出 “当前位置的梯度”(指对下山方向);梯度下降拿着这个梯度,迭代调整模型参数(沿着下山方向一步步走)最终走到梯度为 0 的局部最优点(山脚),误差最小。
- 梯度下降于反向传播
感知机(神经元):
- 更新流程:首先用第一组x1和x2带入求出output,然后求出Δ,再依次更新w和b,然后第二组,第三组依此类推更新w和b,直到迭代次数满足停止条件后,得到最终的w和b,此时通常来说该组wi和b求得的结果是最接近真实值的然后就可以带入新的数据,利用最终的w和b进行预测了
- y = x1w1 + x2w2 + b; η:学习率 Δ:Δ = label - output
- 更新的w权重 w = wi + ηxiΔ 更新的b: b = bi + η*Δ
- 输入 --> 加权求和+偏置 --> 激活函数处理 --> 输出
- 感知机
MLP(多个神经元组成的神经网络,全连接)
- 输入层(1 层) --> 隐藏层(多层) --> 输出层(1 层) --> 激活函数处理(sigmoid 函数,S 曲线) --> 输出
- MLP
CNN 卷积神经网络(局部连接):
- 更适合图像、语音识别任务的神经网络结构
- 卷积层:输入矩阵依次与卷积核进行对应位置相乘求和并加上偏置项,依次得到卷积结果(注意步长), 输出尺寸:
- 输出尺寸:( 输入尺寸 + 2 * padding - 卷积核尺寸 ) / 步长 + 1
- 避免图像边缘信息被浪费,在图像矩阵四周横竖加上一圈的 0,称为 padding,
- 可以等边填充(最常用,输入与输出大小一致),也可以完全填充(卷积核任何能扫到的地方都填充,输出尺寸最大,很少用)
- 池化层:简单来说就是比如输入尺寸是 44,取左上角22 部分的最大值作为代表值,即Max Pooling方法,也可以用平均值
- 反向传播的异同:权重共享、局部连接、池化层与张量维度做了特殊处理,核心是通过梯度聚合与转置卷积实现高效的特征学习与参数更新
- 输入层 - 卷积层 1 - 池化层 1 -卷积层 2 - 池化层 2 -全连接 层
- CNN
RNN 循环神经网络:多用于自然语言处理领域
- 单向 RNN:只能记住前面的信息,其中 St 为隐藏层 t 时刻输出,Xt 为 t 时刻输入,Ut 为输入到隐藏层输入权重,Vt 是隐藏到输出层权重,Ot 是 t 时刻输出
- 计算方式:St = F(Xt * Ut + Wt) ,其中 Wt 就是 St-1
- 双向 RNN:可以记住上下文信息,其中V'表示方向时候 t 时刻的 V
- 计算方式: Ot = g(Vt St + Vt' St') St = F(Xt * Ut + Wt) St' = F(Xt * Ut' + Wt')此时的 Wt'是 St+1'
- 通俗理解就是:RNN 在神经网络顺序连接的时候,把上一次隐藏层的输出添加到了下一层隐藏层的权重中,来达到"记忆功能"的
- RNN 容易出现梯度爆炸和消失的问题,主要原因就是反向传播的函数是一个指数函数,容易导致对应的误差项数值变化非常快
- 梯度爆炸可以通过设置梯度阈值来处理
- 梯度消失:1合理的初始化权重值 2 使用relu代替sigmoid和tanh作为激活函数 3 使用其他结构的RNN
- RNN
LSTM: 可以解决长距离依赖场景(超长序列)
- 简单来说LSTM就是在RNN的基础上,又加入了一个状态C,用来保存长期记忆
- 注:可以理解 C 状态是一个单独的长线状态,每个时刻还有一个单元状态,有点类似于 git 上更新代码的感觉
- t 时刻的时候,输入有三个:Xt,Wt (St-1), Ct-1 ; 输出有两个: Ht(上一次计算的输出) Ct
- 关于 C 状态,有三个开关:
- 遗忘门f:决定上个时刻的 Ct-1 有多少能保留到当前的 Ct, 公式:Ft = sigmoid(Wf*[Ht-1, Xt] + Bf)
- 输入门:决定当前 Xt 中有多少可以保存到当前 Ct 公式:= Ft * Ct-1 + It * Ct'
- 当前输入: It = sigmoid(Wi*[Ht-1, Xt] + Bi)
- 当前输入单元的状态 Ct ' = tanh(Wc*[Ht-1, Xt] + Bc)
- 输出门:决定当前 Ct 有多少输出到 Ot 公式:sigmoid(Wo*[Ht-1, Xt] + Bo)
- 最终结果: Ht = Ot * tanh (Ct)
GRU:LSTM 一个比较成功的变体(小序列)
- 改动 1 : 输入门,遗忘门和输出门合并成 更新门Zt(忘旧和吸新是反向的,合并)和重置门Rt(辅助更新门)
- 改动 2: 把单元状态和输出合并为一个状态:Ht(类似于单元状态合并到了隐藏状态,然后直接输出,输出门已经被更新门取代)
- LSTM&GRU
优化器:为梯度下降法配置的一个的"领航员",寻找模型最优解又要避免出现局部最优解,使之能快速高效的达到"目标"
-
SGD( 随机梯度下降法):无法克服产生局部震荡,从而只是实现了局部最优解的问题
- GD:ΔT会在每输入一个样本就更新一次
- BGD:ΔT会在批量输入数据之后才更新一次(也就是那个batchsize参数)
- SGD:在批量的前提下,随机抽取一个样本更新ΔT
- 是最基础的优化器,每次只随机选取一个样本计算梯度来更新参数:
- 优点是计算量小、收敛速度快,而且有一定的随机性可以跳出局部最优;
- 缺点是,更新的方向很不稳定,波动很大,而且容易在鞍点或者平缓区域停滞。
-
SGDM:带有惯性因子的SGD
- 当更新本次参数的时候,动量因子会根据动量系数保留部分上次梯度,当梯度方向不发生变化那动量因子会加速更新(类比山谷就是陡坡加速到谷底即可),反之方向相反就要减速最好是直接跳过局部最优解的山谷,前往全部最优解的山谷
- 更新的方向更稳定,同时也能加快在正确方向上的收敛速度,解决了 SGD 波动大的问题,但还是没办法解决学习率的问题,学习率需要手动设置,而且对所有参数都是同一个学习率。
-
NAG:( 加速梯度))
- NGA中使用"下一步位置"也就是未来的梯度来替换当前位置梯度来完成"探路",如果下一步位置比当前更陡峭,那就提前"刹车"防止走不到坡底在动量的推动下跳上了另一个高坡从而错过全部最优解,这样就会比纯动量更加保险,就像在动量上加一个限速锁防止走的太快
- 提前预判更新的方向,减少更新时的过冲,相比 SGDM,在一些场景下收敛会更精准,不过本质上还是动量的优化,没有解决学习率的核心问题
-
Adagrad (自适应梯度优化器)
- 引入一个新的概念就是对每个参数进行"缓存",来判断该参数更新的频率,该值是集合了直到当前点为止的梯度的平方如果权重进行了非常大的更新,那么其缓存值也将增加学习率将变得更小,随之权重的更新幅度会随时间而减少。反之如果权重没有进行任何重大更新,那么其缓存值将非常小学习率将提高,从而迫使其进行较大的更新
- 第一次实现了自适应的学习率,它会给每个参数都设置独立的学习率,对于出现频率低的特征(参数),会设置更大的学习率,对于出现频率高的特征,学习率会更小,非常适合处理稀疏数据;但缺点是随着训练的进行,学习率会不断衰减,到后期会趋近于 0,导致训练提前停止。
-
RMSProp:修改了AdaGrad的梯度积累为指数加权的移动平均,以及增加一个新参数,衰减率参数γ,防止训练过程提前结束的问题
- RMSProp和下面要介绍的Adadelta 都是为了解决 Adagrad 学习率急剧下降问题的
- 针对 AdaGrad 学习率衰减过快的问题做了改进,它加入了一个滑动平均的机制,只保留最近一段时间的梯度信息,而不是累积所有的梯度,这样学习率不会衰减到 0,同时也保留了自适应学习率的优点,解决了 AdaGrad 的问题,适合处理非平稳的目标函数。
-
Adadelta:AdaGrad算法和RMSProp算法都需要指定全局学习率,AdaDelta算法属于是结合了两种算法更新参数的优点
- RMSProp 的进一步优化,它连初始学习率都不需要手动设置了,通过对更新步长的动态调整,来自动适配学习率,进一步简化了参数的设置,不过在一些复杂的场景下,收敛的稳定性不如后面的 Adam
-
Adam:前面SGD-M在SGD基础上增加了一阶动量,AdaGrad和AdaDelta在SGD基础上增加了二阶动量(其实就是那个平方项,很多参考资料称之为二阶动量),那么把一阶动量和二阶动量都用起来就是Adam的构成了,即:Adaptive(Adadelta, RMSProp,Adagrad) + Momentum。
- 可以自适应地为每个参数调整学习率,而且收敛速度快,稳定性也很好,是目前最常用的优化器之一,几乎可以适用于大多数的深度学习场景。
| 优化器 | 核心改进点 | 核心优势 | 核心劣势 | 适用场景 |
|---|---|---|---|---|
| SGD | 基础随机梯度更新 | 计算成本低、有随机性易跳出局部最优、实现简单 | 更新波动大、易停滞、学习率固定 | 数据量较大的简单任务、需要手动控制训练过程的场景 |
| SGDM | 加入动量(梯度惯性) | 削弱更新波动、收敛方向更稳定、加快收敛速度 | 学习率仍需手动设置、无自适应学习率 | 大多数普通的深度学习任务,替代 SGD 使用 |
| NAG | 基于未来梯度计算动量 | 减少更新过冲、收敛更精准 | 本质还是动量优化,未解决学习率问题 | 对收敛精度有一定要求,且目标函数有明显方向的场景 |
| AdaGrad | 自适应学习率(按参数独立调整) | 适配稀疏数据、自动调整不同参数的学习率 | 学习率衰减过快,后期趋近于 0 导致训练停止 | 稀疏数据场景(如 NLP 的词向量训练) |
| RMSProp | 加入梯度滑动平均,只保留近期梯度 | 解决 AdaGrad 学习率衰减过快问题、适配非平稳目标函数 | 仍需要设置初始学习率 | 非平稳目标函数的任务、深度学习的常规场景 |
| AdaDelta | 无需手动设置初始学习率,动态调整步长 | 进一步简化参数设置、学习率自适应更灵活 | 复杂场景下收敛稳定性不如 Adam | 不想手动设置学习率,且任务复杂度中等的场景 |
| Adam | 结合动量与自适应学习率,考虑梯度一二阶矩 | 收敛速度快、稳定性强、适用范围广 | 部分场景下可能收敛到局部最优(而非全局最优) | 绝大多数深度学习场景,是目前的默认选择 |
| Nadam | 结合 Adam 与 NAG 的加速梯度 | 收敛精度更高、速度更快 | 计算量比 Adam 稍大 | 对收敛精度要求高的复杂任务 |
交叉熵损失函数比MSE更适合分类任务的原因:
- 错误越严重,惩罚越狠(高效),梯度直接,无消失问题; 让类别概率 “非黑即白”
- 惩罚温和,对大错不敏感(低效),梯度易变小,可能消失; 让预测值接近真实值(连续拟合)
- 交叉熵损失