TensorFlow有哪些令人難以接受的地方?

TensorFlow可謂當前最火的深度學習框架,由於谷歌爸爸的背書而受到無與倫比的讚譽和信任,網上各種教程帖、安利帖不知幾何,連Facebook背書的PyTorch都難以撼其鋒芒,更不要說無人疼愛的其他深度學習框架。底層引擎設計優良的MXNet就算被亞馬遜收養了,其知名度和流行度也在TensorFlow這個網紅面前撐不過一個回合。

但是沒有工具是完美的,TensorFlow亦然,現在是時候來吐槽一下了:

- 在設計理念、日常使用上,TensorFlow有什麼讓你感到難以接受的地方?

- 如果不得不使用TensorFlow的話,可以用什麼更加優雅的方法來繞過原本的設計缺陷?

- 有什麼別的更好的工具可以用來替代TensorFlow某些設計不良的模塊?

- 其他深度學習框架在同樣的問題上有什麼更加高明的做法?

相關問題:如何評價余凱在朋友圈發表呼籲大家用caffe, mxnet等框架,避免使用TensorFlow?


更新:我孤陋寡聞了,原來pytorch也有這個神器,就是tensorboardX,連動態圖都能畫,這下子又少了一個堅守tf的理由了


賈大神已經出來講話了,我這個答案大家就當一個菜鳥的吐槽貼就好

-----------------------------------------

難道不是亂嗎?不光是文檔亂,代碼結構和api功能也是亂得一塌糊塗。

都說mxnet文檔殘廢,我個人體驗卻覺得Tensorflow的官方文檔也是半斤八兩。雖說Tensorflow的確是當下最熱門的深度學習框架,但它肯定算不上是最新手友好、容易上手的框架。就例如我現在進入官網,自然地點入Get started,展示在我面前的是四個標籤:

好,那我們就從GET STARTED開始學習,一看左側的標籤:

嗯?我看完前三個教程才發現,為什麼同一個mnist要重複講三次呢?這個MNIST For ML Beginners和for Experts好像沒什麼區別啊?不就是多講解了一下minst數據集嗎?而且TensorFlow Mechanics 101怎麼又講了一次建圖訓練模型?然後,我明明是來學搭深度網路的,怎麼又突然來了個tf.contrib.learn這個翻版sklearn的教程?後面講Tensorboard的先不管了,我們翻過來PROGRAMMER"S GUIDE這個標籤:

嗯??剛才不是應該講完了tf計算圖的基本概念了嗎?怎麼又來講Variable和Tensor了?為什麼Threading and Queues 要放在Reading data前面?裡面講的內容不是重疊的嗎?Supervisor和TensorFlow Debugger不是應該放到前面講訓練模型的時候講的嗎?保存載入模型checkpoint不是搭建圖模型的基本操作,應該放到前面講嗎?

再來翻到TUTORIALS:

嗯???怎麼先講了finetune再介紹CNN?而且前面有插了個tf.layers教程又是什麼回事?而且後面怎麼又來了個tf.contrib.learn的教程了?最後面還放了個偏微分方程應用是什麼意思?點進去看這些tutorials也是大多內容與前面的文章部分重複,講得也不夠細緻清晰,很難讓新手有一個完整全面的概念。總體感覺tf的文檔就像是將幾十個不同的工程師各自寫出來的文章拼湊在一起,目錄編排邏輯混亂,不是站在學習者的角度來組織編寫的。當然文檔已經不算最亂的,關於api我也要拿些例子來吐槽一下。

最簡單的例子就是層包裝器,同樣是一個conv2d(),在tf文檔里可以有tf.contrib.keras.layers.Conv2D()、tf.contrib.layers.conv2d()、tf.layers.conv2d(),加上本身的keras.layers.Conv2D(),一個功能可以有幾個api,卻找不到其中區別的解釋。又例如讀取文件可以通過tf.read_file()和tf.WholeFileReader().read()實現。這樣的例子還有很多,不知道google是不是懶得整理這些介面。加上google又喜歡不停地改api,一個seq2seq能先寫成tf.contrib.seq2seq,更新一下又變成tf.contrib.legacy_seq2seq再加個新的seq2seq,有什麼新東西又通通扔到tf.contrib里不加說明。我知道tf更新快是個優點,但這樣每次更新都要擔心自己以前的代碼還能不能跑。而且github上很多開源代碼都不敢直接用,因為很多是基於舊版的tf來寫的,跑之前還要檢查一遍其中調的api有沒有變化。

