【教程】估算一个最佳学习速率,以更好地训练深度神经网络

对于训练深度神经网络来说,学习速率是调优的最重要的超参数之一。在这篇文章中,我将描述一个简单而有力的方法来找到一个合理的学习速率。这种方法是我从Fast AI网站的深度学习课程中了解到的。

学习速率如何影响训练

深度学习模型通常由随机梯度下降优化器训练。许多随机梯度下降的变体,如Adam, RMSProp, Adagrad等等,都可以让你设置学习速率。学习速率能够告诉优化器,在一个小批次处理的梯度方向移动权重的距离有多远。

如果学习速率很低,那么训练就更可靠,但是优化需要花费大量的时间,因为最小的损失函数的步长是很小的。

如果学习速率很高,那么训练可能不会收敛甚至是扩散的。权重的变化会非常大,以至于优化器会超过最小值,并使损失变得更严重。

梯度下降与小(上)和大(下)学习速率。来源:Coursera的机器学习课程

训练应该从一个相对较大的学习速率开始,因为在开始的时候,随机的权重远远不是最优的,然后在训练过程中学习速率会下降,从而允许更优的权重更新。

有多种方法可以为学习速率选择一个好的起点。一个简单的方法是尝试一些不同的值,看看哪一个值能给你最好的损失,同时又不牺牲训练的速度。我们可能从一个很大的值开始,比如0.1,然后尝试以指数方式降低的值,如0.01, 0.001等等。当我们开始以一个大的学习速度进行训练时,损失并没有得到改善,甚至可能在我们进行最初的几次训练的时候就会增长。当以较小的学习速率进行训练时,在某些时候,损失函数的值在开始的几次迭代中开始减少。这个学习速率是我们可以使用的最大值,任何更高的值都不会让训练收敛。即使这个值也太高了:它不能足够好地为多个epoch进行训练,因为随着时间的推移,网络将需要更优的更新。因此,一个合理的开始训练的学习速率可能会降低1-2个数量级。

更聪明的方法 在2015年的“训练神经网络的循环学习速率”论文的3.3章节,Leslie N.Smith描述了一种强大的技术,为神经网络选择一系列的学习速率。

关键是要训练一个从低学习速率开始的网络,每一批次都要以指数级的速度增加学习速率。

论文地址:https://arxiv.org/abs/1506.01186

每个小批次处理后,学习速率提高

记录每个批次的学习速率和训练损失。然后,把损失和学习速率画出来。通常情况下是这样的:

开始时的损失减少,然后在训练过程中开始扩散

首先,低学习速率的损失会慢慢提高,然后训练会加速,直到学习速率变大,并且损失增加:训练过程会扩散。

我们需要在图上选择一个点,以最快的速度减少损失。在本例中,当学习速率在0.001到0.01之间时,损失函数就会迅速下降。

另一种观察这些数字的方法是计算损失的变化率(损失函数关于迭代次数的导数),然后绘制y轴上的变化率和x轴上的学习速率。

损失变化率

它看起来波动有些大,让我们用简单的移动平均数的方法来平滑它。

损失的变化率,简单的移动平均数

这样看起来更好。在这张图上,我们需要找到最小值。它接近于学习速率=0.01。

实现 美国USF数据研究所的杰里米霍华德和他的团队开发了fast.ai。fast.ai是一个在PyTorch之上的一个高级抽象的深度学习库,它是一种易于使用又强大的工具集,用于训练艺术深度学习模型。杰里米在最新版本的深度学习课程中使用了这个库。该库提供了一个学习速率查找器的实现。你只需要几行代码就可以绘制对你的模型的学习率造成的损失。

fast.ai库:https://github.com/fastai/fastai

代码:

# learn is an instance of Learner class or one of derived classes like ConvLearner
learn.lr_find()
learn.sched.plot_lr()

这个库没有代码来绘制损失函数的变化率,但是计算它是很简单的:

