# [cs231n (七)神经网络 part 3 : 学习和评估 ][1]

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sinat_36458870/article/details/82824556

cs231n (七)神经网络 part 3 : 学习和评估

标签(空格分隔): 神经网络


0.回顾

cs231n (一)图像分类识别讲了KNN
cs231n (二)讲了线性分类器:SVM和SoftMax
cs231n (三)优化问题及方法
cs231n (四)反向传播
cs231n (五)神经网络 part 1:构建架构
cs231n (六)神经网络 part 2:传入数据和损失

1.引言

之前入门了一个两层的神经网络,基本就是网络框架,现在就需要好好优化网络了,来打开电脑开干哈、、、么么哒~

2. 梯度检验

意不意外、惊不惊喜? 我有出现了、
其实这里就一点:用中心化公式更好

d f ( x ) d x = f ( x + h ) f ( x ) h ( b a d ) \displaystyle \frac{df(x)}{dx}=\frac{f(x+h)-f(x)}{h} (bad)
按照定义h是一个趋近于零的数值,目前计算机的能力下:近似为1e-5

d f ( x ) d x = f ( x + h ) f ( x h ) 2 h ( i n s t e a d ) \displaystyle \frac{df(x)}{dx}=\frac{f(x+h)-f(x-h)}{2h}(instead)

反正目前来说就是:费力(耗费计算能力)不讨好!

关于梯度检验我们需要掌握几点:

  • 使用双精度计算会降低误差
  • 保持小数的有效数值 看《电脑科学家应该知道的浮点运算》
  • 目标函数不可导的时候也会影响梯度精度的
  • 使用数据少点:笨啊,因为这样不可导的数据点就越少啊
  • 梯度检验期间最好是不要使用正则化
  • 不要使用dropout和数据增强(augmentation)
  • 等待梯度开始下降后再开始梯度检查
  • 检查部分维度:假设其他维度是正确的
  • 步长h的设置:一般是1e-4 ----> 1e-6 为什么?

看了这张图就知道为什么了。

梯度

3. 做到:合理性检查

  • 特定情况下的损失值应该合理
  • 是否是因为提高了正则化强度之后导致的损失值变大
  • 小数据的过拟合:不要用正则化,使用20个数据应该能达到损失是零

4. 接下来检查整个学习过程

其实就是跟踪一些重要的参数,从而达到修改超参数的便利, 比如:每个epoch的loss

1. 损失函数

损失值跟踪: 可以得到不同学习率下的损失值变化情况

1

左边:不同学习率下的loss变化,右边:随着epochloss的变化

loss震荡程度和batch size有关系哦,当size=1 震荡程度就会很大,当size=N也就是整个数据,那么震荡最小

2. 训练和验证集精度

紧接着需要跟踪的另一个指标就是:验证和训练集的准确率,看下图

2

  • 训练集和验证集之间的空隙说明:模型的过拟合程度 验证集的准确率很低,说明模型严重过拟合, 此时应该增大正则化强度(正则化项、dropout、增加数据)
  • 再则就是验证曲线和训练曲线很接近,说明模型容量太小,应该增加参数数量。

3. 权重更新

最后一个指标就是:权重值更新了的数量和全部值的比

这个比例应该在1e-3左右,如果小,说明学习率小,如如果大,说明学习率太大。

# assume parameter vector W and its gradient vector dW
param_scale = np.linalg.norm(W.ravel())
update = -learning_rate*dW # simple SGD update
update_scale = np.linalg.norm(update.ravel())
W += update # the actual update
print update_scale / param_scale # want ~1e-3

4. 层激活数及梯度分布情况

初始化问题,梯度消失或者nan值,解决办法:得到网络中所有层的激活数据及梯度分布,观测数据结果, 我们看一下下面的图就知道了。

对于图像数据,我们可视化第一层特征。

3

左边:特征乱七八糟,网络应该是没有收敛,学习率不当,正则化权重太低
右边:特征明显,种类多,好图。

5. 参数更新

当我们使用BP计算梯度以后,梯度就可以更新了,那么如何更新呢?

1. 随机梯度下降

  • 一般更新沿着负梯度调参

  • x += - learning_rate * dx 比如 : α \alpha = 0.05

  • 动量更新新方法,在深度学习中总是能快速收敛
    从物理角度讲,想象一座高山,高度势能是U=mgh,so: U h U\propto h

质点所受的力与梯度的能量 F = U (F=-\nabla U) 有关,**其实就是保守力就等于势能的负梯度!!!**物理专业的骄傲哈哈、

而又因为: F = m a F = ma 所以有:

# 动量法
v = mu * v - learning_rate * dx # 融合速度
x += v # 融合位置

引入参数 muv , 前者就是动量咯,最后结论:mu = [0.5,0.9,0.95,0.99]
要注意mu不是恒定不变的,一般是从0.5慢慢提升至0.99

  • Nesterov动量 理论上更有比较好的支持,实践下比上述动量还好。

