第二週 第二部分 Python與向量化
- 2.11 向量化
邏輯迴歸中要計算 ,向量化的表示爲 z = np.dot(w,x)+b
課程中給出如下代碼,分別計算向量化和非向量化之後的計算時間對比
import numpy as np
import time
a = np.random.rand(1000000)
b = np.random.rand(1000000)
tic = time.time()
c = np.dot(a,b)
toc = time.time()
print(c)
print('Vectorization 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')
可以自己運算下結果,看看向量化的力量。
很多深度學習的程序都是在GPU上跑的。其實GPU和CPU都有SIMD,即單指令流多數據流。
Python中的NumPy可以充分利用並行化,去進行更快的運算。
- 2.12 更多向量化例子
經驗法則:當編寫新的神經網絡或者LR算法時,一定要儘量避免使用for循環。
例:要將 v --> u
# 非向量化表示
u = np.zeros((n,1))
for i in range(n):
u[i] = math.exp(v[i])
# 向量化表示
u = np.exp(v)
在2.10節中(https://blog.csdn.net/weixin_41153216/article/details/80922975),完成m個訓練樣本的梯度下降,需要兩個循環,在本節中,去掉內部的循環,代碼修改如下
# 單次梯度下降V2.py
# 修改部分:向量初始化,內部參數的計算(去掉計算參數的循環,也是本節的重點)。平均值的向量化
import numpy as np
dJ = 0
dw = np.zeros((nx,1))
db = 0
# 遍歷m次訓練樣例,對相應的值進行累加
for ind in range(0,m):
zi = W.T * x[:,ind] + b
ai = sigmoid(zi)
J += -[yi*np.log(ai)+(1-yi)*np.log(1-ai)]
dzi = ai - yi
dw += xi * dzi
db += dzi
# 對所有m個樣本的累積梯度值,求平均
J /= m
dw /= m
db /= m
- 2.13 正向傳播的向量化
本節中主要介紹正向傳播的向量化表示,根據2.1節((https://blog.csdn.net/weixin_41153216/article/details/80922975))中的介紹,X.shape = (nx,m),一共m個訓練樣例,因此會生成m個輸出值Z。
本節內容是向量化如下的代碼
for ind in range(0,m):
zi = W.T * x[:,ind] + b
ai = sigmoid(zi)
向量化的數學思想如下:
Python的表示
Z = np.dot(W.T,X) + b
這裏涉及到一個概念是Python廣播,b實際上是一個數,但是在計算時,會擴展成1*m的矩陣。
- 2.14 向量化的梯度輸出
定義
下面求參數的導數
在Python中的實現是 db = np.sum(dZ)/m
向量優化後的代碼
# 梯度下降.py
# 向量化
import numpy as np
dJ = 0
dw = 0
db = 0
# 假設迭代1000次
for ind in range(0,1000):
Z = np.dot(W.T,X) + b
A = sigmoid(Z)
dZ = A - Y
dw = (X*dZ.T)/m
db = np.sum(dZ)/m
# 進行參數更新
w -= alpha * dw
b -= alpha * db
注:在神經網絡或者LR中,要儘量少用循環,但是外層的迭代循環,目前還沒有辦法省略。