复习:
(1)为什么要进行归一化:使分类函数的裕度更大,对数据扰动的容忍程度更大
(2)过拟合的解决方法:添加正则化项
(3)参数调整规则:一般最先调整学习率(最敏感),调整到比最优值略小
更有效的优化:
(1)随机梯度下降的问题:
a.一些函数的梯度方向并不是指向其最小值的,此时使用梯度下降就会出现“之”字型曲线 。e.g.椭圆形等高线
b.会卡在损失函数的局部极小或鞍点上。
ps:一维上,局部极小较明显,鞍点显得没那么重要;但是高维时,局部极小出现的很少,但是鞍点影响的更频繁
(2)更好的优化算法——动量
一般ρ=0.9/0.99,让其有了惯性~
#Nesterov Momentum
dx = compute_gradient(x)
old_v = v
v = rho * v - learning_rate * dx
x += -rho * old_v + (1 + rho) * v
先沿着速度方向前进,得到对应点的梯度,然后返回起始点,利用刚才求得的梯度再计算,进行真正的前进
初始化:最初速度设置为0
ps:带动量的情况下很容易就会越过极小值点——缺点
(3)AdaGrad
计算每一步梯度的平方,并累加求和,并让参数更新的时候除以这个平方和的平方根。
grad_squared = 0
while True:
dx = compute_gradient(x)
grad_squared += dx * dx
x -= learning_rate * dx / (np.sqrt(grad_squared) + 1e-7) #添加1e-7防止除0
当多维情况下,各个方向梯度大小不一致,通过AdaGrad来平衡梯度前进的方向,但是随着迭代次数增加,步长会越来越小,也会很容易被局部极小困住
(4)RMSProp
grad_squared = 0
while True:
dx = compute_gradient(X)
grad_squared = decay_rate * grad_squared + (1 - decay_rate) * dx * dx
x -= learning_rate * dx / (np.sqrt(grad_squared) + 1e-7)
衰减率通常为0.9/0.99, 用以解决随着迭代次数增加而使步长减小的问题
(5)Adam(almost):Momentum 和 RMSProp的结合:
first_moment = 0 #第一动量
second_moment = 0 #第二动量
while True:
dx = compute_gradient(x)
first_moment = beta1 * first_moment +(1 - beta1) * dx #Momentum
second_moment = beta2 * second_moment + (1 - beta2) * dx * dx #RMSProp
x -= learning_rate * first_moment / (np.sqrt(second_moment) + 1e-7))
缺点:最初时候第一、二动量都很小,有可能会使初始的步长变得很大
Adam(full)
first_moment = 0 #第一动量
second_moment = 0 #第二动量
for t in range(num_iterations):
dx = compute_gradient(x)
first_moment = beta1 * first_moment +(1 - beta1) * dx #Momentum
second_moment = beta2 * second_moment + (1 - beta2) * dx * dx #RMSProp
first_unbias = first_moment / (1 - beta1 ** t) #Bias correction
second_unbias = second_moment/ (1 - beta2 ** t)
x -= learning_rate * first_unbias / (np.sqrt(second_unbias) + 1e-7))
解决步长问题:当t很小的时候,对应初始状态,第一、二动量就会除以一个很大的数;随着t的增大,unbias 逐渐趋于moment
Adam是一个相当棒的算法,初值可以考虑设置为:beta1 = 0.9, beta2 = 0.999, learning_rate = 1e-3 或 5e-4
(6)学习率衰减:
最初设置个较大的学习率,然后随着迭代次数增加而不断衰减
ps:一些论文中损失函数的曲线会出现几次骤降,可能是由于在拐点处发生了学习率的变化所导致的
pss:学习率衰减通常用于SGD,AdaGrad,但少用于Adam
psss:学习率衰减是一个二阶的超参数,最初往往不适用,而是找到一个不错的学习率,再尝试使用学习率衰减
(7)二阶拟合
之前的梯度下降仅仅用了泰勒的一阶近似,但也可以使用二阶近似(牛顿法)。但是参数量巨大,不太现实
(8)集成学习:训练多个不同模型,结果取平均,大概会提升2%。也不一定需要独立的训练这些模型
(9)正则化:防止过拟合
review:L1, L2正则化
dropout:在进行前向传播时,随机让每一层的神经元置零(实际为激活函数置零,一般在全连接层,有时也用在卷积层)
测试时,不再置零,而是直接将输出乘以置零的概率
一直提升速度的方法:在测试时不再乘以概率,而是在训练的时候,将输出除以置零的概率
原理:训练时给网络加入随机量,通过扰乱网络的方法以防止其过拟合
ps:BN和dropout是相似的,有时不必同时使用
(10)数据增强:给数据中引入随机性:水平翻转,随机裁剪(中心,四个角),色彩抖动(color jitter)(使用较少)
(11)随机深度:随机丢弃深度网络的部分层,但测试时的使用整个层
ps:一般只使用batch normalization,如果发现过拟合之后再加入dropout等其他方法
(12)迁移学习 transfer learning:先找到成熟的网络,在一个较大的数据集上训练(ImageNet), 然后修改输入和输出的全连接层。冻结中间层。
ps:如果是很小的数据集,输入部分只需要修改第一个全连接层即可,其余冻结;而如果是中等数据集,则输入部分可能要多改几层,或者是训练整个网络,但是调低学习率。
pss:目前大部分网络使用到CNN时都是先在ImageNet上预训练好,然后再对网络进行fine tune