静态图 VS 动态图

现在的深度学习平台在定义模型的时候主要用两种方式:static computation graph(静态图模型) 和 dynamic computation graph(动态图模型)

静态图:TensorFlow, Theano, Caffe,Keras等。
动态图:PyTorch, Chainer, Dynet,TensorFlow Fold

部署:静态。为什么?

imperative mode做control flow,很多框架其实并不是自己做control flow,而是利用python来做,框架自己只记录一个static graph。这样的缺点是你没法部署到真正核心的产品里面,一旦要部署,就必须回到static graph去 - 很多产品,比如大规模推荐系统和移动端,是不可能用python的,overhead太大。

pytorch更容易重构函数,但是如果需要部署的话就还是得像TF或者其他一些框架一样老老实实做dirty work。

其实是抽象程度和可控程度之间的balance,

控制流真的在产品中很关键吗?因为控制流会影响整个内存的预测和建图,对性能还是有伤害的吧?真的需要性能直接通过C++接口的话会不会overhead可以接受一点?
答:的确对于性能会有影响。比如说在手机端C2的策略是完全不用dispatcher和动态内存,一切都静态分配。不过在比较复杂的网络情况下,真要控制流的话还是需要有一定tradeoff的。
另外实际应用中的确控制流用到的不多。

作者:贾扬清
链接:https://www.zhihu.com/question/63342728/answer/208898814
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

静态图定义的缺陷是在处理数据前必须定义好完整的一套模型,能够处理所有的边际情况。比如在声明模型前必须知道整个数据中句子的最大长度。相反动态图模型(现有的平台比如PyTorch, Chainer, Dynet)能够非常自由的定义模型。举个例子,传统的LSTM往往处理一个句子的时候都是以word为单位,然后利用word2vec来初始化词向量。但是往往有一些很奇怪的词在vocabulary里是找不到的,也就是没法用word2vec初始化词向量。这时候你可能想用characer-level(字符)级别的表示来初始化那个单词,就需要借助动态图模型的定义了。简单来说动态图模型允许你在运行程序的时候动态去修正你的模型结构,来处理各种奇奇怪怪的边角输入,这在学术研究的时候的灵活性就体现出来了。

静态图需要在处理数据前定义好一套完整的模型;而动态图模型允许用户先定义好一套基本的框架再根据数据来实时修正模型。

能不能用指针形容一下动态和静态实现的区别?

tensorflow中的动态图

dynamic_rnn

dynamic-rnn可以允许不同batch的sequence length不同。
是否允许同一个batch内的sequence length不同?

  • 是动态图实现的?还是模拟的动态图?
  • dynamic-rnn到达sequence length之后终止计算吗?
    • 超出序列长度 seq_len,就复制 zero output 和之前的 state 到下一个时间步。避免了padding污染
  • 能batch training吗?
  • 跟普通rnn比较,会变慢吗?还是更快?
  • 推荐用普通rnn还是动态rnn?

为了得到没有padding污染的hidden state(LSTM,GRU会倾向于记住更多后面的信息,padding会对前向RNN的final state产生负面影响),需要传入sequence被pad前的长度;而为了加快计算速度,还是需要对整个数据集根据长度做bucketing。

https://www.zhihu.com/question/52200883/answer/208377796

Is padding necessary for LSTM network?