cs231n笔记7—优化/正则化/学习迁移

优化

1 普通更新。
最简单的更新形式是沿着负梯度方向改变参数(因为梯度指向的是上升方向,但是我们通常希望最小化损失函数)。假设有一个参数向量x及其梯度dx,那么最简单的更新的形式是:

# 普通更新
x += - learning_rate * dx

2 动量(Momentum)更新
在这里引入了一个初始化为0的变量v和一个超参数mu。说得不恰当一点,这个变量(mu)在最优化的过程中被看做动量(一般值设为0.9),但其物理意义与摩擦系数更一致。这个变量有效地抑制了速度,降低了系统的动能,不然质点在山底永远不会停下来。通过交叉验证,这个参数通常设为[0.5,0.9,0.95,0.99]中的一个。和学习率随着时间退火(下文有讨论)类似,动量随时间变化的设置有时能略微改善最优化的效果,其中动量在学习过程的后阶段会上升。一个典型的设置是刚开始将动量设为0.5而在后面的多个周期(epoch)中慢慢提升到0.99。

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

3 Nesterov更新

v_prev = v # 存储备份
v = mu * v - learning_rate * dx # 速度更新保持不变
x += -mu * v_prev + (1 + mu) * v # 位置更新变了形式

4 逐参数适应学习率方法
前面讨论的所有方法都是对学习率进行全局地操作,并且对所有的参数都是一样的。学习率调参是很耗费计算资源的过程,所以很多工作投入到发明能够适应性地对学习率调参的方法,甚至是逐个参数适应学习率调参。很多这些方法依然需要其他的超参数设置,但是其观点是这些方法对于更广范围的超参数比原始的学习率方法有更良好的表现。在本小节我们会介绍一些在实践中可能会遇到的常用适应算法
a. AdaGrad

# 假设有梯度和参数向量x
cache += dx**2
x += - learning_rate * dx / (np.sqrt(cache) + eps)

注意,变量cache的尺寸和梯度矩阵的尺寸是一样的,还跟踪了每个参数的梯度的平方和。这个一会儿将用来归一化参数更新步长,归一化是逐元素进行的。注意,接收到高梯度值的权重更新的效果被减弱,而接收到低梯度值的权重的更新效果将会增强。有趣的是平方根的操作非常重要,如果去掉,算法的表现将会糟糕很多。用于平滑的式子eps(一般设为1e-4到1e-8之间)是防止出现除以0的情况
Adagrad的一个缺点是,在深度学习中单调的学习率被证明通常过于激进且过早停止学习。
(随着其更新的总距离增多,其学习速率也随之变慢)
b. RMSprop
是一个非常高效,但没有公开发表的适应性学习率方法。有趣的是,每个使用这个方法的人在他们的论文中都引用自Geoff Hinton的Coursera课程的第六课的第29页PPT。这个方法用一种很简单的方式修改了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]
和Adagrad不同,其更新不会让学习率单调变小。

c. Adam
Adam是最近才提出的一种更新方法,它看起来像是RMSProp的动量版。简化的代码是下面这样:

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

注意这个更新方法看起来真的和RMSProp很像,除了使用的是平滑版的梯度m,而不是用的原始梯度向量dx。论文中推荐的参数值eps=1e-8, beta1=0.9, beta2=0.999。在实际操作中,我们推荐Adam作为默认的算法,一般而言跑起来比RMSProp要好一点。但是也可以试试SGD+Nesterov动量。
完整的Adam更新算法也包含了一个偏置(bias)矫正机制,因为m,v两个矩阵初始为0,在没有完全热身之前存在偏差,需要采取一些补偿措施。
cs231n笔记7—优化/正则化/学习迁移_第1张图片
一般均使用Adam

学习率退火

随步数衰减:每进行几个周期就根据一些因素降低学习率。典型的值是每过5个周期就将学习率减少一半,或者每20个周期减少到之前的0.1。这些数值的设定是严重依赖具体问题和模型的选择的。在实践中可能看见这么一种经验做法:使用一个固定的学习率来进行训练的同时观察验证集错误率,每当验证集错误率停止下降,就乘以一个常数(比如0.5)来降低学习率。
指数衰减。数学公式是[公式],其中[公式]是超参数,[公式]是迭代次数(也可以使用周期作为单位)。
1/t衰减的数学公式是[公式],其中[公式]是超参数,t是迭代次数。

在实践中,我们发现随步数衰减的随机失活(dropout)更受欢迎,因为它使用的超参数(衰减系数和以周期为时间单位的步数)比[公式]更有解释性。最后,如果你有足够的计算资源,可以让衰减更加缓慢一些,让训练时间更长些。

正则化

Regularization: Dropout
在前向计算时,将一些项置为0,项为激活函数
cs231n笔记7—优化/正则化/学习迁移_第2张图片

 p = 0.5  # probability of keeping a unit active, higher = less dropout
 
   def train_step(X)
      """ X contains the data """
      # forward pass for example 3-layer neural network
      H1 = np.maximum(0, np.dot(W1, X) + b1)
      M1 = np.random.rand(*H1.shape) < p  # first dropout mask
      H1 *= M1   # drop
      H2 = np.maximum(0, np.dot(W2, H1) + b2)
      M2 = np.random.rand(*H2.shape) < p  # send dropout mask
      H2 *= M2   # drop 
      out = np.dot(W3,H2) + b3

在测试时,不需要dropout, 直接计算每层的激活值,然后进行scale作为本层最终输出的激活值(乘个p),其代码如下

 def predict(X):
      # ensembled forward pass
      H1 = np.maxmium(0, np.dot(W1,X)+b1) * p  # Note: scale the activations
      H2 = np.maxmium(0, np.dot(W2,H1)+b2) * p # Note: scale the activations
      out = np.dot(W3,H2) + b3

数据增强
平移、旋转、伸缩、裁剪
cs231n笔记7—优化/正则化/学习迁移_第3张图片

Batch Normalization
可以减少或避免使用Dropout

迁移学习

迁移学习(Transfer learning) 顾名思义就是把已训练好的模型参数迁移到新的模型来帮助新模型训练。考虑到大部分数据或任务都是存在相关性的,所以通过迁移学习我们可以将已经学到的模型参数(也可理解为模型学到的知识)通过某种方式来分享给新模型从而加快并优化模型的学习效率不用像大多数网络那样从零学习。


冻结预训练模型的全部卷积层,只训练自己定制的全连接层。

参考:CS231n课程笔记翻译知乎专栏——智能单元

你可能感兴趣的:(深度学习,深度学习,人工智能,机器学习,python,神经网络)