当向量位于某个位置x时,mu * v 会轻微改变参数向量,因此计算梯度时,应该计算x + mu * v就更有意义???

4

动量将会把我们带到绿色箭头的位置,那么应该再向前看一些。

就知道你听的一头雾水

x_ahead = x + mu * v
# 计算dx_ahead(x_ahead处的梯度)
v = mu * v - learning_rate * dx_ahead
x += v

实际中改写x_ahead = x + mu * v就懂了。

x += -mu * v_prev + (1 + mu) * v && v_prev = v
x += v
v_prev = v # back this up
v = mu * v - learning_rate * dx # velocity update stays the same
x += -mu * v_prev + (1 + mu) * v # position update changes form

这是Yoshua Bengio的文献

2. 学习率退化

  • **随epoch衰减:**一般是每5个epoch减少一半,看验证集的错误率停止下降,就乘常数,降低学习率。

  • 指数衰减: α = α 0 e k t \alpha=\alpha_0e^{-kt}

  • 1/t衰减: α = α 0 / ( 1 + k t ) \alpha=\alpha_0/(1+kt)

α 0 \alpha_0 ,k:超参数,t:迭代次数
随步数衰减的随机失活(dropout)更受欢迎

3. 二阶法

还有最优化方法是基于牛顿法的:

x x [ H f ( x ) ] 1 f ( x ) \displaystyle x\leftarrow x-[Hf(x)]^{-1}\nabla f(x)

其中 H f ( x ) Hf(x) 是Hessian矩阵, 这里是没有学习率这个参数或者说概念的, 这个方法啊,少用。

4. 逐层层自适应学习率:Adagrad、RMSprop

Adagrad:一个由Duchi等人提出适应学习率算法

跟踪每个参数的平方和, 必须加平方根

接收到高梯度值的权重更新的效果被减弱,而接收到低梯度值的权重的更新效果将会增强

eps防止出现0的情况
缺点:学习率太激进,容易过早停止学习。

RMSprop 高效,且没被发表的适应性学习率法,Hinton coursera

就是去除了Adagrad的缺点,慢慢降低了学习率。

cache =  decay_rate * cache + (1 - decay_rate) * dx**2
x += - learning_rate * dx / (np.sqrt(cache) + eps)

超参数decay_rate,多用[0.9,0.99,0.999]

# Assume the gradient dx and parameter vector x
cache += dx**2
x += - learning_rate * dx / (np.sqrt(cache) + eps)

Adam RMSProp的动量版

m = beta1*m + (1-beta1)*dx
v = beta2*v + (1-beta2)*(dx**2)
x += - learning_rate * m / (np.sqrt(v) + eps)

论文中推荐的参数值eps=1e-8, beta1=0.9, beta2=0.999

5d

6d

RMSProp更新, 方法中的分母项, 所以动量类的可以继续前进

图片版权:Alec Radford

6. 超参数优化

总结一下:

  • 初始化学习率
  • 学习率衰减
  • 正则化强度

交叉验证最好使用一个验证集
超参数的范围:learning_rate = 10 ** uniform(-6, 1) dropout=uniform(0,1)

随机选择好于网络搜索

7

大范围搜索——————>>>贝叶斯超参数优化

7. 评估(集成模型

提升准确率的办法: 训练独立几个模型,然后平均结果
模型设置多个记录位点: 记录网络值。
跑参数平均值:也可以提上几个百分点,对网络的权重进行备份。

8. 总结

训练网络:

  1. 小批量梯度检查
  2. 小批量期间得到100%准确率
  3. 跟踪损失准确率以及第一层权重可视化
  4. 权重更新方法:SGD+Nesterov动量法,Adam法
  5. 学习率衰减
  6. 随机搜索超参数
  7. 集成模型(比赛得奖的几乎都用了集成)

9. 附录拓展

Leon Bottou:《SGD要点和技巧》。

Yann LeCun:《Efficient BackProp》。

Yoshua Bengio:《Practical Recommendations for Gradient-Based Training of Deep Architectures》

( y X w ) T ( y X w ) (y-Xw)^T(y-Xw)
= ( y T w T X T ) ( y X w ) = (y^T-w^TX^T)(y-Xw)
= y T y + y T ( w T X T ) y + w T X T ( X w ) = y^Ty + y^T - (w^TX^T)y + w^TX^T(Xw)
= y T y y T ( X w ) ( X w ) T y + w T ( X T X ) w = y^Ty - y^T(Xw) - (Xw)^Ty + w^T(X^TX)w
= y T y 2 w T ( X T y ) + w T ( X T X ) w = y^Ty - 2w^T(X^Ty) + w^T(X^TX)w

A T B = B T A A^TB = B^TA ?

猜你喜欢

转载自blog.csdn.net/sinat_36458870/article/details/82824556