至於github上的代碼結構混亂就更不用說了,我至今搞不明白tensorflow/tensorflow和tensorflow/models裡面的文件是按什麼邏輯來組織的,有些內容都不應該屬於這個repo。例如tensorflow/models裡面的object detection可以看作一個工具箱,用來實現簡單的目標檢測任務,裡面包含了inception-resnet這樣的模型可供選擇,那為什麼會跟tensorflow/models/resnet這樣的簡單模型demo並列呢?更不用說跟tensorflow/models/slim這種包裝庫並列了,slim不是應該放到tensorflow/tensorflow裡面作為keras一樣的api才對嗎?順便說一句,tf官方文檔里至今沒有slim的api,要用slim還是要去看源碼。

為了證明以上吐槽的合理性,沒有對比就沒有傷害,看看隔壁家PyTorch的Tutorials:

從BEGINNER到ADVANCED循序漸進,從Tensor的基本概念到高級的Neural Style應用包括NLP、RL的應用一步步講解,新手只需要按順序閱讀很快就能掌握PyTorch的基本使用,文末還附帶了Jupyter Notebook可以馬上運行練習。而且人家的docs和example projects也是邏輯清晰結構分明:

可惜tf已經搶佔了先機,大部分社區實現都是基於tf,新手想快速復現模型還是要乖乖用回tf吧。而且PyTorch的確做不了產品,也沒有Tensorboard這種神器。

最後在這裡推薦各位一門神課:

Tensorflow for Deep Learning Research

斯坦福今年一月才新開的一門課程,專講Tensorflow應用,從最基礎的圖概念到高階的Seq2Seq和RL一應俱全,還有一堆示例代碼和幾個作業項目,足夠熟練掌握tensorflow的大部分應用場景。視頻課程在youtube上有但是不完整Stanford CS20SI - TensorFlow,建議直接讀slides和note。我當時沒有看視頻只是將slides全部讀完都已經大呼過癮,如果早知道有這門課就不用在那坑爹的官方文檔上浪費那麼多時間了。簡單來說Tensorflow的官方文檔適合當成字典來查閱,要學習還是要通過課程循序漸進。

祝各位使用tensorflow愉快[微笑]


上來給TF說句公道話:TF是目前唯一一個在核心設計層面上支持dynamic control flow的框架,也是極少幾個經歷大規模多應用部署考驗的的框架之一。

很多人感覺其他框架好的理由,是它們繞開了實際應用中的限制條件。比如說imperative mode做control flow,很多框架其實並不是自己做control flow,而是利用python來做,框架自己只記錄一個static graph。這樣的缺點是你沒法部署到真正核心的產品裡面,一旦要部署,就必須回到static graph去 - 很多產品,比如大規模推薦系統和移動端,是不可能用python的,overhead太大。

所以@吳育昕說得對,要寫好的解決方案,哪個框架都要很小心才行。TF的確難,但是它給你提供了真正可以產品化的可能性。對了,當年誰說我是專業TF黑來著?

要相信Jeff Dean大神的眼光還是很不錯的,很多問題只看見一棵樹的時候簡單,看見森林的時候,解決方法就不一樣了。

(有同學說最後夾帶廣告了,所以這一部分我就刪掉啦)


自問自答一下,拋磚引玉。

1.默認佔用所有GPU的所有內存,非常噁心,難道我們每個人都像谷歌一樣有一堆GPU可以用嗎?

解決方案:首先是限制tf只能訪問一部分GPU:

import os
os.environ[『CUDA_VISIBLE_DEVICE』] = 『1,2"

