第二周:神经网络的编程基础之Python与向量化
本節課我們將來探討Python和向量化的相關知識。
1. Vectorization
深度學習算法中,數據量很大,在程序中應該盡量減少使用循環語句,而可以使用向量運算來提高程序運行速度。
向量化(Vectorization)就是利用矩陣運算的思想,大大提高運算速度。例如下面所示在Python中使用向量化要比使用循環計算速度快得多。
import numpy as np import timea = np.random.rand(1000000) b = np.random.rand(1000000)tic = time.time() c = np.dot(a,b) toc = time.time()print(c) print("Vectorized version:" + str(1000*(toc-tic)) + "ms")c = 0 tic = time.time() for i in range(1000000):c += a[i]*b[i] toc = time.time()print(c) print("for loop:" + str(1000*(toc-tic)) + "ms")輸出結果類似于:
250286.989866 Vectorized version:1.5027523040771484ms 250286.989866 For loop:474.29513931274414ms從程序運行結果上來看,該例子使用for循環運行時間是使用向量運算運行時間的約300倍。因此,深度學習算法中,使用向量化矩陣運算的效率要高得多。
為了加快深度學習神經網絡運算速度,可以使用比CPU運算能力更強大的GPU。事實上,GPU和CPU都有并行指令(parallelization instructions),稱為Single Instruction Multiple Data(SIMD)。SIMD是單指令多數據流,能夠復制多個操作數,并把它們打包在大型寄存器的一組指令集。SIMD能夠大大提高程序運行速度,例如python的numpy庫中的內建函數(built-in function)就是使用了SIMD指令。相比而言,GPU的SIMD要比CPU更強大一些。
2. More Vectorization Examples
應該盡量避免使用for循環而使用向量化矩陣運算。在python的numpy庫中,我們通常使用np.dot()函數來進行矩陣運算。
我們將向量化的思想使用在邏輯回歸算法上,盡可能減少for循環,而只使用矩陣運算。值得注意的是,算法最頂層的迭代訓練的for循環是不能替換的。而每次迭代過程對J,dw,b的計算是可以直接使用矩陣運算。
3. Vectorizing Logistic Regression
整個訓練樣本構成的輸入矩陣X的維度是(nxnx,m),權重矩陣w的維度是(nxnx,1),b是一個常數值,而整個訓練樣本構成的輸出矩陣Y的維度為(1,m)。利用向量化的思想,所有m個樣本的線性輸出Z可以用矩陣表示:
在python的numpy庫中可以表示為:
Z = np.dot(w.T,X) + b A = sigmoid(Z)其中,w.T表示w的轉置。
這樣,我們就能夠使用向量化矩陣運算代替for循環,對所有m個樣本同時運算,大大提高了運算速度。
4. Vectorizing Logistic Regression’s Gradient Output
邏輯回歸中的梯度下降算法如何轉化為向量化的矩陣形式。對于所有m個樣本,dZ的維度是(1,m),可表示為:
db可表示為:
?對應的程序為:
db = 1/m*np.sum(dZ)dw可表示為:
?對應的程序為:
dw = 1/m*np.dot(X,dZ.T)我們把整個邏輯回歸中的for循環盡可能用矩陣運算代替,對于單次迭代,梯度下降算法流程如下所示:
Z = np.dot(w.T,X) + b A = sigmoid(Z) dZ = A-Y dw = 1/m*np.dot(X,dZ.T) db = 1/m*np.sum(dZ)w = w - alpha*dw b = b - alpha*db其中,alpha是學習因子,決定w和b的更新速度。上述代碼只是對單次訓練更新而言的,外層還需要一個for循環,表示迭代次數。
5. Broadcasting in Python
下面介紹使用python的另一種技巧:廣播(Broadcasting)。python中的廣播機制可由下面四條表示:
簡而言之,就是python中可以對不同維度的矩陣進行四則混合運算,但至少保證有一個維度是相同的。下面給出幾個廣播的例子,具體細節可參閱python的相關手冊,這里就不贅述了。
值得一提的是,在python程序中為了保證矩陣運算正確,可以使用reshape()函數來對矩陣設定所需的維度。這是一個很好且有用的習慣。
6. A note on python/numpy vectors
接下來我們將總結一些python的小技巧,避免不必要的code bug。
python中,如果我們用下列語句來定義一個向量:
a = np.random.randn(5)這條語句生成的a的維度是(5,)。它既不是行向量也不是列向量,我們把a叫做rank 1 array。這種定義會帶來一些問題。例如我們對a進行轉置,還是會得到a本身。所以,如果我們要定義(5,1)的列向量或者(1,5)的行向量,最好使用下來標準語句,避免使用rank 1 array。
a = np.random.randn(5,1) b = np.random.randn(1,5)除此之外,我們還可以使用assert語句對向量或數組的維度進行判斷,例如:
assert(a.shape == (5,1))assert會對內嵌語句進行判斷,即判斷a的維度是不是(5,1)的。如果不是,則程序在此處停止。使用assert語句也是一種很好的習慣,能夠幫助我們及時檢查、發現語句是否正確。
另外,還可以使用reshape函數對數組設定所需的維度:
a.reshape((5,1))7. Quick tour of Jupyter/iPython Notebooks
Jupyter notebook(又稱IPython notebook)是一個交互式的筆記本,支持運行超過40種編程語言。本課程所有的編程練習題都將在Jupyter notebook上進行,使用的語言是python。
8. Explanation of logistic regression cost function(optional)
在上一節課的筆記中,我們介紹過邏輯回歸的Cost function。接下來我們將簡要解釋這個Cost function是怎么來的。
首先,預測輸出y^y^的表達式可以寫成:
其中,
y^可以看成是預測輸出為正類(+1)的概率:
那么,當y=1時:
當y=0時:
?我們把上面兩個式子整合到一個式子中,得到:
由于log函數的單調性,可以對上式P(y|x)進行log處理:
我們希望上述概率P(y|x)越大越好,對上式加上負號,則轉化成了單個樣本的Loss function,越小越好,也就得到了我們之前介紹的邏輯回歸的Loss function形式。
如果對于所有m個訓練樣本,假設樣本之間是獨立同分布的(iid),我們希望總的概率越大越好:
?同樣引入log函數,加上負號,將上式轉化為Cost function:
上式中,1/m表示對所有m個樣本的Cost function求平均,是縮放因子。?
9. Summary
本節課我們主要介紹了神經網絡基礎——python和向量化。在深度學習程序中,使用向量化和矩陣運算的方法能夠大大提高運行速度,節省時間。以邏輯回歸為例,我們將其算法流程包括梯度下降轉換為向量化的形式。同時,我們也介紹了python的相關編程方法和技巧。
總結
以上是生活随笔為你收集整理的第二周:神经网络的编程基础之Python与向量化的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 是引进外部函数吗_使用PowerBI的这
- 下一篇: js调用vlc_如何使用HTML5或Ja