問耕 編譯整理 量子位 出品 | 公眾號(hào) QbitAI前幾天,量子位發(fā)過一篇《忽悠VC指南》。其中有一條建議是,當(dāng)你假裝AI專家時(shí),最好別談眾人皆知的TensorFlow,那談什么? PyTorch。 其實(shí)這也不全然都是調(diào)侃。和TensorFlow相比,PyTorch確實(shí)也有為數(shù)不少的擁躉。根據(jù)Keras作者Fran?ois Chollet發(fā)布的數(shù)據(jù)顯示:GitHub上的各種深度學(xué)習(xí)框架中,PyTorch排在第五位。 但需要提醒大家的是,PyTorch可是今年1月19日才正式發(fā)布。 △ 二季度深度學(xué)習(xí)框架排名最近,斯坦福大學(xué)研究機(jī)器學(xué)習(xí)的博士生Awni Hannun,圍繞PyTorch還是TensorFlow這個(gè)話題,做了一個(gè)深入的比較。量子位把內(nèi)容傳送如下: 我寫的這份指南,主要對(duì)比了PyTorch和TensorFlow之間的區(qū)別。希望對(duì)那些想著手開始一個(gè)新項(xiàng)目或者考慮轉(zhuǎn)換深度學(xué)習(xí)框架的人有所幫助。 我主要考察了深度學(xué)習(xí)堆棧的訓(xùn)練和部署時(shí),相關(guān)的可編程性和靈活性。在這里,我不會(huì)過多的談?wù)撍俣?、?nèi)存占用等方面的權(quán)衡。 先放結(jié)論PyTorch更有利于研究人員、愛好者、小規(guī)模項(xiàng)目等快速搞出原型。而TensorFlow更適合大規(guī)模部署,特別是需要跨平臺(tái)和嵌入式部署時(shí)。 然后咱們一項(xiàng)一項(xiàng)分著說。 上手時(shí)間 贏家:PyTorch PyTorch本質(zhì)上是Numpy的替代者,而且支持GPU、帶有高級(jí)功能,可以用來搭建和訓(xùn)練深度神經(jīng)網(wǎng)絡(luò)。如果你熟悉Numpy、Python以及常見的深度學(xué)習(xí)概念(卷積層、循環(huán)層、SGD等),會(huì)非常容易上手PyTorch。 而TensorFlow可以看成是一個(gè)嵌入Python的編程語言。你寫的TensorFlow代碼會(huì)被Python編譯成一張圖,然后由TensorFlow執(zhí)行引擎運(yùn)行。我見過好多新手,因?yàn)檫@個(gè)增加的間接層而困擾。也正是因?yàn)橥瑯拥脑?,TensorFlow有一些額外的概念需要學(xué)習(xí),例如會(huì)話、圖、變量作用域(variable scoping)、占位符等。 另外還需要更多的樣板代碼才能讓一個(gè)基本的模型運(yùn)行。所以TensorFlow的上手時(shí)間,肯定要比PyTorch長。 圖創(chuàng)建和調(diào)試贏家:PyTorch 創(chuàng)建和運(yùn)行計(jì)算圖可能是兩個(gè)框架最不同的地方。在PyTorch中,圖結(jié)構(gòu)是動(dòng)態(tài)的,這意味著圖在運(yùn)行時(shí)構(gòu)建。而在TensorFlow中,圖結(jié)構(gòu)是靜態(tài)的,這意味著圖先被“編譯”然后再運(yùn)行。 舉一個(gè)簡單的例子,在PyTorch中你可以用標(biāo)準(zhǔn)的Python語法編寫一個(gè)for循環(huán)結(jié)構(gòu) for _ in range(T): h = torch.matmul(W, h) + b 此處T可以在每次執(zhí)行代碼時(shí)改變。而TensorFlow中,這需要使用“控制流操作”來構(gòu)建圖,例如tf.while_loop。TensorFlow確實(shí)提供了dynamic_rnn用于常見結(jié)構(gòu),但是創(chuàng)建自定義動(dòng)態(tài)計(jì)算真的更加困難。 PyTorch中簡單的圖結(jié)構(gòu)更容易理解,更重要的是,還更容易調(diào)試。調(diào)試PyTorch代碼就像調(diào)試Python代碼一樣。你可以使用pdb并在任何地方設(shè)置斷點(diǎn)。調(diào)試TensorFlow代碼可不容易。要么得從會(huì)話請(qǐng)求要檢查的變量,要么學(xué)會(huì)使用TensorFlow的調(diào)試器(tfdbg)。 播放GIF 贏家:TensorFlow 隨著PyTorch逐漸成熟,我預(yù)計(jì)這部分的差距會(huì)趨近于零。但目前,TensorFlow還是有一些PyTorch不支持的功能。它們是: 沿維翻轉(zhuǎn)張量(np.flip, np.flipud, np.fliplr) 檢查無窮與非數(shù)值張量(np.is_nan, np.is_inf) 快速傅里葉變換(np.fft)
這些TensorFlow都支持。另外,TensorFlow的contrib軟件包中,有更多PyTorch沒有的高級(jí)功能和模型。 序列化贏家:TensorFlow 兩種框架下保存和加載模型都很簡單。PyTorch有一個(gè)特別簡單的API,可以保存模型的所有權(quán)重或pickle整個(gè)類。TensorFlow的Saver對(duì)象也很易用,而且為檢查提供了更多的選項(xiàng)。 TensorFlow序列化的主要優(yōu)點(diǎn)是可以將整個(gè)圖保存為protocol buffer。包括參數(shù)和操作。然而圖還能被加載進(jìn)其他支持的語言(C++、Java)。這對(duì)于部署堆棧至關(guān)重要。理論上,當(dāng)你想改動(dòng)模型源代碼但仍希望運(yùn)行舊模型時(shí)非常有用。 部署贏家:TensorFlow 對(duì)于小規(guī)模的服務(wù)器端部署(例如一個(gè)Flask web server),兩個(gè)框架都很簡單。 對(duì)于移動(dòng)端和嵌入式部署,TensorFlow更好。不只是比PyTorch好,比大多數(shù)深度學(xué)習(xí)框架都要要。使用TensorFlow,部署在Android或iOS平臺(tái)時(shí)只需要很小的工作量,至少不必用Java或者C++重寫模型的推斷部分。 對(duì)于高性能服務(wù)器端的部署,還有TensorFlow Serving能用。除了性能之外,TensorFlow Serving一個(gè)顯著的優(yōu)點(diǎn)是可以輕松的熱插拔模型,而不會(huì)使服務(wù)失效。 文檔贏家:平手 對(duì)于兩個(gè)框架,我都在文檔中找到所需的一切。Python API被很好的記錄,以及有足夠的案例和教程來學(xué)習(xí)框架。 一個(gè)特例是,PyTorch的C庫大多數(shù)沒有文檔。不過,這只有在你編寫一個(gè)定制化的C擴(kuò)展時(shí)才有影響。 數(shù)據(jù)加載贏家:PyTorch PyTorch中用于加載數(shù)據(jù)的API設(shè)計(jì)的很棒。接口由一個(gè)數(shù)據(jù)集、一個(gè)取樣器和一個(gè)數(shù)據(jù)加載器構(gòu)成。數(shù)據(jù)加載器根據(jù)取樣器的計(jì)劃,基于數(shù)據(jù)集產(chǎn)生一個(gè)迭代器。并行化數(shù)據(jù)加載簡單的就像把num_workers參數(shù)傳遞給數(shù)據(jù)加載器一樣簡單。 我在TensorFlow中沒有發(fā)現(xiàn)特別有用的數(shù)據(jù)加載工具。很多時(shí)候,并不總能直接把準(zhǔn)備并行運(yùn)行的預(yù)處理代碼加入TensorFlow圖。以及API本身冗長難學(xué)。 設(shè)備管理贏家:TensorFlow TensorFlow的設(shè)備管理非常好用。通常你不需要進(jìn)行調(diào)整,因?yàn)槟J(rèn)的設(shè)置就很好。例如,TensorFlow會(huì)假設(shè)你想運(yùn)行在GPU上(如果有的話)。而在PyTorch中,即使啟用了CUDA,你也需要明確把一切移入設(shè)備。 TensorFlow設(shè)備管理唯一的缺點(diǎn)是,默認(rèn)情況下,它會(huì)占用所有的GPU顯存。簡單的解決辦法是指定CUDA_VISIBLE_DEVICES。有時(shí)候大家會(huì)忘了這一點(diǎn),所以GPU在空閑的時(shí)候,也會(huì)顯得很忙。 在PyTorch中,我發(fā)現(xiàn)代碼需要更頻繁的檢查CUDA是否可用,以及更明確的設(shè)備管理。在編寫能夠同時(shí)在CPU和GPU上運(yùn)行的代碼時(shí)尤其如此。以及得把GPU上的PyTorch變量轉(zhuǎn)換為Numpy數(shù)組,這就顯得有點(diǎn)冗長。 numpy_var = variable.cpu.data.numpy 自定義擴(kuò)展贏家:PyTorch 兩個(gè)框架都可以構(gòu)建和綁定用C、C++、CUDA編寫的自定義擴(kuò)展。TensorFlow仍然需要更多的樣板代碼,盡管這對(duì)于支持多類型和設(shè)備可能更好。在PyTorch中,你只需為每個(gè)CPU和GPU編寫一個(gè)接口和相應(yīng)的實(shí)現(xiàn)。兩個(gè)框架中編譯擴(kuò)展也是直接記性,并不需要在pip安裝的內(nèi)容之外下載任何頭文件或者源代碼。 關(guān)于TensorBoardTensorBoard是TensorFlow自帶的可視化工具,用來查看機(jī)器學(xué)習(xí)訓(xùn)練過程中數(shù)據(jù)的變化。通過訓(xùn)練腳本中的幾個(gè)代碼段,你可以查看任何模型的訓(xùn)練曲線和驗(yàn)證結(jié)果。TensorBoard作為web服務(wù)運(yùn)行,特別便于對(duì)于無頭結(jié)點(diǎn)上存儲(chǔ)的結(jié)果進(jìn)行可視化。 如果沒有類似的功能,我可不想用PyTorch。不過還好,借助兩個(gè)開源項(xiàng)目可以實(shí)現(xiàn)。第一個(gè)是tensorboard_logger,第二個(gè)是crayon。tensorboard_logger庫用起來甚至比TensorBoard的“摘要”更容易,盡管想用這個(gè)首先得安裝TensorBoard。 crayon可以完全替代TensorBoard,但是需要更多的設(shè)置(docker是先決條件)。 關(guān)于KerasKeras是具有可配置后端的高級(jí)API。目前TensorFlow、Theano、CNTK都支持。也許不久的將來,PyTorch也會(huì)提供支持。作為tf.contrib的一部分,Keras也隨TensorFlow一起分發(fā)。 雖然上面我沒有討論過Keras,但其API特別容易使用,這也是配合常見深度神經(jīng)網(wǎng)絡(luò)架構(gòu)最快的方式。不過,使用API畢竟沒有使用PyTorch或者核心TensorFlow那么靈活。 Keras是許多常用的深層神經(jīng)網(wǎng)絡(luò)架構(gòu)中運(yùn)行最快的方法之一。 關(guān)于TensorFlow Fold今年2月,谷歌推出了TensorFlow Fold。這個(gè)庫建立在TensorFlow智商,允許構(gòu)建更多的動(dòng)態(tài)圖。這個(gè)庫的主要優(yōu)勢是動(dòng)態(tài)批處理。動(dòng)態(tài)批處理可以自動(dòng)對(duì)不同大小的輸入進(jìn)行批量計(jì)算(例如解析樹上的循環(huán)網(wǎng)絡(luò))。 可編程性方面,語法不像PyTorch那么簡單,當(dāng)然在某些情況下,批處理帶來的性能提升還是值得考慮。 好了,以上就是來自Awni Hannun的分享。希望對(duì)大家有所幫助,另外兼聽則明,量子位繼續(xù)搬運(yùn)幾條reddit上讀者的評(píng)論。 讀者Reiinakano: 我不覺得“文檔”環(huán)節(jié)雙方平分秋色。 官方的TensorFlow文檔很差勁。比方,在PyTorch文檔中,對(duì)于遷移學(xué)習(xí)的講解,使用了實(shí)際、有用的代碼,而且還解釋了構(gòu)建的方式。而在TensorFlow的文旦中,整個(gè)講解就是運(yùn)行了一個(gè)bash scripts,沒有任何實(shí)際代碼。
讀者ThaHypnotoad: PyTorch還有很長的路要走。前幾天我發(fā)現(xiàn)int tensor沒有neg定義。不過,我更討厭調(diào)試靜態(tài)圖。所以我選擇忍受PyTorch成長的煩惱。
讀者trias10: 另一個(gè)缺點(diǎn)是,PyTorch沒有對(duì)Windows的官方支持,而TensorFlow有。很多場合(通常是金融和保險(xiǎn)行業(yè))使用Windows進(jìn)行開發(fā)和原型設(shè)計(jì),用Linux進(jìn)行生產(chǎn)部署,所以你需要一個(gè)能對(duì)兩者都支持的框架。
好啦,今天先談到這里。希望對(duì)你有所幫助~ 量子位AI社群7群開始招募啦,歡迎對(duì)AI感興趣的同學(xué),加小助手微信qbitbot2入群; 此外,量子位專業(yè)細(xì)分群(自動(dòng)駕駛、CV、NLP、機(jī)器學(xué)習(xí)等)正在招募,面向正在從事相關(guān)領(lǐng)域的工程師及研究人員。 量子位正在招募編輯/記者,工作地點(diǎn)在北京中關(guān)村。期待有才氣、有熱情的同學(xué)加入我們!相關(guān)細(xì)節(jié),)對(duì)話界面,回復(fù)“招聘”兩個(gè)字。 ?'?' ? 追蹤AI技術(shù)和產(chǎn)品新動(dòng)態(tài)
|