其次是限制在每個可用GPU上佔據需要使用的內存大小:

gpu_options = tf.GPUOptions(allow_growth=True)
sess = tf.Session(config=tf.ConfigProto(gpu_options=gpu_options))

2.明明有默認的python庫argparse可以用,偏偏在很多tf示例代碼中使用tf.app.flags這種東西,總覺得被綁架了,事無巨細都要去使用它的模塊,即使明明有其他更通用的模塊能用。

3.底層介面寫起來繁瑣,高層介面又不靈活,而且tf的高層封裝太多太亂了。相比之下,PyTorch根本就不需要高層封裝,直接用底層介面來寫就已經很清爽了。

4.速度慢。

5.作為靜態圖框架,調試困難。是的,我知道有一個tfdbg工具可以調試,但是如果是用PyTorch這樣的動態框架的話,就不需要多學一個額外的工具,只需要用正常的Python調試工具如ipdb就可以了。PyTorch配合ipdb可以很方便地在出問題的代碼行插一個斷點,執行到斷點處停止,並進入iPython環境,可以互動式地列印出執行到那行代碼的時候各個Tensor的形狀、數值等信息,調試起來超級方便。

6.想到更多再繼續加。


簡單吐個槽:

Tensorflow繼承了Theano的一大堆缺點,並且在此之上更加喪心病狂地把自己發展成了一個新的編程語言,從底層到頂層做了個遍

慢、亂、封裝多、分散式渣渣、實際投入使用成本高。。。等等。

TF現在只是生態太成熟了,大而全,使得大部分人很難繞開。

PyTorch多清爽,MXNet多快。


在 glibc 版本較低的系統(如 CentOS)上安裝困難。


8.17.2017更新,生日快樂

想跑別人0.12的代碼,在改,已瘋。

翻api的時候看到了beamsearchdecoder。你屌行了吧。

--------------------

Beam search.......有人好像說過了。。。

但是beam search真的是非常不和諧。

1. 每一個time step都要session run,因為排序,剪枝的什麼都得在python端做的

2. 同時,states需要根據排序,剪枝的結果進行修改,所以每個time step都要從graph中拿出來,然後下一個time step再輸入。

最蛋疼的是,states是一個tuple的list(比如說多層lstm), 你不能直接從session中fetch和feed。。。。。於是圖裡面就得有concat(為了從圖中輸出的時候)和split(為了處理python端的輸入)。

3. 時間問題,由於states出來都是cpu numpy array啊,是不是莫名其妙浪費了一點時間在gpu轉cpu,cpu轉gpu,雖然可能沒多少時間

我其實很好奇他們在部署的時候到底會不會做beam search。。。。。。還是重新寫了c++的gpu beam search。

但是至少tf官方的im2txt裡面的beam search就是這麼做的。講道理,有沒有更優雅的方法。


據說不久之後Tensorflow 就會有一個eager模式,寫法基本跟Pytorch一樣,沒有session,可以用while等Python語法直接控制邏輯等功能。


大概是我有時候發現內置的函數行為不太符合我的需求時,想在原函數上重構的難度大到感覺用python無法解決,以ops結尾的文件讓我想起了用caffe時被c++統治的恐懼。
不過要是做開源,我覺得挺好,用我者活,改我者掛


繁瑣,冗餘,很多的api更新或者丟棄

還有就是上面提到的同樣功能比如訓練,有太多可調用的函數和方法

相比之下,Pytorch是真簡潔,可惜出來的太晚了


把Python的框架寫成了c++


1、顯存佔用高,這裡的高和GPU顯存佔用設置沒關係

2、版本亂、版本之間的兼容性問題大

3、API文檔簡直廢物一般


