日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學(xué)無先后,達者為師

網(wǎng)站首頁 編程語言 正文

Python?的矩陣傳播機制Broadcasting和矩陣運算_python

作者:??北江愛國???? ? 更新時間: 2022-08-02 編程語言

一、Python的矩陣傳播機制(Broadcasting)

我們知道在深度學(xué)習(xí)中經(jīng)常要操作各種矩陣(matrix)?。回想一下,我們在操作數(shù)組(list)的時候,經(jīng)常習(xí)慣于用**for循環(huán)(for-loop)**來對數(shù)組的每一個元素進行操作。例如:

my_list?=?[1,2,3,4]
new_list?=?[]
for?each?in?my_list:
????new_list.append(each*2)
print(new_list)??#?輸出?[2,3,4,5]

如果是矩陣呢:

my_matrix?=?[[1,2,3,4],
?????????????[5,6,7,8]]
new_matrix?=?[[],[]]
for?i?in?range(2):????
????for?j?in?range(4):
????????new_matrix[i].append(my_matrix[i][j]*2)
print(new_matrix)#?輸出?[[2,?4,?6,?8],?[10,?12,?14,?16]]

實際上,上面的做法是十分的低效的!數(shù)據(jù)量小的話還不明顯,如果數(shù)據(jù)量大了,尤其是深度學(xué)習(xí)中我們處理的矩陣往往巨大,那用for循環(huán)去跑一個矩陣,可能要你幾個小時甚至幾天。

Python考慮到了這一點,這也是本文主要想介紹的**“Python的broadcasting”傳播機制**。

先說一句,python中定義矩陣、處理矩陣,我們一般都用numpy這個庫。

二、下面展示什么是python的傳播機制

import?numpy?as?np#?先定義一個3×3矩陣 A:
A?=?np.array(
????[[1,2,3],
?????[4,5,6],
?????[7,8,9]])?

print("A:\n",A)
print("\nA*2:\n",A*2)?#?直接用A乘以2
print("\nA+10:\n",A+10)?#?直接用A加上10

運行結(jié)果:

A:
?[[1?2?3]
?[4?5?6]
?[7?8?9]]

A*2:
?[[?2??4??6]
?[?8?10?12]
?[14?16?18]]

A+10:
?[[11?12?13]
?[14?15?16]
?[17?18?19]]

接著,再看看矩陣×(+)矩陣:

#定義一個3×1矩陣(此時也可叫向量了)
B?=?np.array([[10],
??????????????[100],
??????????????[1000]])?
print("\nB:\n",B)
print("\nA+B:\n",A+B)?
print("\nA*B:\n",A*B)

運行結(jié)果:

B:
?[[??10]
?[?100]
?[1000]]

A+B:
?[[??11???12???13]
?[?104??105??106]
?[1007?1008?1009]]

A*B:
?[[??10???20???30]
?[?400??500??600]
?[7000?8000?9000]]

可見,雖然A和B的形狀不一樣,一個是3×3,一個是3×1,但是我們在python中可以直接相加、相乘,相減相除也可以。也許看到這,大家都對broadcasting有感覺了。

用一個圖來示意一下:

image.png

所謂“傳播”,就是把一個數(shù)或者一個向量進行“復(fù)制”,從而作用到矩陣的每一個元素上

有了這種機制,那進行向量和矩陣的運算,就太方便了!理解了傳播機制,就可以隨心所欲地對矩陣進行各種便捷的操作了。

三、利用numpy的內(nèi)置函數(shù)對矩陣進行操作

numpy內(nèi)置了很多的數(shù)學(xué)函數(shù),例如np.log(),np.abs(),np.maximum()等等上百種。直接把矩陣丟進去,就可以算出新矩陣!?示例:

print(np.log(A))

輸出把A矩陣每一個元素求log后得到的新矩陣:

array([[0.????????,?0.69314718,?1.09861229],
???????[1.38629436,?1.60943791,?1.79175947],
???????[1.94591015,?2.07944154,?2.19722458]])

再比如深度學(xué)習(xí)中常用的ReLU激活函數(shù),就是y=max(0,x),

image.png

也可以對矩陣直接運算:

X?=?np.array([[1,-2,3,-4],??????????????[-9,4,5,6]])Y?=?np.maximum(0,X)print(Y)

得到:

[[1 0 3 0] [0 4 5 6]]

更多的numpy數(shù)學(xué)函數(shù),可以參見文檔

四、定義自己的函數(shù)來處理矩陣

其實這才是我寫下本文的目的。。。前面扯了這么多,只是做個鋪墊(?/ω\)

我昨天遇到個問題,就是我要對ReLU函數(shù)求導(dǎo),易知,y=max(0,x)的導(dǎo)函數(shù)是:y’ = 0 if x<0 y’ = 1 if x>0 但是這個y’(x)numpy里面沒有定義,需要自己構(gòu)建。即,我需要將矩陣X中的小于0的元素變?yōu)?,大于0的元素變?yōu)?。搞了好久沒弄出來,后來在StackOverflow上看到了解決辦法:

def?relu_derivative(x):
????x[x<0]?=?0
????x[x>0]?=?1
????return?x

X?=?np.array([[1,-2,3,-4],
??????????????[-9,4,5,6]])

print(relu_derivative(X))

輸出:

[[1?0?1?0]
?[0?1?1?1]]

**居然這么簡潔就出來了!!!**ミ?Д?彡 (?Д?#)

這個函數(shù)relu_derivative中最難以理解的地方,就是**x[x>0]**了。于是我試了一下:

X?=?np.array([[1,-2,3,-4],
??????????????[-9,4,5,6]])
print(X[X>0])
print(X[X<0])

輸出:

[1?3?4?5?6]
[-2?-4?-9]

它直接把矩陣X中滿足條件的元素取了出來!原來python對矩陣還有這種操作!

所以可以這么理解,X[X>0]相當(dāng)于一個“選擇器”,把滿足條件的元素選出來,然后直接全部賦值。

用這種方法,我們便可以定義各種各樣我們需要的函數(shù),然后對矩陣整體進行更新操作了!

五、總結(jié)

可以看出,python以及numpy對矩陣的操作簡直神乎其神,方便快捷又實惠。其實上面忘了寫一點,那就是計算機進行矩陣運算的效率要遠遠高于用for-loop來運算

不信可以用跑一跑:

#?vetorization?vs?for?loop
#?define?two?arrays?a,?b:
a?=?np.random.rand(1000000)
b?=?np.random.rand(1000000)

#?for?loop?version:
t1?=?time.time()
c?=?0
for?i?in?range(1000000):
????c?+=?a[i]*b[i]
t2?=?time.time()
print(c)
print("for?loop?version:"+str(1000*(t2-t1))+"ms")
time1?=?1000*(t2-t1)

#?vectorization?version:
t1?=?time.time()
c?=?np.dot(a,b)
t2?=?time.time()
print(c)
print("vectorization?version:"+str(1000*(t2-t1))+"ms")
time2?=?1000*(t2-t1)

print("vectorization?is?faster?than?for?loop?by?"+str(time1/time2)+"?times!")

運行結(jié)果:

249765.8415288075
for?loop?version:627.4442672729492ms
249765.84152880745
vectorization?version:1.5032291412353516ms
vectorization?is?faster?than?for?loop?by?417.39762093576525?times!

可見,用for方法和向量化方法,計算結(jié)果是一樣,但是后者比前者快了400多倍!

因此,在計算量很大的時候,我們要盡可能想辦法對數(shù)據(jù)進行Vectorizing,即“向量化”?,以便讓計算機進行矩陣運算。

原文鏈接:https://juejin.cn/post/7087396875187257358

欄目分類
最近更新