1. 程式人生 > >吳恩達-深度學習-課程筆記-3: Python和向量化( Week 2 )

吳恩達-深度學習-課程筆記-3: Python和向量化( Week 2 )

有時 指數 檢查 都是 效果 很快 -1 tro str

1 向量化( Vectorization )

在邏輯回歸中,以計算z為例,z = w的轉置和x進行內積運算再加上b,你可以用for循環來實現。

但是在python中z可以調用numpy的方法,直接一句z = np.dot( w, x ) + b用向量化完成,而且你會發現這個非常快。

ng做了個實驗,求兩個100萬長的一維向量的內積,用向量化花了1.5毫秒,而用for循環計算花了400多毫秒。

所以平常記得用向量化,一定要避免使用for循環,你的代碼會快很多。

CPU和GPU都有並行化的指令,有時候叫SIMD( single instruction multiple data )。

如果你使用了這樣的內置函數,比如np.function,python的numpy能充分利用並行化去更快的計算。

2 更多向量化的例子( More Vectorization Examples )

平時要避免使用for循環,善用python的numpy庫中的內置函數。

比如矩陣A和向量v的內積,可以用np.dot。對一列向量v實施指數運算,可以用np.exp,還有各種np.log,np.abs,np.maxmum( v, 0)等等。

對於 v ** 2,1 / v這樣的操作也要考慮用np裏的函數。

技術分享

技術分享

3 向量化邏輯回歸( Vectorizing Logistic Regression )

對於邏輯回歸的導數計算也應該使用向量化,完全不用for循環。圖中給出了向量化的過程。

Z的計算的向量化形式是np.dot( w.T, X) + b,其中b在這裏是一個實數,python在向量和實數相加時,會自動把實數變成一個相同維度的向量再相加。

其中w是n * 1的列向量,w.T是1 * n的列向量,X是n * m的矩陣,結果就是1 * m的向量,最後加上1 * m的b向量,得到1 * m的Z。最後通過sigmoid得到預測值A。

技術分享

同時還可以利用向量化計算m個數據的梯度,註意是同時計算。下圖左邊是for循環的實現,右邊是向量化的實現。

這裏dz是代價函數對z變量的導數,之前推導過等於預測值減去實際值a - y。

dw是代價函數對w的導數,db是代價函數對b的導數,如果不記得了可以翻看上一節課,邏輯回歸的內容。

雖然要盡量使用向量化,但是在進行多次梯度下降的叠代還是要用到for循環,這個不可避免。

技術分享

4 python中的廣播( python broadcasting)

當你用一個向量加上一個數的時候,python會自動把這個數變成向量再一一相加。

當你用一個m*n的矩陣加(減乘除)上1*n的向量時,python會自動把1*n的向量豎直復制變成m*n再相加。

當你用一個m*n的矩陣加上m*1的向量時,python會自動把m*1的向量水平復制變成m*n再相加。

這是實現神經網絡時主要用到的廣播,更詳細的可以查看numpy文檔搜索broadcasting。

對於numpy中的一些用法需要了解,可以幫助你更高效地用矩陣運算來提升程序效率,ng在本節還舉了求百分比的例子。

A.sum( axis = 0 )代表豎直求和,如果axis = 1就是水平求和。

技術分享

技術分享

5 python / numpy中的向量說明( A note on python/numpy vectors )

numpy和廣播使我們可以用一行代碼完成很多運算。

但有時可能會引入非常細微的錯誤,非常奇怪的bug,如果你不熟悉所有的復雜的廣播運作方式。

比如你覺得一個行向量和列向量相加應該會報錯,但是並不會,而且也不是簡單的一一相加。

python這些奇怪的效果有其內在邏輯,如果不熟悉python,你可能會寫出奇怪的難以調試的bug。

ng的建議,在實現神經網絡的時候不要使用shape為(n,)這樣的變量,要用(n,1)。

比如a 的 shape是(5, ) ,當你計算np.dot( a, a.T)的時候得到的是一個實數,a和a的轉置,它們的shape都是(5, )。

如果a 的 shape是(5, 1),你計算np.dot( a, a.T)的時候得到的就是一個5*5的矩陣。a的shape是( 5, 1),而a.T的shape是( 1, 5 )。

a.shape = (5, )這是一個秩為1的數組,不是行向量也不是列向量。很多學生出現難以調試的bug都來自秩為1數組。

另外你在代碼中做了很多事情後可能不記得或者不確定a是怎樣的時候,用assert( a.shape == (5,1) )來檢查你的矩陣的維度。

如果你得到了(5,) 你可以把它reshape成(5, 1)或(1, 5),reshape是很快的O(1)復雜度,所以放心大膽的用它,不用擔心。

技術分享

吳恩達-深度學習-課程筆記-3: Python和向量化( Week 2 )