【深度学习】从fast.ai学到的十大技巧

 

 

那些允许新手在短短几周内实施世界级算法的秘诀是什么呢?在GPU驱动的唤醒中留下经验丰富的深度学习从业者?请允许我用十个简单的步骤告诉你。

如果您已经在练习深度学习并希望快速了解fast.ai在课程中使用的强大技术,请继续阅读。如果你已经完成了fast.ai并想要回顾一下你应该学到的东西,请继续阅读。如果你正在调查研究深度学习的想法,请继续阅读,并希望看到该领域如何发展以及fast.ai可以为初学者提供什么。

现在,在我们开始之前,您应该知道您需要访问GPU才能有效地运行fast.ai内容。对于我的fast.ai项目,我一直在使用FloydHub。经过对其他基于云的解决方案的大量实验和研究,我发现FloydHub是在云GPU上训练深度学习模型的最佳和最简单的方法。我喜欢能够在FloydHub 上的项目中轻松跟踪我的实验,使得可视化和过滤哪些模型的性能最佳。他们还拥有最简单的解决方案来管理(并自动版本化)您的数据集,您将学习在任何DL项目中将会非常有价值。

好的,让我们开始吧。

 

1.使用Fast.ai库

from fast.ai import *

fast.ai库不仅是让新手快速实施深度学习的工具包,而且是当前最佳实践的强大而便捷的源。每当fast.ai团队(以及他们的AI研究人员和合作者网络)发现一篇特别有趣的论文时,他们就会在各种数据集上进行测试,并找出如何调整它的方法。如果它们成功,它将在库中实现,并且用户可以快速访问该技术。

结果是一个功能强大的工具箱,包括快速访问最佳实践,例如随机梯度下降与重启,差分学习率和测试时间增加(更不用说更多)。

下面将介绍这些技术中的每一种,我们将展示如何使用fast.ai库快速实现它们。该库是基于PyTorch构建的,您可以非常流畅地使用它们。 要开始使用FloydHub上的库,请查看他们的2分钟安装。

 

2.不要使用一个学习率,使用多个

差异学习率意味着在训练期间更高层的变化比更深层更多。在预先存在的架构之上构建深度学习模型是一种经过验证的方法,可以在计算机视觉任务中产生更好的结果。
大多数这些架构(即Resnet,VGG,初始......)都是在ImageNet上进行培训的,并且根据数据与ImageNet上图像的相似性,这些权重需要或多或少地大幅改变。在修改这些权重时,模型的最后几层通常需要进行最大的变化,而已经训练有素且检测基本特征(例如边缘和轮廓)的更深层次需要更少。

首先,要使用快速ai库获得预先训练的模型,请使用以下代码:

from fastai.conv_learner import *

# import library for creating learning object for convolutional #networks
model = VVG16()

# assign model to resnet, vgg, or even your own custom model
PATH = './folder_containing_images' 
data = ImageClassifierData.from_paths(PATH)

# create fast ai data object, in this method we use from_paths where 
# inside PATH each image class is separated into different folders

learn = ConvLearner.pretrained(model, data, precompute=True)

# create a learn object to quickly utilise state of the art
# techniques from the fast ai library

 

通过现在创建的学习对象,我们可以解决仅通过快速冻结第一层来精细调整最后一层的问题:

learn.freeze()

# freeze layers up to the last one, so weights will not be updated.

learning_rate = 0.1
learn.fit(learning_rate, epochs=3)

# train only the last layer for a few epochs

 

一旦最后一层产生了良好的结果,我们实施差异学习率以改变较低层。较低层希望改变较少,因此最好将每个学习速率设置为比最后一个低10倍:

learn.unfreeze()

# set requires_grads to be True for all layers, so they can be updated

learning_rate = [0.001, 0.01, 0.1]
# learning rate is set so that deepest third of layers have a rate of 0.001, # middle layers have a rate of 0.01, and final layers 0.1.

learn.fit(learning_rate, epochs=3)
# train model for three epoch with using differential learning rates

 

3.如何找到合适的学习率

学习率是训练神经网络最重要的超参数,但直到最近才决定它的价值令人难以置信的hacky。莱斯利史密斯可能在其关于周期性学习率的论文中偶然发现了答案; 一个相对未知的发现,直到它被fast.ai课程推广。

在这种方法中,我们进行试运行并使用较低的学习率训练神经网络,但每批次都会以指数方式增加神经网络。这可以使用以下代码完成:

learn.lr_find()
# run on learn object where learning rate is increased  exponentially

learn.sched.plot_lr()
# plot graph of learning rate against iterations

 

