TensorFlow 是谷歌的开发者创造的一款开源的深度学习框架,于 2015 年发布。官方研究发布于论文《TensorFlow:异构分布式系统上的大规模机器学习》。
论文地址:http://download.tensorflow.org/paper/whitepaper2015.pdf
TensorFlow 现已被公司、企业与创业公司广泛用于自动化工作任务和开发新系统,其在分布式训练支持、可扩展的生产和部署选项、多种设备(比如安卓)支持方面备受好评。
PyTorch 是由 Facebook 的团队开发,并于 2017 年在 GitHub 上开源。有关其开发的更多信息请参阅论文《PyTorch 中的自动微分》。
论文地址:https://openreview.net/pdf?id=BJJsrmfCZ
PyTorch 很简洁、易于使用、支持动态计算图而且内存使用很高效,因此越来越受欢迎。
比较这两个框架最好的方法就是用它们编写代码。我专门为这篇文章写了一个jupyter笔记,你可以在这里找到代码,文章涉及到的所有的代码都有。
与 PyTorch 相比,TensorFlow 的学习曲线相对较徒。Python 程序员需要较少的时间即可使用 PyTorch,因为对他们来说,PyTorch 更像是 Python 框架的扩展。简单的调试和一套优秀的简单 API 就能使程序员轻松驾驭 PyTorch。PyTorch 是研究人员的神器,因为事实证明,开发框架的研究人员至少有 70% 都在使用 PyTorch。尽管 TensorFlow 是业界领先的应用开发选择,但它在这方面还没有赶上 PyTorch。这背后的一个原因可能是 PyTorch 的简单易用性和更好的性能。在 TensorFlow 的世界里, PyTorch 能够凭借自己的强项坚守自己。下面是 PyTorch 的一些亮点,解释了为什么 PyTorch 适合深度学习项目。
PyTorch 是一个实用框架,它可以让我们以更 “Python 化” 的方式编写代码。此外,它是使用朴素的 Python 代码所支持的那种动态特性。
与任何其他库相比,PyTorch 更倾向于 Python。这是因为 PyTorch 相对容易理解,而且感觉更自然、更原生,和 Python 代码一致。对于任何使用过 PyTorch 的人来说,比如损失函数、优化器、转换、数据加载器以及更多的类都是非常容易实现的。
每个 PyTorch 示例(计算机视觉和自然语言处理)的代码都有一个共同的结构:
data/
experiments/
model/
net.py
data_loader.py
train.py
evaluate.py
search_hyperparams.py
synthesize_results.py
evaluate.py
utils.py
model/net.py
:指定神经网络架构、损失函数和评估指标。model/data_loader.py
:指定数据应如何馈送到网络。train.py
:包含主训练循环。evaluate.py
:包含用于评估模型的主循环。utils.py
:用于处理超参数/日志/存储模型的实用功能。PyTorch 中的数据并行(Data Parallel)非常高效,可以将数据分成若干批,然后发送到多个 GPU 进行处理。使用这种技术,PyTorch 可以将很大一部分工作负载从 CPU 转移到 GPU。为了实现数据并行,它使用了 torch.nn.DataParallel 类。
Distributed Data-Parallel(分布式数据并行)是 PyTorch 的一项特性,你可以将其与 Data-Parallel(数据并行)结合使用来处理需要大型数据集和模型的用例,这些数据集和模型对单个 GPU 来说过于庞大。当 GPU 池上的所有任务完成之后,结果将被收集、合并,再由 Data-Parallel 发回给你。
def get_cnn(self, arch, pretrained):
"""Load a pretrained CNN and parallelize over GPUs
"""
if pretrained:
print(("=> using pre-trained model '{}'".format(arch)))
model = models.__dict__[](pretrained=True)
else:
print(("=> creating model '{}'".format(arch)))
model = models.__dict__<a href="">arch
if arch.startswith('alexnet') or arch.startswith('vgg'):
model.features = nn.DataParallel(model.features)
model.cuda()
else:
model = nn.DataParallel(model).cuda()
return model
</a href="">
从版本 1.3 开始,PyTorch 就增加了对 Android 和 iOS 设备部署的支持。这一特性,为边缘设备带来了 PyTorch 的所有优势,以满足需要较低延迟的应用。PyTorch mobile 背后的目标是通过支持移动平台的基础 API 来缩短开发周期,从而无需导出到诸如 Caffe2 之类的移动框架。这样可以大大减少设备上的占用空间。此外,为了更好地控制,还增加了对构建脚本的精确调优的支持。
PyTorch Mobile 入门:
当你可以选择访问每一行,并在每一行后打印的常规方式,PyTorch 调试起来很容易。锦上添花的是,PyTorch 中的对象和操作包含了实际的数据而不是符号引用。PyTorch 的一些标准调试器是:
例如,你可以使用 pdb 的 pdb.set.trace()
函数在代码中放置断点,从而深入到错误的根源。此外,PyTorch 的动态计算图允许在代码执行时进行动态修改和快速调试。
开放神经网络交换格式(Open Neural Network Exchange,OONX)作为人工智能的开源生态系统,为人工智能程序员提供了一个共同的平台,让他们可以在各种框架、工具和库上进行互换工作。ONNX 通过提供可跨多个框架和硬件工作的标准文件格式来实现这一目标。PyTorch中,ONNX 内置了对 PyTorch 和其他一系列框架的支持,如 Caffe2、MXNet、TensorFlow 等等。ONNX 使开发人工智能的程序员更容易导出和迁移他们的 PyTorch 模型,使之成为其他框架可以集成的开放格式。
import torch.onnx
import torchvision
dummy_input = torch.randn(1, 3, 224, 224)
model = torchvision.models.alexnet(pretrained=True)
torch.onnx.export(model, dummy_input, "alexnet.onnx")
通过将每个模型视为有向无环图,PyTorch 提供了一种定义计算图的动态方法。虽然其他框架也允许静态图定义,但 PyTorch 还支持创建动态计算图,你可以随时对其进行操作。从 PyTorch 的动态特性中获益最多的一个元素是递归神经网络。
PyTorch 还提供了优秀的社区支持。PyTorch 的主页上就有关于它每个特性的详细文档。对库的所有最新更新都作了很好的解释。对于每个新添加的内容,都可以找到辅导教程和相关资源,易于上手。
下面是一些 PyTorch 开发人员社区、资源和教程,你可以通过这些资源和教程来贡献、学习和解惑:
● PyTorch Discuss form
● PyTorch Slack Community
● PyTorch Examples
● PyTorch Docs
● Github Pytorch Tutorials
● PyTorch Beginner Cheatsheet
● PyTorch Release Notes
● Deep Learning With Pytorch : A 60 Minute Blitz
● Using Tutorial data from Google Drive in Colab
● Docs and Tutorials in Chinese
● Tutorials in Korean
张量:可理解为一个 n 维矩阵,所有类型的数据,包括标量、矢量和矩阵等都是特殊类型的张量。
TensorFlow 支持以下三种类型的张量:
TensorFlow 不是一个严格的“神经网络”库。只要你可以将你的计算表示为一个数据流图,你就可以使用Tensorflow。你来构建图,描写驱动计算的内部循环。我们提供了有用的工具来帮助你组装“子图”(常用于神经网络),当然用户也可以自己在Tensorflow基础上写自己的“上层库”。定义顺手好用的新复合操作和写一个python函数一样容易,而且也不用担心性能损耗。当然万一你发现找不到想要的底层数据操作,你也可以自己写一点c++代码来丰富底层的操作。
Tensorflow 在CPU和GPU上运行,比如说可以运行在台式机、服务器、手机移动设备等等。想要在没有特殊硬件的前提下,在你的笔记本上跑一下机器学习的新想法?Tensorflow可以办到这点。准备将你的训练模型在多个CPU上规模化运算,又不想修改代码?Tensorflow可以办到这点。想要将你的训练好的模型作为产品的一部分用到手机app里?Tensorflow可以办到这点。你改变主意了,想要将你的模型作为云端服务运行在自己的服务器上,或者运行在Docker容器里?Tensorfow也能办到。
过去如果要将科研中的机器学习想法用到产品中,需要大量的代码重写工作。那样的日子一去不复返了!在Google,科学家用Tensorflow尝试新的算法,产品团队则用Tensorflow来训练和使用计算模型,并直接提供给在线用户。使用Tensorflow可以让应用型研究者将想法迅速运用到产品中,也可以让学术性研究者更直接地彼此分享代码,从而提高科研产出率。
基于梯度的机器学习算法会受益于Tensorflow自动求微分的能力。作为Tensorflow用户,你只需要定义预测模型的结构,将这个结构和目标函数(objective function)结合在一起,并添加数据,Tensorflow将自动为你计算相关的微分导数。计算某个变量相对于其他变量的导数仅仅是通过扩展你的图来完成的,所以你能一直清楚看到究竟在发生什么。
Tensorflow 有一个合理的c++使用界面,也有一个易用的python使用界面来构建和执行你的graphs。你可以直接写python/c++程序,也可以用交互式的ipython界面来用Tensorflow尝试些想法,它可以帮你将笔记、代码、可视化等有条理地归置好。当然这仅仅是个起点——我们希望能鼓励你创造自己最喜欢的语言界面,比如Go,Java,Lua,Javascript,或者是R。
比如说你有一个32个CPU内核、4个GPU显卡的工作站,想要将你工作站的计算潜能全发挥出来?由于Tensorflow 给予了线程、队列、异步操作等以最佳的支持,Tensorflow 让你可以将你手边硬件的计算潜能全部发挥出来。你可以自由地将Tensorflow图中的计算元素分配到不同设备上,Tensorflow可以帮你管理好这些不同副本。
创建和运行计算图可能是这两个框架差别最大的地方。在 PyTorch 中,图结构是动态的,也就是说图是在运行时创建的。在 TensorFlow 中,图结构是静态的,也就是说图在「编译」之后再运行。举个简单例子,在 PyTorch 中,你可以使用标准的 Python 句法写一个 for 循环:
而且 T 可以在这段代码的执行之间改变。在 TensorFlow 中,这需要在构建图时使用控制流操作(control flow operations),比如 tf.while_loop。TensorFlow 确实有 dynamic_rnn 可用于更常见的结构,但创建自定义的动态计算也更加困难。
PyTorch 简单的图构建方式更容易理解,但也许更重要的是也更容易调试。调试 PyTorch 代码就跟调试 Python 代码一样。你可以使用 pdb,并且可以在任何地方设置断点。调试 TensorFlow 则没这么容易。它有两个选择,一是从会话中请求你想检查的变量,而是学会使用 TensorFlow 调试器(tfdbg)。
随着 PyTorch 的发展,这两者之间的差距会缩小至零。但是,TensorFlow 仍然支持一些 PyTorch 并不支持的功能。PyTorch 目前还不具备的特性包括:
而 TensorFlow 支持所有这些。另外比起 PyTorch,TensorFlow 的 contrib 包也有远远更多更高级的函数和模型。
在这两种框架中,保存和加载模型都很简单。PyTorch 有一个非常简单的 API,既可以保存模型的所有权重,也可以 pickle(加工)整个类。TensorFlow 的 Saver 对象也很容易使用,而且也为检查点提供了更多选择。
TensorFlow 在序列化方面的主要优势是整个计算图都可以保存为 protocol buffer。这既包括参数,也包括运算。然后这个图可以用其它支持的语言(C++、Java)加载。对于不支持 Python 的部署环境来说,这是非常重要的功能。而且理论上,这个功能也可以在你修改模型的源代码,但又想运行旧模型时为你提供帮助。
对于小型服务器(比如 Flask 网页服务器)上的部署,两种框架都很简单。
TensorFlow 支持移动和嵌入式部署,而包括 PyTorch 在内的很多深度学习框架都没有这个能力。在 TensorFlow 上,要将模型部署到安卓或 iOS 上需要不小的工作量,但至少你不必使用 Java 或 C++ 重写你模型的整个推理部分。
对于高性能服务器上的部署,还有 TensorFlow Serving 可用。对于严重依赖机器学习的服务,TensorFlow Serving 可能就是继续使用 TensorFlow 的充分理由。除了性能方面的优势,TensorFlow Serving 的另一个重要特性是无需中断服务,就能实现模型的热插拔。
TensorFlow 的设备管理的无缝性能非常好。通常你不需要指定任何东西,因为默认的设置就很好。比如说,TensorFlow 假设如果存在可用的 GPU,你就希望在 GPU 上运行。而在 PyTorch 中,你必须在启用了 CUDA 之后明确地将所有东西移到 GPU 上。
TensorFlow 设备管理的唯一缺陷是它会默认占用所有可用的 GPU 上的所有内存,即使真正用到的只有其中一个。但也有一种简单的解决方案,就是指定 CUDA_VISIBLE_DEVICES。有时候人们会忘记这一点,就会让 GPU 看起来很繁忙,尽管实际上它们啥也没干。
在使用 PyTorch 时,我发现我的代码需要更频繁地检查 CUDA 的可用性和更明确的设备管理。尤其是当编写可以在 CPU 和 GPU 上同时运行的代码时更是如此。另外,要将 GPU 上的 PyTorch Variable 等转换成 NumPy 数组也较为繁琐。
这两种框架都可以构建或绑定用 C、C++ 或 CUDA 写的扩展。TensorFlow 还是需要更多样板代码,尽管有人认为它能更简单清晰地支持多种类型和设备。在 PyTorch 中,你只需要简单地为每个 CPU 和 GPU 版本写一个接口和对应实现即可。这两种框架对扩展的编译都很直接,不需要下载 pip 安装之外的任何头文件或源代码。
TensorFlow是一个非常强大非常成熟的深度学习库,具有非常强大的可视化功能,以及有多个可供选择的框架来进行高级模型开发。它具有用于生产的部署选项,以及对移动平台的支持。
PyTorch仍然是一个年轻的框架,但其发展速度越来越快。它可能会比较适合: