参考文章:
梯度下降:https://www.bilibili.com/video/BV1r64y1s7fU
早停法:https://www.datalearner.com/blog/1051537860479157
正则化:https://www.cnblogs.com/jianxinzhou/p/4083921.html
2017笔记:https://blog.csdn.net/oldmao_2001/article/details/90714657
2021笔记:https://zhuanlan.zhihu.com/p/395527363
2021.09.30
LeeML-Notes:P18,P19
2021.10.18 更新
LeeML2021:P5,P6,P8,P9内容:
① 2.4.1 Critical Point: small gradient
② 2.0 Batch 大小,对优化的影响
③ 2.4.2 Adaptive Learning Rate
④ 2.5 Batch Normalization(批次标准化)
首先看有没有过拟合?也就是训练数据表现好,测试数据不行
上图中,56层的模型对比20层的模型,无论是在training set还是testing set上表现都要差,这个事情并不是Overfitting的原因,而是没有训练好
<----------------2021新增内容1--------------->
- 将一笔大型资料分若干批次计算 loss 和梯度,从而更新参数
- 每看完一个epoch 就把这笔大型资料打乱,然后重新分批次
- 这样能保证每个 epoch 中的 batch 资料不同,避免偶然性
【大小批次的运算时间对比】
【大小批次的性能对比】
【总结】
小批次在 1 个 epoch 中的速度很慢,耗时很长,但是小批次在优化过程性能更好,在测试时的性能也更好。而批次大小是一个超参数,需要自行设定。
model = Sequential()
model.add(Dense(input_dim=28*28,units=500,activation='sigmoid'))
model.add(Dense(units=500,activation='sigmoid'))
model.add(Dense(units=10,activation='softmax'))
units=500 改为 units=689 效果会好一点
model = Sequential()
model.add(Dense(input_dim=28*28,units=689,activation='sigmoid'))
model.add(Dense(units=689,activation='sigmoid'))
model.add(Dense(units=10,activation='softmax'))
deep learning 就是很deep的样子,那么才三层,用for添加10层
model.add(Dense(input_dim=28*28,units=689,activation='sigmoid'))
model.add(Dense(units=689,activation='sigmoid'))
model.add(Dense(units=689,activation='sigmoid'))
for _ in range(10):
model.add(Dense(units=689,activation='sigmoid'))
model.add(Dense(units=10,activation='softmax'))
用sigmoid函数 ,高层会表现不好,改用ReLU
#搭NN:
model = Sequential()
model.add(Dense(input_dim=28*28,units=689,activation='relu'))
model.add(Dense(units=689,activation='relu'))
model.add(Dense(units=10,activation='softmax'))
① 比起sigmoid,计算速度快(看形状就知道啦)
② 看原作者论文提到,这个是有生物学上有一定原因
③ 相当于无限个不同bias的sigmoid函数叠加
④ 解决了梯度消失问题(最重要),ReLU可以分成两部分,小于0的输出0,大于0的输出原值,也就是线性的,所以上面的神经网络可以看成:
- 剩下的所有神经元都是线性的,所以整个网络变成一个瘦长的线性网络:A Thinner linear network,在这个线性神经元的网络中梯度在传递的过程中是不会递减的。
- 虽然单个神经元是线性的,但是整个神经网络是非线性的,原因是:很多个线性的神经元可以形成非线性的结果,例如用很小的方块可以拼成一个大圆是一个道理。
面试常问:ReLU是不可导的,如何进行反向传播(要计算偏导)?
忽略不可导的那个点(0点)。
【变种1 】leaky ReLU
ReLU在input小于0时,output为0,这时微分为0,你就没有办法updata你的参数,所有我们就希望在input小于0时,output有一点的值(input小于0时,output等于0.01乘以input),这被叫做leaky ReLU。
【变种2】 Parametric ReLU
Parametric ReLU在input小于0时,output等于 α z \alpha z αz为neural的一个参数,可以通过training data学习出来,甚至每个neural都可以有不同的 α \alpha α值。
【变种3】 Exponential linear Unit (ELU)
没有被training到的element,那么它连接的w就不会被training到了,在做BP时,只会training在图上颜色深的实线,不会training不是max value的weight。这表面上看是一个问题,但实际上不是一个问题。
当你给到不同的input时,得到的z的值是不同的,max value是不一样的,因为我们有很多training data,而neural structure不断的变化,实际上每一个weight都会被training。
<----------------2021新增内容1--------------->
我们在优化模型中,会遇到 Critical Point(临界点) 中的局部最小值和鞍点。他们会使得梯度接近于0,导致损失值无法继续降低。
- 下图中的纵坐标是 loss 值,横坐标是向量
- 一阶微分乘自变量差值是 y轴上的绿色长度(可以用tan来理解)
- 二阶微分乘两个自变量差值是 y轴上的红色长度。【疑问1:怎么得出来的?】
【当梯度接近0时】
当梯度接近0时,即,g=0时:
- 以 θ ′ \theta' θ′为中心点,周围损失值都比它大的,那么 θ ′ \theta' θ′为损失函数的局部最小点
- 以 θ ′ \theta' θ′为中心点,周围损失值都比它小的,那么 θ ′ \theta' θ′为损失函数的局部最大点
- 以 θ ′ \theta' θ′为中心点,周围损失值有比大,有比它小,那么 θ ′ \theta' θ′为损失函数的鞍点
【举例计算】
- 我们通过让梯度g=0,得知Critical point: 1 = 0, 2 = 0
- 计算出来了H和两个特征值为2和-2,所以该点是个鞍点。
看似陷入了局部最低,但是高维上依旧能找到路进行下降,所以我们认为的局部低点是几乎不存在的,我们不需要考虑。
实验也可以证明:
训练一个网络,直到它卡在临界点。在实验中记录特征值中正值的比例(minimum ratio),当正值比例越大,该位置就更像局部最小值点,因为下降的路越少。我们发现实验的所有临界点都没有达到正值比例100%,最高竟然停留在50%附近,这证明有一半的特征值是负数,即还有一半的路 可以使loss降低,所以在实际问题中,local minima几乎不存在,也就不是梯度下降的一个痛点。
<----------------2021新增内容3--------------->
详见 《梯度下降》相应部分:https://blog.csdn.net/wistonty11/article/details/120118145
.AdaGrad算法的改进。鉴于神经网络都是非凸条件下的,RMSProp在非凸条件下结果更好,
改变梯度累积为指数衰减的移动平均以丢弃遥远的过去历史。
加上Momentum之后,每一次移动的方向是 negative gardient加上Momentum的方向, 类似一个惯性。
① 梯度下降方向是垂直等高线的,如果只是梯度方向,如图情况会是橘色线,会抖动
② Momentum(动量法)是为了对冲mini-batch带来的抖动。
③ 我们进行向量分解,发现竖直方向是抖动的,而水平方向是一致的
④ 那我们就用过去的向量+这步的梯度: V ( t ) = V ( t − 1 ) + Δ W ( t ) i V_{(t)}=V_{(t-1)}+\Delta W_{(t)i} V(t)=V(t−1)+ΔW(t)i
⑤ 但我们需要个权重,把非常早的向量忽略不计,就有了 V ( t ) = β V ( t − 1 ) + ( 1 − β ) Δ W ( t ) i V_{(t)}=\beta V_{(t-1)}+(1-\beta)\Delta W_{(t)i} V(t)=βV(t−1)+(1−β)ΔW(t)i
⑥ Momentum不能保证全局最优,但是有希望跳出局部最优
RMSProp + Momentum,这里就是要注意Adam的参数值一般来说就按推荐的取,不用调。
【Feature Normalization的一个方法】
① 对数据进行标准化
② 隐藏层 z 进行标准化
经过feature normalization后的 x~ 都在同一量级,但是 W1 的不同维度可能有不同的量级,因此计算出来的 z 在不同维度也可能有不同的量级。所以隐藏层 z 也需要进行标准化。
通过右边式子计算平均值和标准差,同个向量中的不同元素分别计算,不同向量同一维度的元素放在一起计算
计算出来的平均值向量和标准差向量大小取决于 z,所以这是一个大型网络,假如将所有的资料输入进去,GPU的内存不够存所有的训练资料,所以分批次输入资料,保证一次只对一个batch 进行标准化。但是批次标准化适用于 batch size 大的,因为只要batch够大就能足以代表全部分布。
往往在批次标准化后还要加一层网络,用于调整 z 的分布,通常刚开始设 γ=1,β=0,等到后面再改变γ,β的大小来调整 z 的分布,这两个参数需要被learn出来。
在testing中没有batch,而training时有 t 个batch,就有 t 个 μ。所以通过计算training中的 moving average(滑动平均)来代替 testing的 μ和西伽马!
训练集上表现很好,但测试集表现欠佳
常用的防止过拟合的方法是对模型加正则项,如L1、L2,dropout,但深度神经网络希望通过加深网络层次减少优化的参数,同时可以得到更好的优化结果,Early stopping的使用可以通过在模型训练整个过程中截取保存结果最优的参数模型,防止过拟合。
【主要步骤】
上图在训练集迭代到400次的时候出现了16个局部最低。也就是以可能出现短暂的最低点,然后继续继续变小。因此,我们需要一个停止的标准来实施早停法。使得它可以产生最低的泛化错误,同时也可以有最好的性价比,即给定泛化错误下的最小训练时间。停止标准有很多,也很灵活,大约有三种:
参考材料:https://www.datalearner.com/blog/1051537860479157
【思路】
如果我们用一个更高次的多项式去拟合,它能很好地拟合训练集,但却并不是一个好的结果,因为它过度拟合了数据
让我们考虑下面的假设,我们想要加上惩罚项,从而使参数 θ3 和 θ4 足够的小。
1000 只是我随便写的某个较大的数字而已。现在,如果我们要最小化这个函数,那么为了最小化这个新的代价函数,我们要让 θ3 和 θ4 尽可能小
所以,当我们最小化这个新的代价函数时, 我们将使 θ3 的值接近于 0,同样 θ4 的值也接近于 0,就像我们忽略了这两个值一样。如果我们做到这一点( θ3 和 θ4 接近 0 ),那么我们将得到一个近似的二次函数。
实际上,这些参数的值越小,通常对应于越光滑的函数,也就是更加简单的函数。因此 就不易发生过拟合的问题。
如果我们像惩罚 θ3 和 θ4 这样惩罚其它参数,就达到了更好地拟合训练数据,又很好的适应训练集
【L1 Regularization】
sgn表示符号函数,如果w是正的,sgn(w)>0,如果w是负的,sgn(w)<0
每一次更新时参数时,我们一定要去减一个 η λ s g n ( w t ) \eta \lambda sgn(w^t) ηλsgn(wt)值(w是正的,就是减去一个值;若w是负的,就是加上一个值,让参数变大)。
L2、L1都可以让参数变小,但是有所不同的,若w是一个很大的值,L2下降的很快,很快就会变得很小,在接近0时,下降的很慢,会保留一些接近01的值;L1的话,减去一个固定的值(比较小的值),所以下降的很慢。所以,通过L1-Norm training 出来的model,参数会有很大的值。
【L2 Regularization】
两种方法基本上都是让图形更光滑,让特征值w 更快接近0。L2 Regularization是按比例衰减;而L1 Regularization是按固定值衰减
就是随机把一些支持机(神经元)去掉
【原理】
【严谨思路】
【严谨思路问题】这样神经网络变化是指数级的 ,没法实现
【Dropout方法】
【例子验证相似】
我没听清会不会别的例子也可以
那么可能经过抓爆后变成四种情况:
概率一算 一样