本文为雷锋字幕组编译的技术博客,原标题8 Deep Learning Best Practices I Learned About in 2017,作者为Brian Muhia。
翻译 | 付腾 林立宏 整理 | 凡江
在2017年我感到最开心的事情就是,我更多地通过实践来参与最新AI的发展,学到了很多的数学知识。这很有趣,但是却没有接触什么实践项目。因此,也没有什么东西能体现我付出的努力。
为了弥补这点,在四月份,我在 AI Grant 网站上申请了一个AI项目,目标是用 FastText 的skip-gram模型来为肯尼亚语建模。我获得了初选的决赛资格,但是,却没有笑到最后。
然后,在九月份,我申请了一个国际奖学金,学习了一个由 fast.ai 的Jeremy Howard开讲的课程:Practical Deep Learning for Coder 《程序员的深度学习实践》 第一部(目前该课程已经完结)。该课程会在一月份的头两个星期左右来到MOOC,并且对公众开放哦。在七周的学习中,我学习到了八种基本技术用来构建:
1. 在已经训练好的模型上构建世界级的图像分类器。
2. 通过对数据进行调查,来构建语言模型,进而建立情感分析工具。
3. 如何在结构化的数据集上进行深度学习。
4. 如何通过协同筛选和深度学习来构建推荐引擎。
所有这些都是在一个更够提供非常高生产效率的开发界面:Jupyter Notebook 来实现的,它目前是由 fastai 的深度学习库支持的,而这个库本身又是由 PyTorch 所支持的。
来看看这里的八个技术。在每个具体案例下,我会结合fast.ai的代码片段来大概的列出其基本的原理,并且在括弧中指出哪些技术是比较适用的(这点很有用,无论你是用深度学习来做图像识别或者分类,NLP,给结构化数据建模或者协同筛选),又或者对更加具体的,某些可以应用深度学习来学习的特殊类型数据进行讨论。在这个课程中,图像识别的课程使用Kaggle challenges的案例来做实践的 1. 是猫还是狗?狗品种的鉴别。 2. 地球数据,如何从太空中看懂亚马逊雨林。
这是互联网时代,我要自我挑战一下。克隆一下 狗vs猫 的形式,不过换成 蜘蛛vs蝎子。嗯,蜘蛛vs蝎子。我从Google图片 上搜索了关键词“蜘蛛”和“沙漠蝎”,然后抓取下载了大约1500张左右的图片。我当然是用程序来自动抓取。我可不想自动的成为资深的蜘蛛学专家,然后右键点点点。。。
我先是对数据进行清理,去除那些非jpg格式的图片,非图片文件和没有扩展名的图片。当我完成这些杂项清理之后,我有了大约815张可用图片。每个类 [蜘蛛,蝎子],有290张图片作为训练集,然后118张蜘蛛和117张蝎子用来做测试/验证集。令我惊讶的是(对我而言,尤其是我看到结果后),这个模型很成功!这个模型达到了95%的准确率。
from fastai.imports import *
from fastai.transforms import *
from fastai.conv_learner import *
from fastai.model import *
from fastai.dataset import *
from fastai.sgdr import *
from fastai.plots import *
sz=224 # image size
# architecture, from https://github.com/facebookresearch/ResNeXt
arch=resnext50
# batch size
bs=64
PATH = 'data/spiderscorpions/'
# Enable data augmentation, and precompute=True
# transforms_side_on flips the image along the vertical axis
# max_zoom: 1.1 makes images up to 10% larger
tfms = tfms_from_model(arch, sz, aug_tfms=transforms_side_on, max_zoom=1.1)
data=ImageClassifierData.from_paths(PATH,tfms=tfms)
learn = ConvLearner.pretrained(arch, data, precompute=True)
# Use lr_find() to find highest learning rate where loss is still clearly improving
learn.lr_find()
# check the plot to find the learning rate where the losss is still improving
learn.sched.plot()
# assuming the optimal learning rate is 0.01, train for 3 epochs
learn.fit(0.01, 3)
# train last layer with data augmentation (i.e. precompute=False) for 2-3 epochs with cycle_len=1
learn.precompute=False
learn.fit(1e-2, 3, cycle_len=1)
# unfreeze all layers, thus opening up resnext50's original ImageNet weights for the
# features in the two spider and scorpion classes
learn.unfreeze()
lr = 0.01
# fastai groups the layers in all of the pre-packaged pretrained convolutional networks into three groups
# retrain the three layer groups in resnext50 using these learning rates for each group
# We set earlier layers to 3x-10x lower learning rate than next higher layer
lrs = np.array([lr/9, lr/3, lr])
learn.fit(lrs, 3)
# Use lr_find() again
learn.lr_find()
learn.sched.plot()
learn.fit(1e-2, 3, cycle_len=1, cycle_mult=2)
log_preds,y = learn.TTA()
preds = np.mean(np.exp(log_preds),0)
accuracy(log_preds, y)
1.通过微调VGG-16和ResNext50来学习 (计算机视觉和图像分类)
对于图像分类的工作,一个神经网络的架构已经在多个挑战中测试过,可以得到非常好的结果了。针对特定的问题,你可以通过微调模型从而得到非常具有里程碑的结果。残留网络 ResNext50 就是一个例子,一个50层的卷积神经网络。它接受了1000种ImageNet挑战的训练, 而且因为它表现得非常好,所以从图像数据中提取的特征足以被重用 。要让它在我的问题上使用,我需要做的是替换最后一层神经网络,输出一个 1000维的向量作为ImangeNet的预测,并带有一层网络输出一个2维向量。在上面代码片段中,这两个输出被特定放在称为PATH 的文件夹。对于蜘蛛VS蝎子的挑战,有以下的内容:
注意到 train 文件夹的两个内容都是文件夹,每一个都包含了290两张图片。
一个微调流程示意图展示如下,重新训练最后一层10维的神经网络。
图片从这里获取
2.周期学习率(通常适用)
学习率可能是用于训练调整深度神经网络最重要的超参数。通常在非自适应环境中完成的(即不使用Adam,AdaDelta 或其变体),而是由DL从业者/研究者同时运行多个实验,每个实验在学习速率之间具有小的差异。如果你有一个非常大的数据集,这需要花费非常多的时间。如果你对用随机矩阵建立直觉的方法缺乏经验,很容易出错。然而,在2015,美国海军研究实验室的 Leslie N. Smith ,找到了一种自动搜索最佳学习率的方法,从一个非常小的值开始,通过网络运行几个小批量,调整学习率,同时跟踪损失的变化,直到损失开始下降。在fast.ai上面两篇博客解释了周期学习率的方法,分别在这里和这里。
在fast.ai,你可以利用通过在学习者对象上运行 lr_find() 来利用学习速率退火的优势, 运行 sched.plot()以确定与最佳学习率一致的点 ,截图如下:
0.1 seems like a good learning rate
从周期性学习率论文摘录中显示,它表现更好, 达到最高的准确度,比学习速率指数衰减的方法快两倍以上。
图一:Smith (2017) “使用周学习率训练神经网络”
3.带重新启动的随机梯度下降(通常适用)
Fig. 2: SGD vs. snapshot ensembles (Huang et al., 2017)
另外一个方法来加速随机梯度下降,包含了逐渐降低学习率的训练过程。 这有助于注意到学习速度的变化与损失的改善是否一致 。当你接近最优的权重,你要采取更小的步骤,因为如果你采取大步骤,你可能会跳过错误表面的最佳区域。如果学习率和损失之间的关系是不稳定的,比如学习率一个小的改变,就会导致损失变化很大,那我们就处在一个不稳定的区域,就像上图所示。那么此时策略变成周期性地提高学习率。这里的“周期”是指提高学习率的次数。这是周期学习率的流程。在fast.ai,将参数 cycle_len 和 cycle_mult 传入到 learner.fit,在上图中,学习率被重置了3次。在使用正常的学习速率时间表时,通常需要更长的时间才能找到最佳的损失,开发人员等待所有的训练周期完成后,再手动尝试不同的学习速率。
4.数据增加(计算机视觉和图像分类 - 现在)
数据增加是一个在你已有的训练和测试数据集中简单的方法。比如图片,这取决于你手头的学习问题,并取决于数据集中图像的对称数量。比如说蜘蛛VS蝎子挑战,在数据集中的很多图片可以垂直翻转,仍然显示动物,没有奇怪的扭曲,这被称为:transforms_side_on. 比如:
5.测试时间增加 ( 计算机视觉和图像分类 - 现在 )
我们在推理的时候使用数据增加(或者时间,这由此而得名)。在推理时间时,你只是在做预测。你可以用测试集中的单个图像来完成,但是如果在被访问的测试集中随机生成每个图像的几个增量,这个过程会变得更加健壮。在fast.ai中,每个测试图像的4个随机增量用于预测,并将这些预测的平均值用作该图像的预测。
6.用预训练的循环神经网络替换词向量
一种获得世界级的情绪分析框架的方法, 不使用词向量,而是通过使用整个你想要训练的数据集进行分析,从中建立一个深层循环的神经网络语言模型。当模型具有高精度时,保存模型的编码器,并使用从编码器获得的嵌入来构建情感分析模型。这比从词向量获得的嵌入矩阵更好,因为RNN可以比词向量更好地跟踪更大范围的依赖性。
7.通过时间反向传播 (BPTT) (NLP)
深层递归神经网络中的隐藏状态, 如果在反向传播一些时间后它没有被重置,可能会增长到难以处理的大小 。比如说,在字符级RNN上,如果你有一百万个字符,那么你也有一百万个隐藏的状态向量,每个都有自己的历史状态。为了调整神经网络的梯度,我们需要对每个字符每批执行一百万条链规则的计算。这会消耗太多的内存。因此,为了降低内存,我们设置了一个最大字符数量来反向传播。由于循环神经网络中的每个循环被称为时间步长,所以限制反向传播保持隐藏状态历史层数的任务被称为时间反向传播。这个数字的值决定了模型计算的时间和内存要求,但它提高了模型处理长句或行动序列的能力。
8.实体嵌入分类变量 ( 结构数据和NLP )
当在结构化的数据集进行深度学习时, 它有助于区分包含连续数据的列,比如说在线商店的价格信息,列中包含了,比如日期和生产地址的连续数据。然后,可以将这些分类列,通过热编码过程转换为指向神经网络的完全连接的嵌入层的查找表。你的神经网络因此获得机会学习这些分类好的变量/列,如果忽略了这些列的分类性质,那么这个问题就会被忽略。它可以学习周期性事件,比如在很多年的数据集上,公众假期之前和之后,一周中的哪一天有最多的事情。这样做的最终结果是在预测产品最优定价和协同筛选的一个非常有效的方法。这应该是所有拥有表格数据公司的标准数据分析和预测方法。所有的公司都应该使用这个。
这个方法在 Rossmann Store Sales Kaggle 比赛中 Guo 和Berkhahn应用了, 即使他们只用最少的特征进行深度学习,也能获得第三名。 他们在本文( this paper )概述了他们的方法。
Guo, Berkhahn (2016)
最后
AI中深度学习的分支变得越来越容易学习,库也变得越来越好。感觉研究人员和从业人员就像爬山一样,步伐越来越大,通过艰苦的工作编译大型数据集和性能更好的GPU,公开发表了一套承诺颠覆人类历史进程的工具。在我看来,AI最大的潜力在于教育和医学,尤其是复兴生物技术。
在我们使用深度学习来创造真正的人工智能之前,用正确的策略,在洞察力、动力和全球协调上,我们会变得更聪明、更富有,并且应该期望在本世纪末,能因为这些工具而活得更长寿、更健康。
博客原址 https://hackernoon.com/8-deep-learning-best-practices-i-learned-about-in-2017-700f32409512
更多文章,关注雷锋网
添加雷锋字幕组微信号(leiphonefansub)为好友
备注「我要加入」,To be an AI Volunteer !
雷锋网雷锋网
发表评论 取消回复