先来回答一下你提的几个问题:Pytorch连最基本的maximum, minimum, tile等等这些numpy和tensorflow中最简单的运算都没有,用view来reshape还会报错contiguous(虽然我知道怎么解决),官方手册也查不到相应说明,这个东西到底好用在哪里?
你说的那几个函数pytorch中都有(或者可以实现)maximum: torch.max() 同时包含了numpy.max 和numpy.maximum的功能
minimum:torch.min()
np.tile(arr,(100,100)) 等价于 tensor.repeat(100,100)
contiguous的问题我经常听别人提问,但我从未遇到过(我几乎从未调用过`tensor.contiguous()`),大多数人也很少会把tensor弄成不连续。之所以tensor会不连续,是为了能够共享内存,更高效的内存利用(其实只要PyTorch在设计的时候把所有的不连续操作都返回一个连续的tensor即可解决这个问题,但是不值得,大多数不连续的tensor都会进行一个reduce操作,然后就变成了连续的了)。
numpy那么多函数,PyTorch不可能都支持,即使不支持,也可以在numpy中实现,然后转成tensor,毕竟numpy和tensor之间的转换极其高效快速(他们共享内存).这个东西到底好用在哪里?
还是说就是定义网络结构简单?
PyTorch到底好在哪,其实我也只是有个朦胧的感觉,总觉的用的舒服自在,用其它框架的时候总是觉得这里或者那里别扭。第一次用PyTorch几乎是无痛上手,而且随着使用的增加,更是越来越喜欢:
PyTorch不仅仅是定义网络结构简单,而且还很直观灵活。静态图的网络定义都是声明式的,而动态图可以随意的调用函数(if,for,list什么的随便用),两者的差距不是一点点。网络的定义在任何框架中都应该是属于最基础最简单的一个内容,即使是接口繁多的tensorflow,通过不断的查文档,新手也能把模型搭起来或者是看懂别人的模型。这个PyTorch也不例外,它的优势在于模型定义十分直观易懂,很容易看懂看别人写的代码。可以看看pytorch/vision 里面的几个经典的网络定义,我觉得很难找到比它更简洁易懂的模型定义了。
网络模型定义只是很基础的一部分,更重要的是模型的使用。比如在使用预训练模型finetue时,我们需要修改预训练模型某些层,新增某些层,删除某些层,新增的层希望给他较高的学习率,之前预训练的层希望学习率设为0。scene-baseline 是我前几天为AI challenger 场景分类写的baseline,可以参考一下,只用了几行代码就实现了预训练模型finetune(新增某些层,删除某些层,修改某些层),以及为不同层设置不同学习率 scene-baseline-optimizer 。
再比如在尽可能不修改原来模型源代码的情况下,获取预训练好模型的某些层的输出(Fast Neural Style需要用到),或者是使用多个预训练好的子模型,分别初始化一个复杂模型的某一部分,因为子模型的结构都是相似的,所以可以让这些子模型共享某些层的参数(知乎看山杯我就用了这个策略。表述的可能很复杂,其实在模型的构建只用了几行)
谈太多框架的使用,可能比较枯燥,只有你自己用了才知道,PyTorch真的是越用越顺手。
下面说几点其它的看法,没有什么条理,不论证举例,只说想法,只是个人看法,不必太认真:
1.PyTorch比TF更符合Unix/Python哲学
Unix哲学:做一件事,并把它做好。(真的要在做实验的时候考虑如何把模型部署到手机,利用TPU加速?)
Unix哲学:KISS(keep it simple, stupid)。github上TF有接近100万行代码,PyTorch只有它的十分之一多一点。TensorFlow创造了 图、会话、命名空间、PlaceHolder 等一大堆全新的概念,简直就是一门新的语言。TensorFlow是Make It Complicated ,TensorFlow+Keras是Make It Complicated And Hide It。而Keras的Hide it又违反了Python的哲学(扁平胜于嵌套 ),丧失了灵活性。而PyTorch就是tensor-autograd-nn 三级封装~ 简洁易懂
Python之禅:尽量找一种,最好是唯一一种直观易懂的实现方案(猜猜TF中RNN有多少种实现,猜猜除了Keras、Sonnet、TFLearn、TensorLayer、Slim、PrettyLayer之外tensorflow还有多少个第三方API )。PyTorch的不同人写的代码都差不多,很容易看懂。The Zen of Python, by Tim Peters
优美胜于丑陋
明了胜于晦涩
简洁胜于复杂 复杂胜于凌乱
扁平胜于嵌套
间隔胜于紧凑
可读性很重要
即便假借特例的实用性之名,也不可违背这些规则
不要包容所有错误,除非你确定需要这样做
当存在多种可能,不要尝试去猜测
而是尽量找一种,最好是唯一一种直观易懂的实现方案虽然这并不容易,因为你不是 Python 之父
做也许好过不做,但不假思索就动手还不如不做
如果你很难向人描述你的实现,那肯定不是一个好实现命名空间是一种绝妙的理念,我们应当多加利用
如果你很难向人描述你的实现,那肯定不是一个好实现
2.快速
在大多数人写的代码中PyTorch都比TensorFlow快,并不是说TensorFlow慢,只是你要用TensorFlow写出同等速度的代码会稍微困难一些(单单是数据加载这一块就会难倒许多人)
3.强大的社区
facebook的FAIR强力支持,FAIR是全球TOP3的AI研究机构。PyTorch论坛,文档,tutorial,一应俱全。FAIR的几位工程师更是全职维护开发,github上PyTorch每天都有许多pull request和讨论。
你很难听到有谁说TF好用,最多是诸如谷歌支持,社区强大,文档完善,功能齐全等等。但是PyTorch你只要深度用过一段时间,就会喜欢上它的。很多人自来水安利PyTorch,当然不是facebook给钱,或者是博得多少点击量,真的是因为它太好用了。
其实关于TensorFlow还有一点让我颇为不满的是,现在媒体总是觉得谷歌的东西就是最好的,每回TensorFlow有什么更新,都要搞个大新闻。而且,谷歌喜欢把一个项目的目标当成这个项目的特点来宣传,但是TensorFlow的实际表现,配不上它的名气。
4.简洁易懂的代码
一个框架你不懂源码,你就不能完全掌握它的运行原理,像tensorflow的`sess.run`简直就是个黑箱。而PyTorch几乎是我用过框架中源码最易懂的,任何一个操作,不论多么高级复杂,都能轻松的找到它对应tensor操作(Caffe/tinydnn也挺简洁的,但是我的C++比较渣)
nn.Module代码是PyTorch中对所有模型对象的封装,我觉得几乎所有人都应该看看,深度学习框架的设计可以很简单!现在Gluon,Sonnet,nnabla等框架也都开始模仿这个设计api~
5.快速实现
深度学习炼丹的过程中,我们肯定都有许多奇思妙想,但这些奇思妙想需要做实验来验证。如果实现比较困难费时,在不确定这个想法是否有效的情况下,我们很容易打退堂鼓。PyTorch可以解放你的想法,用tensor的思维思考代码,一切操作皆tensor,一切tensor能做的,PyTorch都能做到,而且做的像操作tensor一样。
用TensorFlow 我能找到很多别人的代码
用PyTorch 我能轻松实现自己的想法
而且github上很多tensorflow的代码也不能跑了不是吗?毕竟TF常年一步一大更新,不怎么考虑向后兼容。随着同学的更新TF,我眼睁睁看的我的TF代码从运行正常,到警告,到报错
PyTorch实现的项目在github上也有很多,不是吗?基本上所有的研究方向都能找到质量很高的PyTorch开源方案。
6.关于PyTorch的几个误解
PyTorch社区不强大 ?:看上文
PyTorch 文档不齐全?:我觉得PyTorch的文档几乎是所有框架中最好的,这些文档都是作者在设计的时候就写好的,不是别人看着代码,凭借着自己理解写的。 而且PyTorch文档中的给出了很多示例,在IPython下可以直接拷贝运行,做实验测试。
PyTorch中没有TensorBoard? lanpa/tensorboard-pytorch 不仅功能强大(支持Tensorboard几乎所有的操作,连计算图都支持,只是显示效果不好),而且接口简单(比tf的tensorboard api易用)。而且除了Tensorboard还有Visdom可以用~
PyTorch动态图性能比较差?见上文,同等水平的人用PyTorch写出来的代码普遍要比TensorFlow快。当然我认为极限情况下TensorFlow会比PyTorch快,详情可以看TensorFlow官方的benchmark,只是写的代码很复杂,普通用户写不出来。
总感觉表述有点匮乏,表达也不是很流畅,还有很多没表达出来的。可以看看其他人是怎么说的:
PyTorch和TensorFlow到底哪个更好?看看一线开发者怎么说 (帖子是3月份初发的,这时候PyTorch才发布一个多月,但几乎所有用过的人已经都在夸赞)