許多初學(xué)者覺得深度學(xué)習(xí)框架抽象,雖然調(diào)用了幾個函數(shù)/方法,計算了幾個數(shù)學(xué)難題,但始終不能理解這些框架的全貌。
為了更好地認(rèn)識深度學(xué)習(xí)框架,也為了給一些想要自己親手搭建深度學(xué)習(xí)框架的朋友提供一些基礎(chǔ)性的指導(dǎo),日前來自蘇黎世聯(lián)邦理工學(xué)院計算機(jī)科學(xué)系的碩士研究生Gokula Krishnan Santhanam在博客上撰文,概括了大部分深度學(xué)習(xí)框架都會包含的五大核心組件,為我們詳細(xì)剖析了深度學(xué)習(xí)框架一般性的內(nèi)部組織結(jié)構(gòu)。以下由雷鋒網(wǎng)編譯。
Gokula Krishnan Santhanam認(rèn)為,大部分深度學(xué)習(xí)框架都包含以下五個核心組件:
1. 張量(Tensor)
2. 基于張量的各種操作
3. 計算圖(Computation Graph)
4. 自動微分(Automatic Differentiation)工具
5. BLAS、cuBLAS、cuDNN等拓展包
1. 張量(Tensor)
張量是所有深度學(xué)習(xí)框架中最核心的組件,因為后續(xù)的所有運(yùn)算和優(yōu)化算法都是基于張量進(jìn)行的。幾何代數(shù)中定義的張量是基于向量和矩陣的推廣,通俗一點(diǎn)理解的話,我們可以將標(biāo)量視為零階張量,矢量視為一階張量,那么矩陣就是二階張量。
舉例來說,我們可以將任意一張RGB彩色圖片表示成一個三階張量(三個維度分別是圖片的高度、寬度和色彩數(shù)據(jù))。如下圖所示是一張普通的水果圖片,按照RGB三原色表示,其可以拆分為三張紅色、綠色和藍(lán)色的灰度圖片,如果將這種表示方法用張量的形式寫出來,就是圖中最下方的那張表格。
圖中只顯示了前5行、320列的數(shù)據(jù),每個方格代表一個像素點(diǎn),其中的數(shù)據(jù)[1.0, 1.0, 1.0]即為顏色。假設(shè)用[1.0, 0, 0]表示紅色,[0, 1.0, 0]表示綠色,[0, 0, 1.0]表示藍(lán)色,那么如圖所示,前面5行的數(shù)據(jù)則全是白色。
將這一定義進(jìn)行擴(kuò)展,我們也可以用四階張量表示一個包含多張圖片的數(shù)據(jù)集,其中的四個維度分別是:圖片在數(shù)據(jù)集中的編號,圖片高度、寬度,以及色彩數(shù)據(jù)。
將各種各樣的數(shù)據(jù)抽象成張量表示,然后再輸入神經(jīng)網(wǎng)絡(luò)模型進(jìn)行后續(xù)處理是一種非常必要且高效的策略。因為如果沒有這一步驟,我們就需要根據(jù)各種不同類型的數(shù)據(jù)組織形式定義各種不同類型的數(shù)據(jù)操作,這會浪費(fèi)大量的開發(fā)者精力。更關(guān)鍵的是,當(dāng)數(shù)據(jù)處理完成后,我們還可以方便地將張量再轉(zhuǎn)換回想要的格式。例如Python NumPy包中numpy.imread和numpy.imsave兩個方法,分別用來將圖片轉(zhuǎn)換成張量對象(即代碼中的Tensor對象),和將張量再轉(zhuǎn)換成圖片保存起來。
2. 基于張量的各種操作
有了張量對象之后,下面一步就是一系列針對這一對象的數(shù)學(xué)運(yùn)算和處理過程。
其實(shí),整個神經(jīng)網(wǎng)絡(luò)都可以簡單視為為了達(dá)到某種目的,針對輸入張量進(jìn)行的一系列操作過程。而所謂的“學(xué)習(xí)”就是不斷糾正神經(jīng)網(wǎng)絡(luò)的實(shí)際輸出結(jié)果和預(yù)期結(jié)果之間誤差的過程。這里的一系列操作包含的范圍很寬,可以是簡單的矩陣乘法,也可以是卷積、池化和LSTM等稍復(fù)雜的運(yùn)算。而且各框架支持的張量操作通常也不盡相同,詳細(xì)情況可以查看其官方文檔(如下為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/
需要指出的是,大部分的張量操作都是基于類實(shí)現(xiàn)的(而且是抽象類),而并不是函數(shù)(這一點(diǎn)可能要?dú)w功于大部分的深度學(xué)習(xí)框架都是用面向?qū)ο蟮木幊陶Z言實(shí)現(xiàn)的)。這種實(shí)現(xiàn)思路一方面允許開發(fā)者將各種類似的操作匯總在一起,方便組織管理。另一方面也保證了整個代碼的復(fù)用性、擴(kuò)展性和對外接口的統(tǒng)一。總體上讓整個框架更靈活和易于擴(kuò)展,為將來的發(fā)展預(yù)留了空間。