Karmanov表示,他这个项目的目标是创建一个深度学习框架的罗塞塔石碑,让数据科学家能够轻松地将他们在一个框架上的专长转移到另一个框架上(而不是从头开始学习)。具体说,就是在8种最常用的框架上构建同一个神经网络。而且,有了这样一个模型后,也就有了比较各个框架的基准,各个框架的训练时间和默认选项也变得更加透明。
Karmanov发现,许多在线教程都使用低级别的API,虽然写很详细,但对于大多数用例而言,除非想要创建新的层,否则意义不大。因此,他在项目中使用了最高级别的API,以便更容易地在框架之间进行比较。
结果证明,一旦使用更高级的API,不同框架的代码结构实际上变得非常相似,并且可以粗略地表示为:
本质上这里是在对一系列确定的数学运算(尽管是随机初始化的)进行比较,因此在结果中比较各个框架的准确性并没有什么意义。Karmanov将精度作为一个去匹配(而非对比)的指标,确保比较的是相同的模型架构。
结果:Caffe2、MXNet表现不俗
硬件是Nvidia K80 GPU,环境是Ubuntu,所有框架都是最新版本:
但是,比较训练速度意义不大
虽然对10大常用框架进行了对比,但Karmanov进一步在他的Medium文章里解释了,比较速度并没有意义:
10点心得
以下是Karmanov在所有框架上匹配训练精度,参考Github上所有issue/Pull request后的一些见解:
1. 上面的框架(除了Keras),为了方便比较,都尝试使用相同级别的API,所以都使用相同的生成函数。对于MXNet和CNTK,我尝试了一个更高级别的API,使用框架的训练生成器函数。这个例子中速度的提升是可以忽略的,因为整个数据集作为NumPy数组加载到RAM中,每个epoch完成的处理是就是一次shuffle。我怀疑框架的生成器运行了异步shuffle。奇怪的是,NXNet和CNTK似乎在batch级别而不是observation级别上shuffle,因此测试精度稍微降低(至少在10个epoch之后)。如果有IO,或者有预处理和数据增强的情况,custom生成器对性能的影响将会更大。
2. 启用CuDNN的auto-tune/穷举搜索参数(为固定大小的图像选择最有效的CNN算法)能够大幅提升性能。在Caffe2,PyTorch和Theano,这个功能得手动开启。CNTK,MXNet和Tensorflow则是默认启用这项功能。Chainer是什么情况我还不清楚。扬清说,cudnnGet(默认)和cudnnFind之间的性能提升在Titan X GPU上要小得多;在这里,K80 +新的cudnn看来使问题更加突出了。在目标检测时,不论组合为何,运行cudnnFind都严重影响了性能回归,所以在目标检测时应该禁用exhaustive_search
3. 使用Keras时,选择与后端框架匹配的[NCHW]排序非常重要。CNTK是最先是针对通道(channel)运算的,但我不小心把Keras配置为最后用通道了。结果每个批次都必须改变顺序,严重降低了性能。
4. Tensorflow,PyTorch,Caffe2和Theano需要向pooling层提供一个布尔值,表示有没有在训练(这对测试精度有很大影响,72%比77%)。在这种情况下,不应该使用dropout来进行测试。
5. TensorFlow有点烦人,需要做两个调整:启用TF_ENABLE_WINOGRAD_NONFUSED,以及将维度最先(而不是最后)提供给通道(data_format='channels_first')可以提升速度。启用WINOGRAD进行卷积,当然也可以提升TF做后端的Keras
6. 对大多数函数而言,Softmax通常跟cross_entropy_loss() 捆绑在一起,如果你在最后的全连接层上需要激活,最好检查一下,这样可以节省时间避免做两次
7. 不同框架的内核初始化函数可能会有所不同(我发现这对准确性有+/- 1%的影响),只要有可能我都会指定xavier/glorot
8. SGD-momentum的实现,我需要关闭unit_gain(在CNTK是默认打开的)来匹配其他框架的实现
9. Caffe2对网络的第一层(no_gradient_to_input = 1)有一个额外的优化,通过不计算输入的梯度,使速度有一个较小的提升。很可能,TensorFlow和MXNet是默认启用这项功能的。但是,对于一些研究目的和像DeepDream这样的项目,计算这个梯度可能还是有用的
10. 在max-pooling之后(而不是之前)应用ReLU激活意味着在降维后执行计算,这会省掉几秒钟的时间。在MXNet上面,这减少了3秒钟的时间
Karmanov对整个开源社区,包括Caffe2作者、Facebook的贾扬清表示感谢,他在Github写了更多心得体会,并欢迎你提供提升训练时间的建议: