史丹佛CS231n 2017最新課程:李飛飛詳解深度學習的框架實現與對比

ZhuZhiboSmith發表於2017-06-19

史丹佛大學的課程 CS231n (Convolutional Neural Networks for Visual Recognition) 作為深度學習和計算機視覺方面的重要基礎課程,在學界廣受推崇。今年 4 月,CS231n 再度開課,全新的 CS231n Spring 2017 仍舊由李飛飛帶頭,帶來了很多新鮮的內容。今天機器之心給大家分享的是其中的第八講——深度學習軟體(Deep Learning Software)。主要內容有:CPU 和 GPU 的對比;深度學習框架簡介;TensorFlow 和 PyTorch 的例項;以及各種深度學習框架的比較。

一、 CPU 和 GPU


 CPU:核芯的數量更少;

    但是每一個核芯的速度更快,效能更強;

    更適用於處理連續性(sequential)任務。

 

 GPU:核芯的數量更多;

     但是每一個核芯的處理速度較慢;

     更適用於並行(parallel)任務。

史丹佛CS231n 2017最新課程:李飛飛詳解深度學習的框架實現與對比


二、深度學習框架簡介


去年我們還僅有 Caffe、Torch、Theano 和 TensorFlow 這些深度學習框架可供使用;但是到了今年,在此基礎上我們又新增加了 Caffe2、Pytorch、TensorFlow、PaddlePaddle、 CNDK、MXNet 等等一系列新的框架,可謂「百花齊放」。如今最常用的框架當數 Pytorch 和 TensorFlow 了, 而 Caffe 和 Caffe2 次之。

史丹佛CS231n 2017最新課程:李飛飛詳解深度學習的框架實現與對比

深度學習框架的關鍵點在於:

(1)易於建造大型的計算機圖形;

(2)易於在計算機圖形中進行梯度計算;

(3)能在 GPU 上高效執行(cuDNN, cuBLA 等)

三、TensorFlow 簡單例項


下面我們將詳細說明一個在 TensorFlow 下訓練神經網路的簡單例項:即用隨機資料訓練一個兩層的網路,啟用函式為 ReLU。

 

a. 定義計算機圖形


史丹佛CS231n 2017最新課程:李飛飛詳解深度學習的框架實現與對比

1. 為輸入 x,權重係數 w1、w2, 和目標函式 y 建立 placeholder:

史丹佛CS231n 2017最新課程:李飛飛詳解深度學習的框架實現與對比

2. 定義前向傳輸:這是為了計算 y 的預測值和誤差損失(loss);實際上這裡是沒有計算過程的——僅僅是為了建立圖形!

史丹佛CS231n 2017最新課程:李飛飛詳解深度學習的框架實現與對比

3. 告訴 Tensorflow 去計算關於 w1 和 w2 的梯度損失;這裡仍然不產生計算過程——僅僅是為了建立圖形。

史丹佛CS231n 2017最新課程:李飛飛詳解深度學習的框架實現與對比


b. 執行


現在已經完成了建立圖形的步驟,所以我們進入對圖形進行運算的部分。

史丹佛CS231n 2017最新課程:李飛飛詳解深度學習的框架實現與對比

建立 Numpy 陣列,這個陣列將會被填進上方的 placeholder 中。

史丹佛CS231n 2017最新課程:李飛飛詳解深度學習的框架實現與對比

對圖形進行運算:將 x、y、w1、w2 輸入到 numpy 陣列中;得到關於損失(loss),w1 梯度和 w2 梯度的 numpy 陣列。

史丹佛CS231n 2017最新課程:李飛飛詳解深度學習的框架實現與對比

訓練網路:反覆對圖形進行運算,用梯度(gradient)來更新權重(weights)。

史丹佛CS231n 2017最新課程:李飛飛詳解深度學習的框架實現與對比

把 w1 和 w2 的相應函式從 placeholder() 改為 Variable()。

史丹佛CS231n 2017最新課程:李飛飛詳解深度學習的框架實現與對比

新增 assign 操作來更新 w1 和 w2(圖形的一部分)。

史丹佛CS231n 2017最新課程:李飛飛詳解深度學習的框架實現與對比

對圖形進行一次運算來初始化 w1 和 w2,然後進行多次迭代訓練。

史丹佛CS231n 2017最新課程:李飛飛詳解深度學習的框架實現與對比

完整程式碼如下:

史丹佛CS231n 2017最新課程:李飛飛詳解深度學習的框架實現與對比

但是產生一個問題:誤差損失(loss)並沒有下降!這是因為 Assign 指令實際上並沒有被執行。


史丹佛CS231n 2017最新課程:李飛飛詳解深度學習的框架實現與對比

這時我們就需要新增虛擬圖形節點,並且告訴圖形去計算虛擬節點。

史丹佛CS231n 2017最新課程:李飛飛詳解深度學習的框架實現與對比

可以使用 optimizer 來計算梯度和更新權重係數;記得要執行 optimizer 的輸出!