其實繁瑣,自由度太高不是TF自己的鍋啊...
TF的官方定義是:An open source software library for machine intelligence,突出和強調的是一個library,也就是說儘可能的功能小而全,類似提供了一個分散式高性能函數庫,用來做深度學習只是目前最流行的一個方向而已,你大可用它來進行其他高性能分散式計算。
而pytorch的定義就是deep learning framework,顯然用來寫深度學習的模型比TF方便,這是一個更專門化的framework,而不是library,更不是用於通用計算的library。
因此,我覺得TF目前廣受詬病的這些缺點,恰恰是因為一開始野心大,定位高和現在開發還不是那麼完美的矛盾,而這些隨著時間是可以預見被解決的。因此我認為這和從一開始定位狹隘相比,反而是優點。


1,寫起來像八股文
2,函數介面雜亂
3,調試麻煩
4,寫動態結構麻煩
5,control dependency反人類


祝TFboy們使用愉快。
(隔壁facebook某工具,不知高到哪裡去了)


1、tensor張量轉numpy很麻煩(一直打算寫篇博客梳理一下……拖了好久的總算總結了一下TensorFlow 之 tensor轉numpy

2、程序默認佔滿所有GPU,需要手動設置(為此還專門寫了一篇博客,甩個鏈接http://rootlu.com/blog/2017/05/28/GPUSetup.html/)

3、DEBUG過程很艱難……

4、文檔好亂啊,真不想看


我沒用過 pytorch,對 tf 略有研究。我不太清楚 pytorch 實現 mcmc 採樣十輪然後再接一個什麼運算好不好寫,反正我用 tf.while_loop 很爽。

我認為用 tf 用的爽得先有自己順手的輪子,不必像 keras 那麼大,努力把核心的 daily routine 封裝起來就行。比如我自己的輪子 https://github.com/korepwx/tfsnippet ,包括 train loop, component style variable reuse 還有一些貝葉斯的東西。在 pytorch 顯示出壓倒性優勢之前,我還會 stick to my wheel over tf


tensor和numpy array不能轉換,非常麻煩

用習慣以後人會變得越來越抖m

版本更新以後很多東西不兼容了


pytorch天天有人安利。但是api社區文檔examples,又有多少人在維護?


目前用過的要說體驗最好的其實是PyTorch和Chainner。TF偏低層是個問題,無形加大工作量,但是也還算靈活,但是TF眼見著要來做高一層的封裝了,海納百川式地引入高級封裝就比較蛋疼了。

TF目前的版本里打包了的高級封裝至少包含keras、tflearn、tflayers(經提示還有tfslim),這三個玩意一起揉進去,有的在contrib里,有的直接在一級的包里(比如tf.layers),各自之間還並不太配合,文檔一塌糊塗,不好找不說,用起來也不太完整,到頭來還得自己做。

然而有些東西(比如batch_norm),自己做嫌麻煩,用高級封裝也混亂,繞了一圈回來的經歷不要太少。說到底最後這堆亂七八糟的高級封裝意義實在坑。

唔不過至少C++庫做Python wrap的時候多少把參數表給包了一下,像rope以及各大IDE多少能給點兒填參數的提示和補全,就憑這一點就碾過mxnet了……


C++部署支持太弱了,頭文件需要到處拼湊,各種C++介面文檔太少。目前正在考慮TensorFlow訓練模型,換個框架部署的方式。


tensorflow太過底層。

好處是足夠的靈活你可以任意搞你想要的各種事情。

壞處是在沒有高層封裝的情況下構建一個可運行的網路要費勁不少。所以導致了tf的高層封裝層出不窮,但是又太過於琳琅滿目,也沒有哪家說做的足夠好,難以選擇。

-------
當然了目前情況下tensorflow還是我的第一選擇,因為也沒啥可選的。pytorch和mxnet也都有其不方便的地方使得我不會就這麼拋棄tensorflow。


推薦閱讀:

pattern recognition and machine learning這本書怎麼看?
國內做計算機視覺或者機器學習比較好的實驗室有哪些?
BRETT 機器人算有「學習」的能力么?
「社交網路分析」是門怎樣的學科?
機器學習有很多關於核函數的說法,核函數的定義和作用是什麼?

TAG:機器學習 | 谷歌 (Google) | 深度學習(Deep Learning) | TensorFlow |