带你测试对比深度学习框架!TensorFlow,Keras,PyTorch...哪家强?(附数据集)

简介:

深度学习框架哪家强:TensorFlow?Caffe?MXNet?Keras?PyTorch?对于这几大框架在运行各项深度任务时的性能差异如何,各位读者不免会有所好奇。

微软数据科学家Ilia Karmanov最新测试的结果显示,亚马逊MXNet在CNN、RNN与NLP情感分析任务上性能强劲,而TensorFlow仅擅长于特征提取。

测试详情更新在Ilia Karmanov的GitHub项目DeepLearningFrameworks(https://github.com/ilkarman/DeepLearningFrameworks)内。不过作者表示,项目内的测试代码并非专门为深度学习性能而编写,目的仅在于简单比较一下各框架之间的性能差异。

以下为该项目的详情,have fun!

我们做这个榜单的初衷是为了好玩,所以省略了很多重要部分的比较。比如:帮助和支持,自定义图层(可以创建一个胶囊网络吗?),数据加载器,调试,不同的平台支持,分布式训练等等。

我们不确定是否能对框架的整体性能提出任何建议,因为本项目主要还是在演示如何在不同的框架中创建相同的神经网络。

例如,使用Caffe2在Python中创建CNN,然后在Julia中使用KNet复制这个网络,或者也可以在PyTorch中尝试创建一个RNN并在Tensorflow中复制它。你可以在Chainer中进行一些特征提取,然后在CNTK中复制这个操作。

因为Microsoft Azure深度学习虚拟机NC6上的框架已经更新到了最新版本,所以notebooks代码选择在上面运行,仅占用了显卡Nvidia K80 GPU一半的性能。

e7362329bf1f60236afafc5141e01062064005f2

测试目标

创建深度学习框架的Rosetta Stone(译者注:一个非常好用的外语学习软件),使数据科学家能够轻松地将他们的专业知识从一个框架转移到另一个框架(通过翻译,而不是从头开始学习)。另外,是为了更加透明地在模型训练时间和默认选项方面进行比较。

许多在线教程使用非常低级别的API,虽然这些API非常详细,但对于大多数用例来说,并没有多大意义,因为大多数时候有更高级别的帮助程序可用。在这里,我们直接忽略冲突的默认值的条件下,尝试采用最高级别的API,以便在框架之间进行更容易的比较。

下面的结果将证明,一旦使用更高级的API,代码结构变得非常相似,并且可以粗略地表示为:

  • 加载数据;  x_train,x_test,y_train,y_test = cifar_for_library(channel_first =?,one_hot =?)
  • 生成CNN / RNN网络结构(通常在最后一层上不激活)
  • 指定损失函数(交叉熵与softmax是一起指定的),优化器并初始化网络权重+会话
  • 用mini-batch的方式来训练训练集并使用自定义迭代器(所有框架都使用公共的数据库)
  • 在测试集的mini-batch上面进行预测
  • 计算准确率 

本质上,我们是在比较一系列确定性的数学运算(尽管是随机初始化),所以比较跨框架的准确性就是没有意义了。相反,它会提示我们去检查想要的匹配(?),以确保我们正在比较的是相同的模型架构。

测试结果(2017年11月24日)

在CIFAR-10数据集上训练CNN(VGG类型)网络 

性能对比- 图像识别

5baec24ce31a02a3d858e6dc0905919e426b04b8

该模型的输入是标准的CIFAR-10数据集,包含五万个训练图像和一万个测试图像,均匀分布在10个类别中。每个32×32像素的图像转化为张量的形式(3,32,32),像素值从0-255归一化到0-1。 例如:汽车图像的相关参数 y=(0,1,0,0,0,0,0,0,0,0),其标签是= [飞机,汽车,鸟,猫,鹿,狗,青蛙,马,船 ,卡车]

在IMDB数据集上训练RNN(GRU,门控循环单元)

性能对比 - 自然语言处理(情感分析)

49eb9b867e40e43ca7367a4bb9c94c44ba2d777c

这个模型的输入是标准的IMDB电影评论数据集,包含两万五千个训练评论和两万五千个测试评论,统一分为2个等级(正面/负面)。 下载的评论已经是单词索引的张量形式,例如 (如果你喜欢像南方公园这样的成人喜剧漫画)将被表示为(1 2 3 4 5 6 3 7 8)。

遵循Keras框架的处理方法,其中起始字符被设置为1,词汇外(使用3万大小的词汇库)被表示为2,因此词索引从3开始。通过零填充/截断的方式,把每条评论都固定到150个字。

在可能的情况下,我会尝试使用cudnn的方式来优化RNN(由CUDNN = True开关来控制),因为我们有一个可以轻易降低到CuDNN水平的简单的RNN。例如,对于CNTK,我们使用optimized_rnnstack而不是Recurrence(LSTM())函数。 虽然它不太灵活,但是速度要快得多。

例如,对于CNTK,我们不能再使用类似层归一化的更复杂的变量。在PyTorch中,这是默认启用的。但是对于MXNet,我无法找到这样的RNN函数,而是使用稍慢的Fused RNN函数。 

Keras最近刚得到了cudnn的支持,但是只有Tensorflow后端可以使用(而不是CNTK后端)。 Tensorflow有许多RNN变种,其中包括他们自己定制的内核。这里有一个很好的基准,我将尝试更新使用CudnnLSTM的样例而不是当前的方法。

注:CNTK框架是支持动态轴,这意味着我们不需要将输入填充到150个字,就可以按原样输入,但是由于我找不到与其他框架做到这一点的方法,所以我还是采用填充的方法。这样对CNTK框架有点不公平,因为会低估了它的能力。

分类模型创建大小为(150x125)的嵌入矩阵,然后采用100个门控循环单元,并将最终输出(不是输出序列也不是隐藏状态)作为输出。 

ResNet-50(特征提取)推断性能对比

77ff81517622ad8488ca58956cf079eb392c706b

加载一个预训练好的ResNet50模型并在avg_pooling结束后变成(7,7)向量处截断,输出一个2048维的向量。在这里可以插入一个softmax层或其它的分类器,例如用激励树来实现迁移学习。此处,在CPU和GPU上向avg_pool层进行前向传递的时间均计算在内。

我从中学到了什么?


关于CNN

以下提供了一些我在看到github上面提出的问题后比较跨框架的测试准确率时的一些见解。

1、上面的例子(Keras除外),为了便于比较,尝试使用相同级别的API,因此都使用相同的生成器函数。 对于MXNet和CNTK,我尝试了一个更高级别的API,在这里我使用了框架的训练生成器函数。在这个例子中,速度的提高是微不足道的,因为整个数据集都是作为NumPy数组加载到RAM中的,而且在处理的时候每个迭代的数据都是随机的。我怀疑框架的生成器是异步执行随机的。

奇怪的是,框架的随机操作似乎是在一个批次层次上而不是在一个观察层次上进行的,因此会略微降低测试精度(至少在10个迭代之后)。 对于我们会进行的输入输出活动以及可能在运行中进行预处理和数据增强的情况,自定义的生成器将对性能产生更大的影响。

2、让CuDNN自动调整/穷举搜索参数(能选择最有效的CNN算法来固定图像的大小)能在性能上带来一个巨大的提升。Chainer,Caffe2,PyTorch和Theano这四个框架都必须手动启动它。CNTK,MXNet和Tensorflow三个框架是默认启用CuDNN的。

贾扬清提到了cudnnGet (默认)和cudnnFind之间性能的提升。然而,其在TitanX GPU上的差异小得多。

现在看来,在K80 +上采用的新的cudnn使其性能差异问题更为突出。由于在目标检测各种图像大小的组合上运行cudnnFind会出现较大的性能下降,所以穷举搜索算法应该是不能在目标检测的任务上使用了。

3、使用Keras时,选择与后端框架相匹配的[NCHW]排序很重要。CNTK是channels first,我曾经在Keras上错误的配置为channels last。这样就必须在每一个batch上改变它的顺序,同时会造成性能严重的下降。通常,[NHWC]是大多数框架的默认设置(如Tensorflow),[NCHW]是在NVIDIA GPU上使用cuDNN训练时可以使用的最佳顺序。

4、Tensorflow,PyTorch,Caffe2和Theano四个框架都需要一个提供给dropout层的布尔值来指示我们是否训练,因为这对在测试集上的准确率有很大的影响,72 vs 77%。因此,在这种情况下不应该使用Dropout来测试。

5、使用Tensorflow框架时需要两个改变:通过启用TF_ENABLE_WINOGRAD_NONFUSED,同时还改变提供给channel first而不是channel last的维度(data_format ='channels_first')。对卷积操作启用WINOGRAD,自然而然的就将keras变成改成以TF作为后端。

6、Softmax层通常与cross_entropy_loss()函数一起用于大部分的功能,你需要检查一下你是否要激活最终的全连接层,以节省使用两次的时间。

7、不同框架的内核初始化器可能会有所不同,并且会对准确性有±1%的影响。我尽可能统一地指定xavier / glorot,而不要太冗长的内核初始化。

8、为了SGD-momentum中momentum类型的实现,我不得不关闭unit_gain。因为它在CNTK框架上是默认关闭,以此来跟其他框架的实现保持一致。

9、Caffe2对网络的第一层(no_gradient_to_input = 1)进行了额外的优化,可以通过不计算输入的梯度产生了一个比较小的速度提升。 Tensorflow和MXNet可能已经默认启用了此功能。 计算这个梯度对于研究和像deep-dream的网络是有用的。

10、在max-pooling之后使用ReLU激活意味着你在减少维度之后才执行一个计算,从而能够减少几秒钟。这可以使采用MXNet框架的运行时间缩短3秒。

11、一些可能有用的额外检查:

  • 是否指定的内核(3)变成了对称元组(3,3)或1维卷积(3,1)?
  • 步长(最大池化中的)是否是默认为(1,1)或等于内核(Keras这样做的)?
  • 默认填充通常是off(0,0)或valid,但检查一下它不是on/'same'是很有用的
  • 卷积层上默认的激活是否是'None'或'ReLu'的
  • Bias值的初始化可能不能(有时是没有bias值)
  • 梯度的下降和无穷大的值或 NaNs的处理可能因框架不同而不同
  • 有些框架支持稀疏的标签,而不是one-hot编码类型的(例如我使用的Tensorflow有f.nn.sparse_softmax_cross_entropy_with_logits函数)
  • 数据类型的假设可能是不同的-例如,我曾经试着用float32和int32类型来初始化X和Y。但是在torch中Y需要double类型(是为了可以使用在torch.LongTensor(y).cuda函数中)的数据
  • 如果框架有一个稍微低级一点的API,请确保在测试过程中不要通过设置training= False来计算梯度。

12、据说安装支持python3.5版本的Caffe2有点困难。因此我这里分享了一个脚本

8c814c6cbd05d6730728895e1e375b54f8966cf4

关于RNN

1、大多数框架(例如Tensorflow)上,都有多个RNN实现/内核; 一旦降低到cudnn LSTM / GRU级别,执行速度是最快的。但是,这种实现不太灵活(例如,可能希望层归一化),并且接下来如果在CPU上运行推理可能会出现问题。

2、在cuDNN这个层面,大部分框架的运行时间是非常相似的。这个Nvidia的博客文章写到过几个有趣的用于循环神经网络cuDNN优化的方法,例如,融合 - “将许多小矩阵的计算结合为大矩阵的计算,并尽可能地对计算进行流式处理,增加与内存I / O计算的比率,从而在GPU上获得更好的性能。”


原文发布时间为:2017-12-6

本文作者:文婧

本文来自云栖社区合作伙伴“数据派THU”,了解相关信息可以关注“数据派THU”微信公众号


相关实践学习
部署Stable Diffusion玩转AI绘画(GPU云服务器)
本实验通过在ECS上从零开始部署Stable Diffusion来进行AI绘画创作,开启AIGC盲盒。
相关文章
|
4天前
|
机器学习/深度学习 人工智能 算法
基于Python深度学习的【垃圾识别系统】实现~TensorFlow+人工智能+算法网络
垃圾识别分类系统。本系统采用Python作为主要编程语言,通过收集了5种常见的垃圾数据集('塑料', '玻璃', '纸张', '纸板', '金属'),然后基于TensorFlow搭建卷积神经网络算法模型,通过对图像数据集进行多轮迭代训练,最后得到一个识别精度较高的模型文件。然后使用Django搭建Web网页端可视化操作界面,实现用户在网页端上传一张垃圾图片识别其名称。
21 0
基于Python深度学习的【垃圾识别系统】实现~TensorFlow+人工智能+算法网络
|
4天前
|
机器学习/深度学习 人工智能 算法
【手写数字识别】Python+深度学习+机器学习+人工智能+TensorFlow+算法模型
手写数字识别系统,使用Python作为主要开发语言,基于深度学习TensorFlow框架,搭建卷积神经网络算法。并通过对数据集进行训练,最后得到一个识别精度较高的模型。并基于Flask框架,开发网页端操作平台,实现用户上传一张图片识别其名称。
19 0
【手写数字识别】Python+深度学习+机器学习+人工智能+TensorFlow+算法模型
|
4天前
|
机器学习/深度学习 人工智能 算法
基于深度学习的【蔬菜识别】系统实现~Python+人工智能+TensorFlow+算法模型
蔬菜识别系统,本系统使用Python作为主要编程语言,通过收集了8种常见的蔬菜图像数据集('土豆', '大白菜', '大葱', '莲藕', '菠菜', '西红柿', '韭菜', '黄瓜'),然后基于TensorFlow搭建卷积神经网络算法模型,通过多轮迭代训练最后得到一个识别精度较高的模型文件。在使用Django开发web网页端操作界面,实现用户上传一张蔬菜图片识别其名称。
20 0
基于深度学习的【蔬菜识别】系统实现~Python+人工智能+TensorFlow+算法模型
|
20天前
|
机器学习/深度学习 人工智能 算法
【车辆车型识别】Python+卷积神经网络算法+深度学习+人工智能+TensorFlow+算法模型
车辆车型识别,使用Python作为主要编程语言,通过收集多种车辆车型图像数据集,然后基于TensorFlow搭建卷积网络算法模型,并对数据集进行训练,最后得到一个识别精度较高的模型文件。再基于Django搭建web网页端操作界面,实现用户上传一张车辆图片识别其类型。
65 0
【车辆车型识别】Python+卷积神经网络算法+深度学习+人工智能+TensorFlow+算法模型
|
1月前
|
机器学习/深度学习 人工智能 算法
【玉米病害识别】Python+卷积神经网络算法+人工智能+深度学习+计算机课设项目+TensorFlow+模型训练
玉米病害识别系统,本系统使用Python作为主要开发语言,通过收集了8种常见的玉米叶部病害图片数据集('矮花叶病', '健康', '灰斑病一般', '灰斑病严重', '锈病一般', '锈病严重', '叶斑病一般', '叶斑病严重'),然后基于TensorFlow搭建卷积神经网络算法模型,通过对数据集进行多轮迭代训练,最后得到一个识别精度较高的模型文件。再使用Django搭建Web网页操作平台,实现用户上传一张玉米病害图片识别其名称。
55 0
【玉米病害识别】Python+卷积神经网络算法+人工智能+深度学习+计算机课设项目+TensorFlow+模型训练
|
2月前
|
机器学习/深度学习 人工智能 算法
鸟类识别系统Python+卷积神经网络算法+深度学习+人工智能+TensorFlow+ResNet50算法模型+图像识别
鸟类识别系统。本系统采用Python作为主要开发语言,通过使用加利福利亚大学开源的200种鸟类图像作为数据集。使用TensorFlow搭建ResNet50卷积神经网络算法模型,然后进行模型的迭代训练,得到一个识别精度较高的模型,然后在保存为本地的H5格式文件。在使用Django开发Web网页端操作界面,实现用户上传一张鸟类图像,识别其名称。
108 12
鸟类识别系统Python+卷积神经网络算法+深度学习+人工智能+TensorFlow+ResNet50算法模型+图像识别
|
3月前
|
机器学习/深度学习 算法 TensorFlow
深入探索强化学习与深度学习的融合:使用TensorFlow框架实现深度Q网络算法及高效调试技巧
【8月更文挑战第31天】强化学习是机器学习的重要分支,尤其在深度学习的推动下,能够解决更为复杂的问题。深度Q网络(DQN)结合了深度学习与强化学习的优势,通过神经网络逼近动作价值函数,在多种任务中表现出色。本文探讨了使用TensorFlow实现DQN算法的方法及其调试技巧。DQN通过神经网络学习不同状态下采取动作的预期回报Q(s,a),处理高维状态空间。
52 1
|
2月前
|
机器学习/深度学习 数据挖掘 TensorFlow
解锁Python数据分析新技能,TensorFlow&PyTorch双引擎驱动深度学习实战盛宴
在数据驱动时代,Python凭借简洁的语法和强大的库支持,成为数据分析与机器学习的首选语言。Pandas和NumPy是Python数据分析的基础,前者提供高效的数据处理工具,后者则支持科学计算。TensorFlow与PyTorch作为深度学习领域的两大框架,助力数据科学家构建复杂神经网络,挖掘数据深层价值。通过Python打下的坚实基础,结合TensorFlow和PyTorch的强大功能,我们能在数据科学领域探索无限可能,解决复杂问题并推动科研进步。
61 0
|
2月前
|
机器学习/深度学习 数据挖掘 TensorFlow
从数据小白到AI专家:Python数据分析与TensorFlow/PyTorch深度学习的蜕变之路
【9月更文挑战第10天】从数据新手成长为AI专家,需先掌握Python基础语法,并学会使用NumPy和Pandas进行数据分析。接着,通过Matplotlib和Seaborn实现数据可视化,最后利用TensorFlow或PyTorch探索深度学习。这一过程涉及从数据清洗、可视化到构建神经网络的多个步骤,每一步都需不断实践与学习。借助Python的强大功能及各类库的支持,你能逐步解锁数据的深层价值。
65 0
|
3月前
|
持续交付 测试技术 jenkins
JSF 邂逅持续集成,紧跟技术热点潮流,开启高效开发之旅,引发开发者强烈情感共鸣
【8月更文挑战第31天】在快速发展的软件开发领域,JavaServer Faces(JSF)这一强大的Java Web应用框架与持续集成(CI)结合,可显著提升开发效率及软件质量。持续集成通过频繁的代码集成及自动化构建测试,实现快速反馈、高质量代码、加强团队协作及简化部署流程。以Jenkins为例,配合Maven或Gradle,可轻松搭建JSF项目的CI环境,通过JUnit和Selenium编写自动化测试,确保每次构建的稳定性和正确性。
62 0

热门文章

最新文章