观点 | 哈哈,TensorFlow被吐槽了吧

作者 | Nico

参与 | shawn

今天,一篇吐槽TensorFlow的文章在网上刷屏,到底是怎么回事呢?来看这位作者的抱怨有没有道理。

每隔几个月,我都会Google一下“Tensorflow sucks(Tensorflow 烂透了)”或“f*** Tensorflow”,希望能找到志同道合的黑粉。尽管Tensorflow面世已约两年,我还是找不到一个令我满意的批评Tensorflow的言论,也许是我用的搜索引擎不对,但是我认为罪魁祸首是一种被称为“谷歌嫉妒”的现象,具体表现为全世界的工程师都臆想:

  • 在谷歌工作的人比你聪明,比你有能力。
  • 如果懂Tensorflow,就能在谷歌谋得一份深度学习的职位(年轻人,醒醒吧)
  • 你所在的初创公司在使用Tensorflow,如果在博客上夸奖Tensorflow的优点,谷歌看到后也许会想收购你的公司。
  • 如果get不到Tensorflow那反直觉的设计,你就资质平庸。

现在,让我们把这些臆想抛在脑后,客观地看看Tensorflow。

当Tensorflow刚面世的时候,其开发者向我们承诺:有了Tensorflow,就再也不用忍受那些不是设计蹩脚就是缺乏维护的深度学习框架了(例如 https://github.com/BVLC/caffe/issues)。结果,我们得到的这个深度学习框架虽然可以与Java相提并论(“一次编写,到处运行” ——译者注:这是Sun Microsystem(于2010年被Oracle收购)为宣传Java语言的跨平台特性而提出的口号),但是完全陈述性的模式(paradigm)却使它用起来没那么有趣。真是讨厌!

哪里出错了呢?虽然谷歌的目的是开发出一个让所有人都能使用的工具,但是它做出的这个产品似乎并不能让所有人都满意。

对于研究人员而言,Tensorflow不仅学起来难,而且用起来也难。研究注重的是灵活性,缺乏灵活性这个缺陷已深入到Tensorflow 的“骨髓”。

在Tensorflow中,如果想提取神经网络中间层的值,你需要先定义一个graph,然后将数据以字典(dictionary)的形式输入到这个graph中,执行graph。噢,别忘了将中间层作为graph的输出添加到网络中,否则就无法得出中间层的值。好吧,虽然很麻烦,但是行得通。

想有条件地执行层(例如:在每生成一个end-of-sentence (EOS) token时停止运行的循环神经网络)?哪一天等你完成了,使用Pytorch的人也败了3家AI初创公司了。

对于像我这样的机器学习从业人员,Tensorflow也算不上明智之选。这个框架陈述性的设计语言使得调试(debugging)更为困难。能在安卓或iOS系统上运行模型这个优点固然很好,但是当你看到框架的二进制文件(binaries)有多大(20MB以上),或者试图检查几乎不存在的C++文件,或者当你想进行某种条件式的网络执行(在mobile这种资源不足的情况中非常有用)时,你就不会这样认为了。

对比其他框架

Tensorflow的开发者都是深度学习领域的大拿,这一点毋庸置疑。但是,名望最大的原Tensorflow开发者贾扬清(Yangquing Jia)最近离开谷歌转投Facebook大营,专注于快速崛起的Caffe2项目(https://github.com/caffe2/caffe2/graphs/contributors, https://github.com/caffe2/caffe2/issues)。和Tensorflow不同,Caffe2允许用户通过一行代码用某一条数据执行某一网络层。

此外,Pytorch正越来越受到顶尖AI研究人员的青睐。Torch用户因编写Lua代码执行简单的string操作而饱受重复性劳损(RSI)折磨,但是他们并没有涌向Tensorflow,而是转投Pytorch。看来对于顶尖AI实验室而言,Tensorflow还是不够好。抱歉了,谷歌。

最让我感兴趣的问题是:为什么谷歌偏偏为Tensorflow选择了一个完全陈述性的模式,全然不顾这种模式显而易见的缺陷。他们是否认为,将所有计算囊括到一个计算图(computation graph)中可以使模型在自家TPU(张量处理器)上运行,从而在深度学习驱动型应用的云计算服务上与英伟达(Nvidia)展开竞争,切断其数百万美元的财路?这很难说。总的来说,对公众而言Tensorflow算不上是一个完全开源的项目。如果开发者能完善Tensorflow的设计,那我就没话可说。但是,与谷歌的其他开源项目(如Protobuf、Golang和Kubernetes)相比,Tensorflow落后的不是一点点。

虽然陈述性模式对于UI编程而言很有用,但是对于深度学习而言它并不是一个理想选择,原因有很多。

拿React Javascript库来说,它是当今交互式网页应用程序设计的标准选择。在React中,开发者不知道数据在应用程序中如何传递是合理的,因为Javascript的执行速度要比DOM (Document Object Model,文档对象模型)的更新速度快好几个数量级。只要终端用户的体验“足够好”,Reacr开发者就不必操心状态的传播机制。

但是在深度学习中,一个层就可以执行数百万个FLOP!深度学习研究人员的目标就是理解计算过程并实现精确控制,因为他们要不断突破极限(例如动态神经网络),并找出获得中间层结果的简易途径。

实例

举个简单的例子:训练一个模型,让模型将其输入乘以3

首先,我们先看Tensorflow的代码:

import tensorflow as tf import numpy as np X = tf.placeholder("float") Y = tf.placeholder("float") W = tf.Variable(np.random.random(), name="weight") pred = tf.multiply(X, W) cost = tf.reduce_sum(tf.pow(pred-Y, 2)) optimizer = tf.train.GradientDescentOptimizer(0.01).minimize(cost) init = tf.global_variables_initializer() with tf.Session() as sess: sess.run(init) for t in range(10000): x = np.array(np.random.random()).reshape((1, 1, 1, 1)) y = x * 3 (_, c) = sess.run([optimizer, cost], feed_dict={X: x, Y: y}) print c

然后再看Pytorch完成相同任务的代码:

import numpy as np import torch from torch.autograd import Variable model = torch.nn.Linear(1, 1) loss_fn = torch.nn.MSELoss(size_average=False) optimizer = torch.optim.SGD(model.parameters(), lr=0.01) for t in range(10000): x = Variable(torch.from_numpy(np.random.random((1,1)).astype(np.float32))) y = x * 3 y_pred = model(x) loss = loss_fn(y_pred, y) optimizer.zero_grad() loss.backward() optimizer.step() print loss.data[0]

虽然Pytorch的代码比TensorFlow代码少一行,但是它的操作过程更加简洁,训练过程中的语法结构与实际的学习流程配合得更加紧密。

  • 向前传递输入
  • 生成损失
  • 计算梯度
  • 反向传播

在TensorFlow中,核心操作则是神秘的sess.run调用。

为什么要再写一些结尾部分让人难以理解且难以维护的代码呢?客观而言,Pytorch的界面要比Tensorflow好很多。好的不是一点点。

结论

对于快速原型(rapid prototyping)而言,谷歌创造的TensorFlow框架太过于低级,无法使用;但是在尖端研究或者资源有限的生产环境中,TensorFlow却因太高级而无法轻松使用。

老实说,当你为了确保你的库能够使用,于是在这个高级库的基础上再多建了好几个开源高级库,你一定知道哪里肯定出大错了:

  • http://tflearn.org/
  • https://github.com/tensorflow/tensorflow/tree/master/tensorflow/contrib/slim
  • https://github.com/fchollet/keras
  • https://github.com/tensorflow/skflow

注意:我承认Tensorboard(TensorFlow的监测工具)真的是一个很好的工具。如果你想为你的机器学习项目制定一个很好的监测方案,你可以看看Losswise (https://losswise.com)。我开发这个工具的目的是,为了让像我一样的机器学习开发者能在任何机器学习库中解耦追踪(decouple track)模型的性能,并且能够用上许多Tensorboard不提供的好功能。

原文发布于微信公众号 - AI科技大本营(rgznai100)

原文发表时间:2017-10-09

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏美团技术团队

美团点评联盟广告的场景化定向排序机制

前言 在美团点评的联盟广告投放系统(DSP)中,广告从召回到曝光的过程需要经历粗排、精排和竞价及反作弊等阶段。其中精排是使用CTR预估模型进行排序,由于召回的候...

651140
来自专栏美团技术团队

智能分析最佳实践——指标逻辑树

背景 所有业务都会面对“为什么涨、为什么降、原因是什么?”这种简单粗暴又不易定位的业务问题。为了找出数据发生异动的原因,业务人员会通过使用多维查询、dashbo...

699110
来自专栏IT大咖说

别急!看完文章再来说你懂TensorFlow

19410
来自专栏云加头条

DI-X平台发布:云上的深度学习,助力接入AI快车道

腾讯云推出的DI-X提供了融合了深度学习的框架、算法、模型训练、模型推理和协作的一站式深度学习平台,用以加速中小企业接入人工智能的过程。

1.2K30
来自专栏应兆康的专栏

18. Eyeball和Blackbox开发集应该多大?

你的 Eyeball 开发集应该足够大,大到可以让你了解到算法的主要错误类别。如果你正在从事一项人类可以表现很好的任务(如识别图像中的猫咪),下面是一些指导方...

33980
来自专栏ATYUN订阅号

Uber开源Atari,让个人计算机也可以快速进行深度神经进化研究

Uber近期发布了一篇文章,公开了五篇关于深度神经进化的论文,其中包括发现了遗传算法可以解决深层强化学习问题,而一些流行的方法也可替代遗传算法,如深度Q-lea...

11940
来自专栏AI研习社

DeepMind 推出分布式训练框架 IMPALA,开启智能体训练新时代

AI 研习社按,日前,DeepMind 推出一种全新的分布式智能体训练框架 IMPALA,该框架具有高度可扩展性,将学习和执行过程分开,使用了一种名为 V-tr...

33860
来自专栏人工智能头条

4月机器学习热文出炉,这10篇文章你读了吗?

16640
来自专栏人工智能

快速安全追踪(FaSTrack):确保动态系统的安全实时导航

实时自主运动和导航是很难的,特别是当我们关心安全性时。当我们的动力系统复杂,以及外部干扰(如风)和先验条件未知时,这变得更加困难。我们在这项工作中的目标是为了保...

29970
来自专栏量子位

4小时学会雅达利游戏,AI需要几台电脑?

昨天,优步AI Lab开源了深度神经进化的加速代码。其博客上称,哪怕用户只有一台电脑(台式机),用这个代码也能训练出会打雅达利的AI。而且只需要4!小!时!

13220

扫码关注云+社区

领取腾讯云代金券