史丹佛CS231n 2017最新課程:李飛飛詳解深度學習的框架實現與對比

使用預先定義的常用損失函式:

史丹佛CS231n 2017最新課程:李飛飛詳解深度學習的框架實現與對比

使用 Xavier 進行初始化;tf.layer 會自動設定權重係數(weight)和偏置項(bias)!

史丹佛CS231n 2017最新課程:李飛飛詳解深度學習的框架實現與對比


c. 高階 Wrapper——Keras


Keras 可以理解為是一個在 TensorFlow 頂部的 layer,它可以讓一些工作變得更加簡單(也支援 Theano 後端)。

史丹佛CS231n 2017最新課程:李飛飛詳解深度學習的框架實現與對比


把模型目標定義成一系列的 layer :

史丹佛CS231n 2017最新課程:李飛飛詳解深度學習的框架實現與對比

定義優化器目標(optimizer object):

史丹佛CS231n 2017最新課程:李飛飛詳解深度學習的框架實現與對比

建立模型,明確規定損失函式(loss function):

史丹佛CS231n 2017最新課程:李飛飛詳解深度學習的框架實現與對比

僅用一行程式碼就能訓練模型!

史丹佛CS231n 2017最新課程:李飛飛詳解深度學習的框架實現與對比

除了 Keras, 還有一些其他型別的高階容器(Wrapper)可供使用:

史丹佛CS231n 2017最新課程:李飛飛詳解深度學習的框架實現與對比


四、PyTorch 例項


PyTorch 是 Facebook 推出的深度學習框架,不論是在工業界還是學術界,它都得到了廣泛的應用。它包括三個等級的抽象概念:

  • 張量(Tensor):命令式的多維陣列物件(ndarray),在 GPU 上執行;
  • 變數(Varaible):計算型圖形(computational graph)的節點;用於儲存資料和梯度(gradient)
  • 模組(Module):代表一個神經網路層;可以儲存狀態(state), 也可以儲存可學習的權重係數(learnable weights)

PyTorch 和 TensorFlow 中抽象概念的等價對應關係:

 史丹佛CS231n 2017最新課程:李飛飛詳解深度學習的框架實現與對比

a. Pytorch 中的張量(Tensor)設定

PyTorch 中的張量就像 numpy 中的陣列,但是這些張量可以在 GPU 上執行;

這裡我們用 PyTorch 的張量設定了一個兩層網路:

史丹佛CS231n 2017最新課程:李飛飛詳解深度學習的框架實現與對比

下面我們來分步解讀:

1. 為資料和權重(weights)建立隨機張量:

史丹佛CS231n 2017最新課程:李飛飛詳解深度學習的框架實現與對比

2. 設定前向傳播:計算預測值(prediction)和損失(loss):

史丹佛CS231n 2017最新課程:李飛飛詳解深度學習的框架實現與對比

3. 設定反向傳播:計算梯度(gradients):

史丹佛CS231n 2017最新課程:李飛飛詳解深度學習的框架實現與對比

4. 梯度下降(Gradient descent)和權重(weights)相對應:

史丹佛CS231n 2017最新課程:李飛飛詳解深度學習的框架實現與對比

5. 為了在 GPU 上執行,將張量(tensors)設定為 cuda 資料型別:

史丹佛CS231n 2017最新課程:李飛飛詳解深度學習的框架實現與對比

b. PyTorch 中的 Autogradient 設定

PyTorch 的張量(Tensors)和變數(Variables)擁有相同的應用程式設計介面 API。變數(Variables)可以記憶它們是怎麼產生的(因為反向傳播的緣故)。

史丹佛CS231n 2017最新課程:李飛飛詳解深度學習的框架實現與對比

下面仍進行分步解讀:

 

1. 我們不希望(損失 loss 的)梯度和資料(data)有相關性,但我們希望梯度和權重(weights)是相關的。相關設定如圖: 

史丹佛CS231n 2017最新課程:李飛飛詳解深度學習的框架實現與對比

2. 這裡的前向傳播看上去和上述張量(Tensor)的對應版本很相似,但是需要注意的是現在這裡全部都是變數(variable)。

史丹佛CS231n 2017最新課程:李飛飛詳解深度學習的框架實現與對比

3. 計算損失函式對 w1 和 w2 的梯度(開始的時候梯度置零):

史丹佛CS231n 2017最新課程:李飛飛詳解深度學習的框架實現與對比

4. 讓梯度和權重(weights)相對應:

史丹佛CS231n 2017最新課程:李飛飛詳解深度學習的框架實現與對比

C. 定義新型 Autograd 函式

通過張量的前向和反向傳播來定義你自己的 autograd 函式:

史丹佛CS231n 2017最新課程:李飛飛詳解深度學習的框架實現與對比

可以在前向傳播中使用新的 autograd 函式:

史丹佛CS231n 2017最新課程:李飛飛詳解深度學習的框架實現與對比

d. PyTorch 中的神經網路(nn)設定

用更高階的「容器」(wrapper)來處理神經網路(neural nets), 和 Keras 相似。完整程式碼如下:

史丹佛CS231n 2017最新課程:李飛飛詳解深度學習的框架實現與對比

下面進行分步解讀:

把我們的模型定義成一系列的 layers:

史丹佛CS231n 2017最新課程:李飛飛詳解深度學習的框架實現與對比

也要定義常用損失函式:

史丹佛CS231n 2017最新課程:李飛飛詳解深度學習的框架實現與對比

前向傳播:給模型輸入資料;給損失函式(loss function)輸入預測資訊(prediction):

史丹佛CS231n 2017最新課程:李飛飛詳解深度學習的框架實現與對比

反向傳播:計算所有的梯度(gradients):

史丹佛CS231n 2017最新課程:李飛飛詳解深度學習的框架實現與對比

讓梯度和每一個模型引數對應:

史丹佛CS231n 2017最新課程:李飛飛詳解深度學習的框架實現與對比

下面我們新增一個優化器(optimizer):

史丹佛CS231n 2017最新課程:李飛飛詳解深度學習的框架實現與對比

在計算完梯度以後對所有的引數(parameters)進行更新:

史丹佛CS231n 2017最新課程:李飛飛詳解深度學習的框架實現與對比

E. PyTorch 中的神經網路——定義新的模型

Pytorch 中的模組(Module)其實是一個神經網路層(neural net layer),需要注意它的輸入和輸出都是變數;模組(Module)中包含著權重 (當作變數處理) 或者其他模組;你可以使用 autograd 來定義你自己的模組。詳細程式碼如下:

史丹佛CS231n 2017最新課程:李飛飛詳解深度學習的框架實現與對比

下面進行分步解讀:

1. 把我們的整體模型定義成一個單一的模組:

史丹佛CS231n 2017最新課程:李飛飛詳解深度學習的框架實現與對比

2. 用初始化程式來設定兩個子模組(一個父模組可以包含子模組)

史丹佛CS231n 2017最新課程:李飛飛詳解深度學習的框架實現與對比

3. 用子模組和變數上的 autograd ops 定義前向傳播;不需要定義反向傳播——因為 autograd 會作相應處理:

史丹佛CS231n 2017最新課程:李飛飛詳解深度學習的框架實現與對比

4. 建立並訓練一個模型例項:

史丹佛CS231n 2017最新課程:李飛飛詳解深度學習的框架實現與對比

E. PyTorch 中的資料儲存器(Dataloaders)

資料儲存器(DataLoader)包括一個資料集 (Dataset),而且給你提供了小批量處理(minibatching),「洗牌」處理(shuffling)和多執行緒處理(multithreading);當你需要載入自定義資料(custom data)時,寫下你自己的資料集型別(dataset class)就可以了。

史丹佛CS231n 2017最新課程:李飛飛詳解深度學習的框架實現與對比

通過遍歷儲存器(loader)來形成小批量(minibatch);儲存器會給你提供張量(Tensors), 所以你需要將其「打包」(wrap)進變數中:

史丹佛CS231n 2017最新課程:李飛飛詳解深度學習的框架實現與對比

注意:使用帶有 torchvision 的預先訓練好的模型(pretrained model)將會更加簡單易行。

F. Torch 和 pytorch 的簡單對比

史丹佛CS231n 2017最新課程:李飛飛詳解深度學習的框架實現與對比

結論:儘量使用 PyTorch 來做你的新專案。

五、Caffe2 簡介

史丹佛CS231n 2017最新課程:李飛飛詳解深度學習的框架實現與對比

六、深度學習框架之爭,究竟誰更勝一籌?

史丹佛CS231n 2017最新課程:李飛飛詳解深度學習的框架實現與對比

史丹佛CS231n 2017最新課程:李飛飛詳解深度學習的框架實現與對比

史丹佛CS231n 2017最新課程:李飛飛詳解深度學習的框架實現與對比

史丹佛CS231n 2017最新課程:李飛飛詳解深度學習的框架實現與對比

其實具體選擇何種框架來進行深度學習取決於我們要做什麼。在參閱相關文獻之後,我們大致可以得出以下結論(僅供參考):

  • PyTorch 和 Torch 更適用於學術研究(research);TensorFlow,Caffe,Caffe2 則更適用於工業界的生產環境部署(industrial production)。
  • Caffe 適用於處理靜態影象(static graph);Torch 和 PyTorch 更適用於動態影象(dynamic graph);而 TensorFlow 在兩種情況下都很實用。
  • Tensorflow 和 Caffe2 可在移動端使用。  

附主要參考文獻CS231n_2017_Lecture8,連結可直接下載PPT:

  • http://cs231n.stanford.edu/slides/2017/cs231n_2017_lecture8.pdf

其他參考資料:

  • http://203.187.160.132:9011/dl.ee.cuhk.edu.hk/c3pr90ntc0td/slides/tutorial-caffe.pdf
  • http://203.187.160.132:9011/dl.ee.cuhk.edu.hk/c3pr90ntc0td/slides/DL_in_Action.pdf

相關文章