def plot_loss_change(sched, sma=1, n_skip=20, y_lim=(-0.01,0.01)):
 """
 Plots rate of change of the loss function.
 Parameters:
 sched - learning rate scheduler, an instance of LR_Finder class.
 sma - number of batches for simple moving average to smooth out the curve.
 n_skip - number of batches to skip on the left.
 y_lim - limits for the y axis.
 """
 derivatives = [0] * (sma + 1)
 for i in range(1 + sma, len(learn.sched.lrs)):
 derivative = (learn.sched.losses[i] - learn.sched.losses[i - sma]) / sma
 derivatives.append(derivative)
 
 plt.ylabel("d/loss")
 plt.xlabel("learning rate (log scale)")
 plt.plot(learn.sched.lrs[n_skip:], derivatives[n_skip:])
 plt.xscale('log')
 plt.ylim(y_lim)

plot_loss_change(learn.sched, sma=20)

请注意,在训练前选择一次学习速率是不够的。最佳学习速率在训练时下降。你可以周期性地重新运行相同的学习速率搜索过程,以在训练过程的后期找到学习速率。

使用其他库实现该方法 我还没有准备好使用像Keras这样的其他库的学习速率的搜索方法。只要多次运行训练,每次只训练一个小批次就可以了。在每次小批次训练后,通过将它乘以一个小的常数增加学习速率。当损失比先前观察到的最好的值(例如,当当前损失>最好损失乘以4)高很多时,停止该程序。

选择一个学习速率的起始值只是问题的一部分。另一件要优化的事情是学习进度:如何在训练中改变学习速率。传统观点认为,随着时间的推移,学习速率会逐渐下降,有多种方法来设置:当损失停止改进、指数学习速率衰减,等等情况发生时,学习速率就会降低。

Fast AI网站:http://www.fast.ai/

原文发布于微信公众号 - ATYUN订阅号(atyun_com)

原文发表时间:2017-12-06

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏IT派

深度学习参数技巧

1:优化器 机器学习训练的目的在于更新参数,优化目标函数,常见优化器有SGD,Adagrad,Adadelta,Adam,Adamax,Nadam。 其中SGD...

3457
来自专栏AI科技评论

学界丨反向传播算法最全解读,机器学习进阶必看!

AI 科技评论按:如果对人工智能稍有了解的小伙伴们,或多或少都听过反向传播算法这个名词,但实际上BP到底是什么?它有着怎样的魅力与优势?本文发布于 offcon...

4305
来自专栏量子位

不懂卷积神经网络?别怕,看完这几张萌图你就明白了

林鳞 编译自 authomaton.blogspot 量子位 出品 | 公众号 QbitAI 这篇文章用最简明易懂的方式解释了卷积神经网络(CNN)的基本原理,...

3146
来自专栏技术沉淀

逻辑回归(NN Mindset)

1525
来自专栏数值分析与有限元编程

雅可比矩阵(二)

假设在物理坐标系中由曲线y=x,y=3x,xy=1,xy=5围成一个单元区域D。如图所示: ? 四个点的坐标分别为 ? 要求该区域的面积,常规的做法是在默认的...

3074
来自专栏CreateAMind

PPGN即插即用GAN:Ian Goodfellow推荐的最新模型 视频+多图

PPGN 整合了对抗训练、cnn特征匹配、降噪自编码、Langevin采样;在NIPS2016得到了Ian Goodfellow的介绍.

922
来自专栏IT派

手把手教你使用TensorFlow生成对抗样本 | 附源码

摘要: 本文使用TensorFlow一步一步生成对抗样本,步骤明确清晰。首先生成的对抗样本不具有旋转鲁棒性,后面使用同样的方法生成具有鲁棒性的对抗样本,适合初学...

6695
来自专栏人工智能

神经网络与反向传播算法

1、前言 先简单的说下神经网络吧。 简单来说就是模拟大脑的神经元。 前端会有一大批数据输入,例如,前端输入了一张图像的所有像素点。 中间层会有成千上万个网络数据...

1966
来自专栏AI研习社

从编程实现角度学习 Faster R-CNN(附极简实现)

Faster R-CNN 的极简实现: github: simple-faster-rcnn-pytorch(http://t.cn/RHCDoPv ) 本文插...

9345
来自专栏AI研习社

随机加权平均 -- 在深度学习中获得最优结果的新方法

在这篇文章中,我将讨论最近两篇有趣的论文。它们提供了一种简单的方式,通过使用一种巧妙的集成方法提升神经网络的性能。

1512

扫码关注云+社区