python向量化编程技巧_神经网络基础之Python与向量化
Vectorization
深度學(xué)習(xí)算法中,數(shù)據(jù)量很大,在程序中盡量減少使用loop循環(huán)語(yǔ)句,而可以使用向量運(yùn)算來(lái)提高程序運(yùn)行速度。
向量化(Vectorization)就是利用矩陣運(yùn)算的思想,大大提高運(yùn)算速度。例如下面所示在Python中使用向量化要比使用循環(huán)計(jì)算速度快得多。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21import 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("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")
輸出結(jié)果類似于:1
2
3
4250286.989866
Vectorized version:1.5027523040771484ms
250286.989866
For loop:474.29513931274414ms
從程序運(yùn)行結(jié)果上來(lái)看,該例子使用for循環(huán)運(yùn)行時(shí)間是使用向量運(yùn)算運(yùn)行時(shí)間的約300倍。因此,深度學(xué)習(xí)算法中,使用向量化矩陣運(yùn)算的效率要高得多。
為了加快深度學(xué)習(xí)神經(jīng)網(wǎng)絡(luò)運(yùn)算速度,可以使用比CPU運(yùn)算能力更強(qiáng)大的GPU。事實(shí)上,GPU和CPU都有并行指令(parallelization instructions),稱為Single Instruction Multiple Data(SIMD)。SIMD是單指令多數(shù)據(jù)流,能夠復(fù)制多個(gè)操作數(shù),并把它們打包在大型寄存器的一組指令集。SIMD能夠大大提高程序運(yùn)行速度,例如python的numpy庫(kù)中的內(nèi)建函數(shù)(build-in function) 就是使用了SIMD指令。相比而言,GPU的SIMD要比CPU更強(qiáng)大一些。
More Vectorization Examples
盡量避免使用for循環(huán)而使用向量化矩陣運(yùn)算。在python的numpy庫(kù)中,我們通常使用np.dot()函數(shù)來(lái)進(jìn)行矩陣運(yùn)算。
我們將向量化的思想使用在邏輯回歸算法,盡可能減少for循環(huán),而只使用矩陣運(yùn)算。值得注意的是,算法最頂層的迭代訓(xùn)練的for循環(huán)是不能替換的。而每次迭代過(guò)程對(duì)J,dw,b的計(jì)算是可以直接使用矩陣運(yùn)算。
Vectorizing Logistic Regression
整個(gè)訓(xùn)練樣本構(gòu)成的輸入矩陣X的維度是$(n_X,1)$,b是一個(gè)常數(shù)值,而整個(gè)訓(xùn)練忘本構(gòu)成的輸出矩陣Y的維度是(1,m)。利用向量化的思想,所有m個(gè)樣本的線性輸出Z可以用矩陣表示:
在python的numpy庫(kù)中可以表示為:1
2Z = np.dot(w.T,X) + b
A = sigmoid(Z)
其中,w,T表示w的轉(zhuǎn)置
這樣,我們就能夠使用向量化矩陣運(yùn)算代替for循環(huán),對(duì)所有m個(gè)樣本同時(shí)運(yùn)算,大大提高了運(yùn)算速度。
Vectorizing Logistic Regression’s Gradient Output
再來(lái)看邏輯回歸中的梯度下降算法如何轉(zhuǎn)化為向量化的矩陣形式。對(duì)于所有m個(gè)樣本,db可表示為:
db可表示為:
對(duì)應(yīng)的程序?yàn)?#xff1a;1db=1/m*np.sum(dZ)
dw課表示為:
對(duì)應(yīng)的程序?yàn)?dw=1/m*np.dot(X,dZ,T)
這樣,我們把整個(gè)邏輯回歸中的for循環(huán)盡可能用矩陣運(yùn)算代替,對(duì)于單次迭代,梯度下降算法流程如下所示:1
2
3
4
5
6
7
8Z=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是學(xué)習(xí)因子,決定w和b的更新速度。上述代碼只是單次訓(xùn)練更新而言的,外層還需要一個(gè)for循環(huán),代表迭代次數(shù)。
Broadcasting in Python
下面介紹使用python的另一種技巧:廣播(Broadcasting).python中的廣播機(jī)制可以由下面四條表示:
·讓所有輸入數(shù)組都向其中shape最長(zhǎng)的數(shù)組看齊,shape中不足的部分都通過(guò)在前面加1補(bǔ)齊
·輸出數(shù)組的shape是輸入數(shù)組shape的各軸上的最大值
·如果輸入數(shù)組的某個(gè)軸和輸出數(shù)組的對(duì)應(yīng)軸的長(zhǎng)度相同或者其長(zhǎng)度為1時(shí),這個(gè)數(shù)組能夠用來(lái)計(jì)算,否則出錯(cuò)
·當(dāng)輸入數(shù)組的某個(gè)軸的長(zhǎng)度為1時(shí),沿著此軸運(yùn)算時(shí)都用此軸上的第一組值
簡(jiǎn)而言之,就是用python中可以對(duì)不同維度的矩陣進(jìn)行四則混合運(yùn)算,但至少保證有一個(gè)維度是相同的。下面給出幾個(gè)廣播的例子,具體細(xì)節(jié)可參閱python的相關(guān)手冊(cè),這里就不贅述了。
在python程序中為了保證矩陣運(yùn)算正確,可以使用reshape()函數(shù)來(lái)對(duì)矩陣設(shè)定所需的維度。這是一個(gè)很好且有用的習(xí)慣。
A note on python/numpy vectors
總結(jié)一些python的小技巧,避免不必要的code bug
python中,如果我們用下列語(yǔ)句來(lái)定義一個(gè)變量:1a = np.random.randn(5)
這條語(yǔ)句生成的a維度是(5, )。它既不是行向量也不是列向量,我們把a(bǔ)叫做rank 1 array。這種定義會(huì)帶來(lái)一些問(wèn)題。例如我們對(duì)a進(jìn)行轉(zhuǎn)置,還會(huì)得到a本身。所以,如果我們要定義(5,1)的列向量,最好使以下標(biāo)準(zhǔn)語(yǔ)句,避免使用rank 1 array。1
2a = np.random.randn(5,1)
b = np.random.randn(1,5)
除此之外,我們還可以使用assert語(yǔ)句對(duì)向量或者數(shù)組的維度進(jìn)行判斷,例如:1assert(a.shape == (5,1))
assert語(yǔ)句會(huì)對(duì)內(nèi)嵌語(yǔ)句進(jìn)行判斷,即判斷a的維度是不是(5,1)的。如果不是,則程序在此處停止。使用assert語(yǔ)句也是一種很好的習(xí)慣,能夠幫我們及時(shí)檢查、發(fā)現(xiàn)語(yǔ)句是否正確。
另外,還可以使用reshape函數(shù)對(duì)數(shù)組設(shè)定所需的維度:1a.shape((5,1))
Quick tour of Jupyter/iPython Notebooks
Jupyter notebook是一個(gè)交互筆記本,支持運(yùn)行40中編程語(yǔ)言,本課程所有的編程練習(xí)題都將在Jupyter notebook上進(jìn)行,使用語(yǔ)言是python。
Explanation of logistic regression cost function(optional)
接下來(lái)簡(jiǎn)要介紹邏輯回歸的Cost function是怎么來(lái)的
首先,預(yù)測(cè)輸出$hat{y}$的表達(dá)式可以寫成:
其中,$sigma(z)=frac{1}{1+exp(-z)}$。$hat{y}$可以看成是預(yù)測(cè)輸出為正類(+1)的概率:
那么,當(dāng)y=1時(shí):
當(dāng)y= 0時(shí):
我們把上面兩個(gè)式子整合到一個(gè)式子中,得到:
由于log函數(shù)的單調(diào)性,可以對(duì)上式P(y|x)進(jìn)行l(wèi)og處理
我們希望上述概率P(y|x)越大越好,對(duì)上式加上負(fù)號(hào),則轉(zhuǎn)化成額單個(gè)樣本的Loss function,越小越好,也iu得到了我們之前介紹的邏輯回歸的Loss function形式
如果對(duì)于所有m個(gè)訓(xùn)練樣本,假設(shè)樣本之間是獨(dú)立同分布的(iid),我們希望總的概率越大越好:
同樣引入log函數(shù),加上負(fù)號(hào),將上式轉(zhuǎn)化為Cost function:
上式中,$frac{1}{m}$表示對(duì)所有m個(gè)樣本的Cost function求平均,是縮放因子。
Summary
本節(jié)課我們主要介紹了神經(jīng)網(wǎng)絡(luò)基礎(chǔ)————python和向量話。在深度學(xué)習(xí)程序中,使用向量化和矩陣運(yùn)算的方法能夠大大提高運(yùn)行速度,節(jié)省時(shí)間。以邏輯回歸威力,我們將算法流程包括梯度下降轉(zhuǎn)化為向量化的形式,同時(shí),我們也介紹了python的相關(guān)編程方法和技巧。
總結(jié)
以上是生活随笔為你收集整理的python向量化编程技巧_神经网络基础之Python与向量化的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 类似endnote_求推荐一款文献管理软
- 下一篇: 《数字孪生体技术白皮书》