Theano、TensorFlow、Torch、MXNet 再到近日比较热门的 PyTorch 等等,深度学习框架之间的比较一直以来都是非常受人关注的热点话题。不过你知道用户实际用起来的感觉怎么样吗?近日,Reddit 用户 cjmcmurtrie 发了一个主题为「PyTorch vs. TensorFlow」的讨论帖,想要了解这两大流行的框架之间各自有什么优势。
帖子一楼写道:
我还没有从 Torch7 迁移到 TensorFlow。我玩过 TensorFlow,但我发现 Torch7 更加直观(也许是我玩得不够?)。我也尝试了一点 PyTorch,所以我决定先看看效果。
使用了几周 PyTorch 之后,我认为我现在还不必迁移到 TensorFlow,至少在我感兴趣的项目上还不需要。用 PyTorch 写自定义模块真是简单至极。而且其动态图构建(dynamic graph construction)给我之前需要熬夜实现(或等待列表上)的东西带来了很多新想法。我认为对机器学习开发者来说,PyTorch 是一个了不起的工具集。我也知道 TensorFlow 的社区资源要强大得多,但如果要开发全新的项目(而不是为已有的架构重新写代码或阅读教程),社区也不一定能有很大的帮助。
这个 Reddit 帖子发出后得到了很多机器学习研究者和开发者的关注,他们纷纷跟贴谈论自己的想法和经验(不只是关于 PyTorch 和 TensorFlow,讨论中还涉及到更多工具)。
下文为我们提炼的一些观点,原帖请看:https://redd.it/5w3q74
TensorFlow
优势:
等效的图形编译(graph compilation)要快得多;我们用了几秒而不是几分钟。但是它仍然不够快,如果我们想要将它的大部分添加到我们的 CI 套件(CI suite),但我们不需要等待很长时间来开始训练。
从 Lasagne 转到 TensorFlow 之后,我喜欢 tf.layers 和 tf.contrib.layers 中更高层次的功能;它们为接受张量(tensor)并返回张量的功能性 API,因此更容易与「原始」的 TensorFlow 集成。我们可以做普通的张量操作,而不用写一个层那么麻烦。
在我们使用的模型上,TensorFlow 的速度稍稍快于 Theano(20%-30%)。当第一次使用时,我们看到大致相同的性能,并认为这可以接受,但然后我们阅读 TensorFlow 的性能指南(https://www.tensorflow.org/performance/performance_guide),并切换到 NCHW 并融入批处理规范(batch norm),然后一切运行得更快了。我猜 Theano 本身就不是很快……
关于开发人员的反馈速度:我曾在 TF 的问题区提出了一些微不足道的问题,但 TF 开发人员通常在一两天内就回复我了。
此外,工具是相当好的。TensorBoard 绝对好用,用来表示的时间线(timeline)/跟踪(trace)的工具也一样好用。但是我还没有尝试新加入的 tfdbg。
TensorFlow 在设计时就考虑到了分布式,所以如果你需要运行真正的大规模项目,TensorFlow 多半是最好的。
缺点:
TensorFlow 的 API 非常荒谬,它在每个阶段都会重新发明轮子,并且要求开发者学习很多本不必要的新概念。然而,开发者峰会表示这一境况正在改善——而且同时使用 TensorFlow Servin 和 Cloud ML 会提高你的生产力。
在实践中部署到 iOS 非常困难。
我并没有在 Keras 或者 Tensorflow 上工作,但是我看过他们的「问题」日志和一些用户组,只是因为大量的用户,这些框架看起来并不会得到这种个人的关注。
PyTorch
优势:
它属于轻量级;
它目前位于 Python 中;
它使你能够明确地控制计算。没有编译器能自己妄图变聪明来「帮助你」,或是将你的代码加速;事实上大多编译器在调试中会产生大量麻烦;
它使 GPU 内核调用之上仅有少量(可解释的)抽象层,而这恰恰是高性能的保证;
也许这是个人偏好,但我得到了与抽象有关的特定 OCD。每当我要做艰巨的工作时都会很紧张,因为一旦我的未来被泄漏,我便能感觉到它那些无法摆脱且难以忍受的痛苦。相对简单的事情理应在引擎盖之下发生的大多数情况下,这种感觉尤为强烈;
调试更容易,因为特定代码中会是特定行(而不是在距离使用大型或生成的 Graph 对象的 sess.run()很远的地方)失败。你的堆栈跟踪不会填满三个屏幕来让你玩「找找错误在哪里!」的竖版卷轴游戏;
不存在编译时间。我无法理解 Theano 用户是如何处理的,他们一定更有耐心;
你可以直接操作渐变,显然,做一些事情时可以更容易,也更自然(如在反向传播过程中的渐变剪辑,或各种「破碎的反向传播」的有关想法,就像最近的 Shake Shake reg 命令一样;的确,我认为你可以用 stop_gradient 破解一个解决方案);
它对动态图的支持从一开始就是自上而下的设计原则,而非随之而至的事后想法。并且我们会看到更多的动态图表,如做成一大块 NLP,或是神经模块网 ;
它没有缩进或膨胀你的代码的显式会话对象;
它获得的抽象是正确的:raw numpy - > Tensors(但 GPU 上的 raw numpy 可能对深度学习一无所知!)- >变量(它们了解深度学习),并且 Modules 或 Optim 等等会稍有益处。
动态计算使很多事情更加容易,如 seq2seq + attention 的神经翻译很难通过 keras + tf 来实现,但使用 PyTorch 便会很容易;
更容易调试,因为你可以只使用标准的 PyThon 工具;
PyTorch 让自定义的实现更加容易,所以你得以将更多时间专注于算法中,这样往往能够改进主要性能;
使 Multi-gpu 简单易懂;
Torch-vision 使加载和变换图像变得容易。
PyTorch 提供了一个强化功能。增强功能基本上不会在实现中产生过多资源消耗,能有一些内置函数来调用 RL 的感觉真棒。
我遇到的错误或问题得到PyTorch 团队及时的反映,通常会在当天修复,或者得到解决方法或得到问题跟踪。
PyTorch 是可以立即使用的,在我当前的项目的单 GPU 的训练时间比 theano+lasagne 快 100%。我测试过,100% 逐字地在 CIFAR100 上从(在最简单的情况下)5 分/历元到 2.5 分/历元,并且在某些情况下降到 2 分钟/历元(即,快两倍)
缺点:
PyTorch 的 API感觉有些粗糙,但对它有一些限定词。如果你只是做一些标准的任务(实现 ResNet 或者 VGG)我认为你不会有问题,但我一直都有一些分歧因为我所做的一切都有些奇怪。
对于 PyTorch 我最大的「抱怨」基本上是在神经网络 API 方面「事情并未按照我让他们组合的方式进行放置」。具体来说,我非常喜欢 Lasagne 的「层次(layers)」范式—但是一点点批判性的思维就会让你得出这个结论,这个范式尤其不适合动态图框架。
PyTorch 没有为部署设计,开发团队它看上去并没有把重心放在 PyTorch 上(虽然在这方面,我可能看错了,我模糊的记得我在论坛的帖子上看到过这个)。我想要练习将一些东西放置在网站或者 droid app 上我不确定其他的框架能很好地支持这种方式。
本文来自开源中国社区 [http://www.oschina.net]