慎用预训练深度学习模型
2019年04月28日 由 sunlei 发表
796502
0
预训练的模型很容易使用,但是您是否忽略了可能影响模型性能的细节?
你有多少次运行以下代码片段:
import torchvision.models as models
inception = models.inception_v3(pretrained=True)
或者
from keras.applications.inception_v3 import InceptionV3
base_model = InceptionV3(weights='imagenet', include_top=False)
似乎使用这些预训练模型已经成为行业最佳实践的新标准。合情合理,为什么不利用一个经过大量数据和计算训练的模型呢?
来看看国外两个网站Reddit和HackerNews上的讨论:
预训模型万岁!
利用预培训的模型有几个重要的好处:
- 合并起来超级简单
- 快速实现稳定(相同甚至更好)的模型性能
- 不需要那么多标记数据
- 从转移学习、预测和特征提取的通用用例
NLP领域的进步也鼓励使用预训练语言模型,如GPT和GPT-2、AllenNLP的ELMo、谷歌的BERT、Sebastian Ruder和Jeremy Howard的ULMFiT。
利用预训练模型的一种常见技术是特征提取,在此过程中检索由预训练模型生成的中间表示,并将这些表示用作新模型的输入。通常假定这些最终完全连接层捕获与解决新任务相关的信息。
每个人都参与其中
每一个主要的框架,如Tensorflow, Keras, PyTorch, MXNet等,都提供了预训练模型,如Inception V3, ResNet, AlexNet等,权重为:
- Keras应用程序
- PyTorch torchvision.models
- Tensorflow官方模型(现在是Tensorflow hub)
- MXNet模型动物园
- ai应用程序
但是,这些基准测试是可重复的吗?
这篇文章的灵感来自麻省理工学院计算机科学博士研究生柯蒂斯·诺斯卡特。他的文章《走向可重复性:Keras和PyTorch的基准测试》提出了几个有趣的观点:
- resnet架构在PyTorch中表现更好,而inception架构在Keras中表现更好。
- 不能复制Keras应用程序上发布的基准测试,即使完全复制示例代码也是如此。事实上,他们报告的准确性(截至2019年2月)通常高于实际的准确性。
- 当部署在服务器上或与其他Keras模型按顺序运行时,一些预训练的Keras模型产生不一致或较低的准确性。
- 使用批处理规范化的Keras模型可能不可靠。对于某些模型,前向传递计算(假定梯度为off)仍然会导致在推断时权重发生变化。
你可能会想:这怎么可能?它们不是同一种模型吗?如果在相同的条件下训练,它们不应该有相同的性能吗?
好吧,你不是一个人这样认为。柯蒂斯的文章也在推特上引发了一些不同的声音。
了解(并信任)这些基准测试非常重要,因为它们允许您根据要使用的框架做出明智的决策,并且通常用作研究和实现的基准。
那么,当你利用这些预训练模型时,需要注意什么呢?
使用预训练模型的注意事项:
1.你的任务相似吗?您的数据有多相似?
您是否期望引用0.945%的验证精度为Keras Xception模型,如果您正在使用您的新x射线数据集,首先,您需要检查您的数据与模型所训练的原始数据集(在本例中为ImageNet)有多相似。您还需要知道特性是从何处(网络的底部、中部或顶部)传输的,因为这将根据任务相似性影响模型性能。
2.你是如何预处理数据的?
您的模型的预处理应该与原始模型的训练相同。几乎所有的torchvision模型都使用相同的预处理值。对于Keras模型,您应该始终为相应的模型级模块使用preprocess_input函数。例如:
# VGG16
keras.applications.vgg16.preprocess_input# InceptionV3
keras.applications.inception_v3.preprocess_input#ResNet50
keras.applications.resnet50.preprocess_input
3.你的后端是什么?
有一些关于黑客新闻网站的传言称,将Keras的后端从Tensorflow更改为CNTK (Microsoft Cognitive toolkit)可以提高性能。由于Keras是一个模型级库,它不处理诸如张量积、卷积等低级操作,所以它依赖于其他张量操作框架,如TensorFlow后端和Theano后端。
Max Woolf提供了一个优秀的基准测试项目,该项目发现CNTK和Tensorflow之间的准确性是相同的,但CNTK在LSTMs和多层感知(MLPs)方面更快,而Tensorflow在CNNs和embeddings方面更快。
伍尔夫的帖子是2017年的,所以如果能得到一个更新的比较结果,也包括Theano和MXNet作为后端,那将会很有趣(虽然Theano现在已经被弃用了)。
也有一些说法,有些版本的Theano可能会忽略您的种子(有关Keras的post表单,请参阅本文)。
4.你的硬件是什么?
您使用的是亚马逊EC2 NVIDIA Tesla K80还是谷歌计算NVIDIA Tesla P100?甚至可能是TPU?😜看看这些有用的基准参考资料,了解这些不同的预训练模型运行时间。
- Apache MXNet的GluonNLP 0.6:缩小了与BERT重复研究的差距
- Caleb Robinson的“如何重现ImageNet验证结果”(当然,还有Curtis的“基准测试文章”)
- DL Bench
- Stanford DAWNBench
- TensorFlow的性能基准
5.你的学习速度如何?
在实践中,您应该保持预训练的参数不变(即使用预训练模型作为特征提取器),或者对它们进行微微调整,以避免在原始模型中忘记所有内容。
6.在使用批处理规范化或退出等优化时,特别是在训练模式和推理模式之间,有什么不同吗?
正如柯蒂斯的文章所说:
使用批处理规范化的Keras模型可能不可靠。对于某些模型,前向传递计算(假定梯度为off)仍然会导致在推断时权重发生变化。
但为什么会这样呢?
Expedia的首席数据科学家Vasilis Vryniotis首先发现了Keras中冷冻批次标准化层的问题:
Keras当前实现存在的问题是,当冻结批处理规范化(BN)层时,它在培训期间继续使用小批处理统计信息。我相信当BN被冻结时,更好的方法是使用它在训练中学习到的移动平均值和方差。为什么?由于同样的原因,在冻结层时不应该更新小批统计数据:它可能导致较差的结果,因为下一层的训练不正确。
Vasilis还引用了这样的例子,当Keras模型从列车模式切换到测试模式时,这种差异导致模型性能显著下降(从100%下降到50%)。
好了,请带着这些问题来指导您如何与下一个项目的预培训模型进行交互。有评论、问题或补充吗?可以在下面发表评论!