每次迭代,学习率都呈指数增长

同时,记录学习率的每个值的损失。然后我们根据学习率绘制损失:

learn.sched.plot()
# plots the loss against the learning rate

找出损失仍在减少的地方,但尚未达到稳定水平。

通过找到学习率最高且损失仍在下降的值来确定最佳学习率,在上述情况下,该值将为0.01。

 

4.余弦退火

随着每批随机梯度下降(SGD),您的网络应该越来越接近损失的全局最小值。因为它越来越接近这个最小值,因此学习率应该变得更小以使你的算法不会超调,而是尽可能接近这一点。余弦退火通过降低余弦函数后的学习率来解决这个问题,如下图所示。

随着我们增加x,我们看到余弦(x)在这个波浪形状之后减少。

 

看看上面的图,我们看到随着我们增加x,余弦值首先缓慢下降,然后更快,然后再稍微慢一些。这种降低模式与学习速率很好地协作,以计算有效的方式产生很好的结果。

learn.fit(0.1, 1)
# Calling learn fit automatically takes advantage of cosine annealing

该技术在使用时由快速ai库自动实现learn.fit()。上面的代码将使我们的学习率在整个时期内降低,如下图所示。

学习率在一个需要200次迭代的时期内降低

但是,我们可以比这更进一步,并引入重启。

 

5.重启后的随机梯度下降

在训练期间,梯度下降可能会陷入局部最小值而不是全局最小值。

梯度下降可能会陷入局部最小值

 

通过突然提高学习率,梯度下降可以“跳出”局部最小值并找到通向全局最小值的方式。这样做被称为带重启的随机梯度下降(SGDR),这一想法在Loshchilov和Hutter的论文中表现得非常有效。

快速ai库也会自动为您处理SGDR。在呼叫时learn.fit(learning_rate, epochs),学习速率在每个纪元的开始处重置为您作为参数输入的原始值,然后在余弦退火中如上所述在时期上再次减小。

在每个时期之后,学习率恢复到其原始值。

 

每次学习率下降到最小点(上图中每100次迭代),我们称之为循环。

cycle_len = 1
# decide how many epochs it takes for the learning rate to fall to
# its minimum point. In this case, 1 epoch

cycle_mult=2
# at the end of each cycle, multiply the cycle_len value by 2

learn.fit(0.1, 3, cycle_len=2, cycle_mult=2)
# in this case there will be three restarts. The first time with
# cycle_len of 1, so it will take 1 epoch to complete the cycle.
# cycle_mult=2 so the next cycle with have a length of two epochs, 
# and the next four.

 

每个周期需要两倍于上一周期完成的时期

使用这些参数以及使用差异学习速率是允许快速ai用户在图像分类问题上表现良好的关键技术。

Cycle_multcycle_len进行了讨论这里的fast.ai论坛,而上述关于学习率可以发现,概念更全面地解释这个快速AI教训和这个博客帖子。

 

6. Anthropomorphise你的激活功能

Softmax喜欢挑选一件事。Sigmoid想知道你在-1和1之间的位置,超出这些值并不关心你增加了多少。Relu是一名俱乐部保镖,他不会让负数通过门。

以这种方式处理激活函数似乎很愚蠢,但给它们一个字符可以确保不将它们用于错误的任务。正如杰里米·霍华德所指出的那样,即使是学术论文也经常使用softmax进行多类分类,而且在我研究DL的短暂时间里,我也已经看到它在博客和论文中使用不当。

 

7.转学在NLP中非常有效

正如使用预先训练的模型已被证明在计算机视觉中非常有效一样,越来越清楚的是,自然语言处理(NLP)模型可以从这样做中受益。

在fast.ai 的第4课中,杰里米·霍华德建立了一个模型,以确定IMDB评论是使用转移学习是积极的还是消极的。立即观察到这种技术的力量,他所达到的精确度超过了Bradbury等人在论文中提出的所有先前的努力。

预先存在的架构提供最先进的NLP结果。

 

成功的秘诀在于首先训练模型以获得对语言的一些理解,然后再使用这种预先训练的模型作为模型的一部分来分析情绪。

为了创建第一模型,训练递归神经网络(RNN)以预测文本序列中的下一个单词。这称为语言建模。一旦网络经过高度准确的训练,其对每个单词的编码就会传递给用于情感分析的新模型。

在该示例中,我们看到该语言模型与模型集成以执行情感分析,但是该相同方法可以用于从翻译到数据提取的任何NLP任务。

再次,计算机视觉中的上述原则同样适用于此,冻结和使用差异学习率可以产生更好的结果。

