如何快速了解一個深度學習框架?抓住這五大核心組件

      網友投稿 820 2022-05-29

      許多初學者覺得深度學習框架抽象,雖然調用了幾個函數/方法,計算了幾個數學難題,但始終不能理解這些框架的全貌。

      為了更好地認識深度學習框架,也為了給一些想要自己親手搭建深度學習框架的朋友提供一些基礎性的指導,日前來自蘇黎世聯邦理工學院計算機科學系的碩士研究生Gokula Krishnan Santhanam在博客上撰文,概括了大部分深度學習框架都會包含的五大核心組件,為我們詳細剖析了深度學習框架一般性的內部組織結構。

      如何快速的了解一個深度學習框架?抓住這五大核心組件

      Gokula Krishnan Santhanam認為,大部分深度學習框架都包含以下五個核心組件:

      1. 張量(Tensor) 2. 基于張量的各種操作 3. 計算圖(Computation Graph) 4. 自動微分(Automatic Differentiation)工具 5. BLAS、cuBLAS、cuDNN等拓展包

      1. 張量(Tensor)

      張量是所有深度學習框架中最核心的組件,因為后續的所有運算和優化算法都是基于張量進行的。幾何代數中定義的張量是基于向量和矩陣的推廣,通俗一點理解的話,我們可以將標量視為零階張量,矢量視為一階張量,那么矩陣就是二階張量。

      舉例來說,我們可以將任意一張RGB彩***片表示成一個三階張量(三個維度分別是圖片的高度、寬度和色彩數據)。如下圖所示是一張普通的水果圖片,按照RGB三原色表示,其可以拆分為三張紅色、綠色和藍色的灰度圖片,如果將這種表示方法用張量的形式寫出來,就是圖中最下方的那張表格。

      圖中只顯示了前5行、320列的數據,每個方格代表一個像素點,其中的數據[1.0, 1.0, 1.0]即為顏色。假設用[1.0, 0, 0]表示紅色,[0, 1.0, 0]表示綠色,[0, 0, 1.0]表示藍色,那么如圖所示,前面5行的數據則全是白色。

      將這一定義進行擴展,我們也可以用四階張量表示一個包含多張圖片的數據集,其中的四個維度分別是:圖片在數據集中的編號,圖片高度、寬度,以及色彩數據。

      將各種各樣的數據抽象成張量表示,然后再輸入神經網絡模型進行后續處理是一種非常必要且高效的策略。因為如果沒有這一步驟,我們就需要根據各種不同類型的數據組織形式定義各種不同類型的數據操作,這會浪費大量的開發者精力。更關鍵的是,當數據處理完成后,我們還可以方便地將張量再轉換回想要的格式。例如Python NumPy包中numpy.imread和numpy.imsave兩個方法,分別用來將圖片轉換成張量對象(即代碼中的Tensor對象),和將張量再轉換成圖片保存起來。

      2. 基于張量的各種操作

      有了張量對象之后,下面一步就是一系列針對這一對象的數學運算和處理過程。

      其實,整個神經網絡都可以簡單視為為了達到某種目的,針對輸入張量進行的一系列操作過程。而所謂的“學習”就是不斷糾正神經網絡的實際輸出結果和預期結果之間誤差的過程。這里的一系列操作包含的范圍很寬,可以是簡單的矩陣乘法,也可以是卷積、池化和LSTM等稍復雜的運算。而且各框架支持的張量操作通常也不盡相同,詳細情況可以查看其官方文檔(如下為NumPy、Theano和TensorFlow的說明文檔)。

      NumPy: http://www.scipy-lectures.org/intro/numpy/operations.html

      Theano: http://deeplearning.net/software/theano/library/tensor/basic.html

      TensorFlow: https://www.tensorflow.org/api_docs/python/math_ops/

      需要指出的是,大部分的張量操作都是基于類實現的(而且是抽象類),而并不是函數(這一點可能要歸功于大部分的深度學習框架都是用面向對象的編程語言實現的)。這種實現思路一方面允許開發者將各種類似的操作匯總在一起,方便組織管理。另一方面也保證了整個代碼的復用性、擴展性和對外接口的統一。總體上讓整個框架更靈活和易于擴展,為將來的發展預留了空間。

      3. 計算圖(Computation Graph)

      有了張量和基于張量的各種操作之后,下一步就是將各種操作整合起來,輸出我們需要的結果。

      但不幸的是,隨著操作種類和數量的增多,有可能引發各種意想不到的問題,包括多個操作之間應該并行還是順次執行,如何協同各種不同的底層設備,以及如何避免各種類型的冗余操作等等。這些問題有可能拉低整個深度學習網絡的運行效率或者引入不必要的Bug,而計算圖正是為解決這一問題產生的。

      后來隨著技術的不斷演進,加上腳本語言和低級語言各自不同的特點(概括地說,腳本語言建模方便但執行緩慢,低級語言則正好相反),因此業界逐漸形成了這樣的一種開發框架:前端用Python等腳本語言建模,后端用C++等低級語言執行(這里低級是就應用層而言),以此綜合了兩者的優點。可以看到,這種開發框架大大降低了傳統框架做跨設備計算時的代碼耦合度,也避免了每次后端變動都需要修改前端的維護開銷。而這里,在前端和后端之間起到關鍵耦合作用的就是計算圖。

      將計算圖作為前后端之間的中間表示(Intermediate Representations)可以帶來良好的交互性,開發者可以將Tensor對象作為數據結構,函數/方法作為操作類型,將特定的操作類型應用于特定的數據結構,從而定義出類似MATLAB的強大建模語言。

      需要注意的是,通常情況下開發者不會將用于中間表示得到的計算圖直接用于模型構造,因為這樣的計算圖通常包含了大量的冗余求解目標,也沒有提取共享變量,因而通常都會經過依賴性剪枝、符號融合、內存共享等方法對計算圖進行優化。

      目前,各個框架對于計算圖的實現機制和側重點各不相同。例如Theano和MXNet都是以隱式處理的方式在編譯中由表達式向計算圖過渡。而Caffe則比較直接,可以創建一個Graph對象,然后以類似Graph.Operator(xxx)的方式顯示調用。

      因為計算圖的引入,開發者得以從宏觀上俯瞰整個神經網絡的內部結構,就好像編譯器可以從整個代碼的角度決定如何分配寄存器那樣,計算圖也可以從宏觀上決定代碼運行時的GPU內存分配,以及分布式環境中不同底層設備間的相互協作方式。除此之外,現在也有許多深度學習框架將計算圖應用于模型調試,可以實時輸出當前某一操作類型的文本描述。

      4. 自動微分(Automatic Differentiation)工具

      計算圖帶來的另一個好處是讓模型訓練階段的梯度計算變得模塊化且更為便捷,也就是自動微分法。

      正如前面提到的,因為我們可以將神經網絡視為由許多非線性過程組成的一個復雜的函數體,而計算圖則以模塊化的方式完整表征了這一函數體的內部邏輯關系,因此微分這一復雜函數體,即求取模型梯度的方法就變成了在計算圖中簡單地從輸入到輸出進行一次完整遍歷的過程。與自動微分對應,業內更傳統的做法是符號微分。

      符號微分即常見的求導分析。針對一些非線性過程(如修正線性單元ReLU)或者大規模的問題,使用符號微分法的成本往往非常高昂,有時甚至不可行(即不可微)。因此,以上述迭代式的自動微分法求解模型梯度已經被廣泛采用。并且由于自動微分可以成功應對一些符號微分不適用的場景,目前許多計算圖程序包(例如Computation Graph Toolkit)都已經預先實現了自動微分。

      另外,由于每個節點處的導數只能相對于其相鄰節點計算,因此實現了自動微分的模塊一般都可以直接加入任意的操作類中,當然也可以被上層的微分大模塊直接調用。

      5. BLAS、cuBLAS、cuDNN等拓展包

      現在,通過上述所有模塊,我們已經可以搭建一個全功能的深度學習框架:將待處理數據轉換為張量,針對張量施加各種需要的操作,通過自動微分對模型展開訓練,然后得到輸出結果開始測試。這時還缺什么呢?答案是運算效率。

      由于此前的大部分實現都是基于高級語言的(如Java、Python、Lua等),而即使是執行最簡單的操作,高級語言也會比低級語言消耗更多的CPU周期,更何況是結構復雜的深度神經網絡,因此運算緩慢就成了高級語言的一個天然的缺陷。

      目前針對這一問題有兩種解決方案。

      第一種方法是模擬傳統的編譯器。就好像傳統編譯器會把高級語言編譯成特定平臺的匯編語言實現高效運行一樣,這種方法將高級語言轉換為C語言,然后在C語言基礎上編譯、執行。為了實現這種轉換,每一種張量操作的實現代碼都會預先加入C語言的轉換部分,然后由編譯器在編譯階段將這些由C語言實現的張量操作綜合在一起。目前pyCUDA和Cython等編譯器都已經實現了這一功能。

      第二種方法就是前文提到的,利用腳本語言實現前端建模,用低級語言如C++實現后端運行,這意味著高級語言和低級語言之間的交互都發生在框架內部,因此每次的后端變動都不需要修改前端,也不需要完整編譯(只需要通過修改編譯參數進行部分編譯),因此整體速度也就更快。

      除此之外,由于低級語言的最優化編程難度很高,而且大部分的基礎操作其實也都有公開的最優解決方案,因此另一個顯著的加速手段就是利用現成的擴展包。例如最初用Fortran實現的BLAS(基礎線性代數子程序),就是一個非常優秀的基本矩陣(張量)運算庫,此外還有英特爾的MKL(Math Kernel Library)等,開發者可以根據個人喜好靈活選擇。

      值得一提的是,一般的BLAS庫只是針對普通的CPU場景進行了優化,但目前大部分的深度學習模型都已經開始采用并行GPU的運算模式,因此利用諸如NVIDIA推出的針對GPU優化的cuBLAS和cuDNN等更據針對性的庫可能是更好的選擇。

      運算速度對于深度學習框架來說至關重要,例如同樣訓練一個神經網絡,不加速需要4天的時間,加速的話可能只要4小時。在快速發展的人工智能領域,特別是對那些成立不久的人工智能初創公司而言,這種差別可能就會決定誰是先驅者,而誰是追隨者。

      總結

      深度學習

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:【敏捷江湖桃花島】華山論劍第三期問答精選
      下一篇:XML DOM 解析器錯誤(一)
      相關文章
      亚洲精品第一国产综合精品99| 亚洲色欲啪啪久久WWW综合网| 国产天堂亚洲国产碰碰| 亚洲jjzzjjzz在线观看| 亚洲精品一区二区三区四区乱码| 亚洲国产综合专区在线电影| 午夜亚洲国产理论秋霞| 亚洲AV无码久久精品成人| 亚洲AV无码久久精品成人| 亚洲AV无一区二区三区久久| 亚洲精品你懂的在线观看| 亚洲午夜国产精品无码| 亚洲日产无码中文字幕| 亚洲开心婷婷中文字幕| 国产∨亚洲V天堂无码久久久| 亚洲精品一品区二品区三品区| 精品亚洲综合久久中文字幕| 亚洲AV无码一区二区乱子伦| 久久久久亚洲av无码专区蜜芽 | 亚洲乱码中文字幕在线| 亚洲一区二区无码偷拍| 亚洲人成电影网站色| 风间由美在线亚洲一区| 亚洲国产一级在线观看| 成人亚洲性情网站WWW在线观看| 亚洲夜夜欢A∨一区二区三区| 国产精品亚洲精品日韩已满| 亚洲av无码不卡一区二区三区| 亚洲成年轻人电影网站www| 91精品国产亚洲爽啪在线观看| 亚洲第一网站免费视频| 亚洲国产美女精品久久久久| 亚洲视频无码高清在线| 亚洲国产成人久久综合| 亚洲高清无码专区视频| 亚洲国产第一站精品蜜芽| 久久国产亚洲精品无码| 456亚洲人成影院在线观| 久久亚洲中文无码咪咪爱| 国产日韩成人亚洲丁香婷婷| 亚洲国产成人精品无码区在线观看|