斯坦福CS231n 2017最新课程:李飞飞详解深度学习的框架实现与对比
斯坦福CS231n 2017最新課程:李飛飛詳解深度學(xué)習(xí)的框架實(shí)現(xiàn)與對比
By?ZhuZhiboSmith2017年6月19日 13:37斯坦福大學(xué)的課程 CS231n (Convolutional Neural Networks for Visual Recognition) 作為深度學(xué)習(xí)和計(jì)算機(jī)視覺方面的重要基礎(chǔ)課程,在學(xué)界廣受推崇。今年 4 月,CS231n 再度開課,全新的 CS231n Spring 2017 仍舊由李飛飛帶頭,帶來了很多新鮮的內(nèi)容。今天機(jī)器之心給大家分享的是其中的第八講——深度學(xué)習(xí)軟件(Deep Learning Software)。主要內(nèi)容有:CPU 和 GPU 的對比;深度學(xué)習(xí)框架簡介;TensorFlow 和 PyTorch 的實(shí)例;以及各種深度學(xué)習(xí)框架的比較。
一、 CPU 和 GPU
?CPU:核芯的數(shù)量更少;
? ? 但是每一個(gè)核芯的速度更快,性能更強(qiáng);
? ? 更適用于處理連續(xù)性(sequential)任務(wù)。
?
?GPU:核芯的數(shù)量更多;
? ? ?但是每一個(gè)核芯的處理速度較慢;
? ? ?更適用于并行(parallel)任務(wù)。
二、深度學(xué)習(xí)框架簡介
去年我們還僅有 Caffe、Torch、Theano 和 TensorFlow 這些深度學(xué)習(xí)框架可供使用;但是到了今年,在此基礎(chǔ)上我們又新增加了 Caffe2、Pytorch、TensorFlow、PaddlePaddle、 CNDK、MXNet 等等一系列新的框架,可謂「百花齊放」。如今最常用的框架當(dāng)數(shù) Pytorch 和 TensorFlow 了, 而 Caffe 和 Caffe2 次之。
深度學(xué)習(xí)框架的關(guān)鍵點(diǎn)在于:
(1)易于建造大型的計(jì)算機(jī)圖形;
(2)易于在計(jì)算機(jī)圖形中進(jìn)行梯度計(jì)算;
(3)能在 GPU 上高效運(yùn)行(cuDNN, cuBLA 等)
三、TensorFlow 簡單實(shí)例
下面我們將詳細(xì)說明一個(gè)在 TensorFlow 下訓(xùn)練神經(jīng)網(wǎng)絡(luò)的簡單實(shí)例:即用隨機(jī)數(shù)據(jù)訓(xùn)練一個(gè)兩層的網(wǎng)絡(luò),激活函數(shù)為 ReLU。
?
a. 定義計(jì)算機(jī)圖形
1. 為輸入 x,權(quán)重系數(shù) w1、w2, 和目標(biāo)函數(shù) y 創(chuàng)建 placeholder:
2. 定義前向傳輸:這是為了計(jì)算 y 的預(yù)測值和誤差損失(loss);實(shí)際上這里是沒有計(jì)算過程的——僅僅是為了創(chuàng)建圖形!
3. 告訴 Tensorflow 去計(jì)算關(guān)于 w1 和 w2 的梯度損失;這里仍然不產(chǎn)生計(jì)算過程——僅僅是為了創(chuàng)建圖形。
b. 運(yùn)行
現(xiàn)在已經(jīng)完成了創(chuàng)建圖形的步驟,所以我們進(jìn)入對圖形進(jìn)行運(yùn)算的部分。
創(chuàng)建 Numpy 數(shù)組,這個(gè)數(shù)組將會(huì)被填進(jìn)上方的 placeholder 中。
對圖形進(jìn)行運(yùn)算:將 x、y、w1、w2 輸入到 numpy 數(shù)組中;得到關(guān)于損失(loss),w1 梯度和 w2 梯度的 numpy 數(shù)組。
訓(xùn)練網(wǎng)絡(luò):反復(fù)對圖形進(jìn)行運(yùn)算,用梯度(gradient)來更新權(quán)重(weights)。
把 w1 和 w2 的相應(yīng)函數(shù)從 placeholder() 改為 Variable()。
添加 assign 操作來更新 w1 和 w2(圖形的一部分)。
對圖形進(jìn)行一次運(yùn)算來初始化 w1 和 w2,然后進(jìn)行多次迭代訓(xùn)練。
完整代碼如下:
但是產(chǎn)生一個(gè)問題:誤差損失(loss)并沒有下降!這是因?yàn)?Assign 指令實(shí)際上并沒有被執(zhí)行。
這時(shí)我們就需要添加虛擬圖形節(jié)點(diǎn),并且告訴圖形去計(jì)算虛擬節(jié)點(diǎn)。
可以使用 optimizer 來計(jì)算梯度和更新權(quán)重系數(shù);記得要執(zhí)行 optimizer 的輸出!
使用預(yù)先定義的常用損失函數(shù):
使用 Xavier 進(jìn)行初始化;tf.layer 會(huì)自動(dòng)設(shè)置權(quán)重系數(shù)(weight)和偏置項(xiàng)(bias)!
c. 高級 Wrapper——Keras
Keras 可以理解為是一個(gè)在 TensorFlow 頂部的 layer,它可以讓一些工作變得更加簡單(也支持 Theano 后端)。
把模型目標(biāo)定義成一系列的 layer :
定義優(yōu)化器目標(biāo)(optimizer object):
創(chuàng)建模型,明確規(guī)定損失函數(shù)(loss function):
僅用一行代碼就能訓(xùn)練模型!
除了 Keras, 還有一些其他類型的高級容器(Wrapper)可供使用:
四、PyTorch 實(shí)例
PyTorch 是 Facebook 推出的深度學(xué)習(xí)框架,不論是在工業(yè)界還是學(xué)術(shù)界,它都得到了廣泛的應(yīng)用。它包括三個(gè)等級的抽象概念:
- 張量(Tensor):命令式的多維數(shù)組對象(ndarray),在 GPU 上運(yùn)行;
- 變量(Varaible):計(jì)算型圖形(computational graph)的節(jié)點(diǎn);用于存儲(chǔ)數(shù)據(jù)和梯度(gradient)
- 模塊(Module):代表一個(gè)神經(jīng)網(wǎng)絡(luò)層;可以存儲(chǔ)狀態(tài)(state), 也可以存儲(chǔ)可學(xué)習(xí)的權(quán)重系數(shù)(learnable weights)
PyTorch 和 TensorFlow 中抽象概念的等價(jià)對應(yīng)關(guān)系:
?
a. Pytorch 中的張量(Tensor)設(shè)置
PyTorch 中的張量就像 numpy 中的數(shù)組,但是這些張量可以在 GPU 上運(yùn)行;
這里我們用 PyTorch 的張量設(shè)置了一個(gè)兩層網(wǎng)絡(luò):
下面我們來分步解讀:
1. 為數(shù)據(jù)和權(quán)重(weights)創(chuàng)建隨機(jī)張量:
2. 設(shè)置前向傳播:計(jì)算預(yù)測值(prediction)和損失(loss):
3. 設(shè)置反向傳播:計(jì)算梯度(gradients):
4. 梯度下降(Gradient descent)和權(quán)重(weights)相對應(yīng):
5. 為了在 GPU 上運(yùn)行,將張量(tensors)設(shè)置為 cuda 數(shù)據(jù)類型:
b. PyTorch 中的 Autogradient 設(shè)置
PyTorch 的張量(Tensors)和變量(Variables)擁有相同的應(yīng)用編程接口 API。變量(Variables)可以記憶它們是怎么產(chǎn)生的(因?yàn)榉聪騻鞑サ木壒?#xff09;。
下面仍進(jìn)行分步解讀:
?
1. 我們不希望(損失 loss 的)梯度和數(shù)據(jù)(data)有相關(guān)性,但我們希望梯度和權(quán)重(weights)是相關(guān)的。相關(guān)設(shè)置如圖:?
2. 這里的前向傳播看上去和上述張量(Tensor)的對應(yīng)版本很相似,但是需要注意的是現(xiàn)在這里全部都是變量(variable)。
3. 計(jì)算損失函數(shù)對 w1 和 w2 的梯度(開始的時(shí)候梯度置零):
4. 讓梯度和權(quán)重(weights)相對應(yīng):
C. 定義新型 Autograd 函數(shù)
通過張量的前向和反向傳播來定義你自己的 autograd 函數(shù):
可以在前向傳播中使用新的 autograd 函數(shù):
d. PyTorch 中的神經(jīng)網(wǎng)絡(luò)(nn)設(shè)置
用更高級的「容器」(wrapper)來處理神經(jīng)網(wǎng)絡(luò)(neural nets), 和 Keras 相似。完整代碼如下:
下面進(jìn)行分步解讀:
把我們的模型定義成一系列的 layers:
也要定義常用損失函數(shù):
前向傳播:給模型輸入數(shù)據(jù);給損失函數(shù)(loss function)輸入預(yù)測信息(prediction):
反向傳播:計(jì)算所有的梯度(gradients):
讓梯度和每一個(gè)模型參數(shù)對應(yīng):
下面我們添加一個(gè)優(yōu)化器(optimizer):
在計(jì)算完梯度以后對所有的參數(shù)(parameters)進(jìn)行更新:
E. PyTorch 中的神經(jīng)網(wǎng)絡(luò)——定義新的模型
Pytorch 中的模塊(Module)其實(shí)是一個(gè)神經(jīng)網(wǎng)絡(luò)層(neural net layer),需要注意它的輸入和輸出都是變量;模塊(Module)中包含著權(quán)重 (當(dāng)作變量處理) 或者其他模塊;你可以使用 autograd 來定義你自己的模塊。詳細(xì)代碼如下:
下面進(jìn)行分步解讀:
1. 把我們的整體模型定義成一個(gè)單一的模塊:
2. 用初始化程序來設(shè)置兩個(gè)子模塊(一個(gè)父模塊可以包含子模塊)
3. 用子模塊和變量上的 autograd ops 定義前向傳播;不需要定義反向傳播——因?yàn)?autograd 會(huì)作相應(yīng)處理:
4. 創(chuàng)建并訓(xùn)練一個(gè)模型實(shí)例:
E. PyTorch 中的資料存儲(chǔ)器(Dataloaders)
資料存儲(chǔ)器(DataLoader)包括一個(gè)數(shù)據(jù)集 (Dataset),而且給你提供了小批量處理(minibatching),「洗牌」處理(shuffling)和多線程處理(multithreading);當(dāng)你需要載入自定義數(shù)據(jù)(custom data)時(shí),寫下你自己的數(shù)據(jù)集類型(dataset class)就可以了。
通過遍歷存儲(chǔ)器(loader)來形成小批量(minibatch);存儲(chǔ)器會(huì)給你提供張量(Tensors), 所以你需要將其「打包」(wrap)進(jìn)變量中:
注意:使用帶有 torchvision 的預(yù)先訓(xùn)練好的模型(pretrained model)將會(huì)更加簡單易行。
F. Torch 和 pytorch 的簡單對比
結(jié)論:盡量使用 PyTorch 來做你的新項(xiàng)目。
五、Caffe2 簡介
六、深度學(xué)習(xí)框架之爭,究竟誰更勝一籌?
其實(shí)具體選擇何種框架來進(jìn)行深度學(xué)習(xí)取決于我們要做什么。在參閱相關(guān)文獻(xiàn)之后,我們大致可以得出以下結(jié)論(僅供參考):
- PyTorch 和 Torch 更適用于學(xué)術(shù)研究(research);TensorFlow,Caffe,Caffe2 則更適用于工業(yè)界的生產(chǎn)環(huán)境部署(industrial production)。
- Caffe 適用于處理靜態(tài)圖像(static graph);Torch 和 PyTorch 更適用于動(dòng)態(tài)圖像(dynamic graph);而 TensorFlow 在兩種情況下都很實(shí)用。
- Tensorflow 和 Caffe2 可在移動(dòng)端使用。 ?
附主要參考文獻(xiàn)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
總結(jié)
以上是生活随笔為你收集整理的斯坦福CS231n 2017最新课程:李飞飞详解深度学习的框架实现与对比的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 黄仁勋评价股东孙正义
- 下一篇: TensorFlow + Docker