NLP这种方法的实现对我来说太详细了,无法在这篇文章中分享代码,但是如果你有兴趣在这里观看课程并在这里访问代码。

 

8.深度学习可以挑战ML处理结构化数据

Fast.ai展示了在结构化数据上快速生成出色结果的技术,无需借助特征工程或应用领域特定知识。

他们的库充分利用了PyTorch的嵌入功能,允许将分类变量快速转换为嵌入矩阵。

他们展示的技术相对简单,只需将分类变量转换为数字,然后为每个值分配嵌入向量:

一周中的每一天都嵌入了四个值。

 

与创建虚拟变量(即执行一个热编码)的传统方法相比,这样做的好处是每天可以用四个数字代替一个数字,因此我们获得更高的维度和更丰富的关系。

本课程中显示的实现(此处的代码)在Rossman Kaggle比赛中获得第三名,只有拥有自己的代码才能创建许多额外功能的领域专家才能击败。

Pinterest也证实了使用深度学习大大减少对特征工程的需求的想法,他们已经说过这种情况,因为他们转向深度学习模型,以更少的工作获得最先进的结果!

 

9.一个游戏获胜的捆绑:建立规模,辍学和TTA

4月30日,fast.ai团队在Imagenet和CIFAR10分类上赢得了DAWNBench竞赛(由斯坦福大学运营)。在Jeremy的胜利写作中,他将自己的成功归功于fast.ai图书馆中的一些额外功能。

其中之一是两年前Geoffrey Hinton在这篇开创性论文中提出的Dropout概念。尽管它最初受欢迎,但在最近的计算机视觉论文中似乎有所忽略。然而,PyTorch使其实现变得异常简单,并且在快速的ai上它比以往更容易。

空格表示由退出功能敲除的激活。

 

Dropout对抗过度拟合,因此在CIFAR10这样一个相对较小的数据集上获胜是非常重要的。 在创建学习对象时,快速ai会自动执行Dropout,但可以使用ps变量进行更改,如下所示:

learn = ConvLearner.pretrained(model, data, ps=0.5, precompute=True)
# creates a dropout of 0.5 (i.e. half the activations) on test dataset. 
# This is automatically turned off for the validation set

有关Dropout的更多信息,请参阅此视频(从4:57开始)。

他们用于解决过度拟合和提高准确性的另一种非常简单有效的方法是对较小的图像尺寸进行训练,然后再增加尺寸并再次训练相同的模型。

# create a data object with images of sz * sz pixels 
def get_data(sz): 
	tmfs = tfms_from_model(model, sz)
	# tells what size images should be, additional transformations such
	# image flips and zooms can easily be added here too
 
	data = ImageClassifierData.from_paths(PATH, tfms=tfms)
	# creates fastai data object of create size

	return data

learn.set_data(get_data(299))
# changes the data in the learn object to be images of size 299
# without changing the model.

learn.fit(0.1, 3)
# train for a few epochs on larger versions of images, avoiding overfitting

可以将精度提高一个或两个的最终技术是测试时间增加(TTA)。这涉及拍摄原始图像的一系列不同版本(例如裁剪不同区域,或更改缩放)并将其传递通过模型。然后计算不同版本的平均输出,并将其作为图像的最终输出分数。它可以通过运行来调用learn.TTA()

preds, target = learn.TTA()

这种技术很有效,因为图像的原始裁剪可能会错过一个重要的特征。为模型提供图片的多个版本并取平均值会降低这种效果。

 

10.创造力是关键

 

fast.ai团队不仅在DAWNBench比赛中赢得最快速度的奖品,而且这些相同的算法也因最便宜的运行而获奖。这里要学到的教训是,创建成功的DL应用程序不仅仅是在这个问题上放弃大量GPU,而应该是创造力,直觉和创新的问题。

本文中讨论的大多数突破(退出,余弦退火,SGD重启,列表继续......)实际上是如此精确的时刻,有人想到以不同的方式解决问题。然后,这些方法的准确性提高了,而不仅仅是通过简单地向少数IBM计算机抛出另外一千个图像来实现。

因为有很多大型犬在硅谷有很多大型GPU,不要以为你不能挑战它们,或者你不能创造出特殊或创新的东西。

事实上,有时你可能会看到约束是一种祝福; 毕竟,必要性是发明之母。

 

原文:https://blog.floydhub.com/ten-techniques-from-fast-ai/

 

 

 

 

你可能感兴趣的:(Machine,Learning,Deep,Learning,机器学习算法理论与实战)