寫在最前面
1.本文將盡量簡明直觀的介紹點積運算斥赋,及其在python中的簡單應(yīng)用倘是。對點積運算的理解將對機器學(xué)習(xí)的算法編寫提供相當(dāng)大的幫助黄虱。
2.本文代碼使用python及numpy科學(xué)算法庫進(jìn)行編寫。
3.很重要的一點是:向量A與向量B的點積 并不等于 向量B與向量A的點積白热,我們用A·B表示兩個向量的點積運算敛助,則A·B!=B·A(或者你習(xí)慣于A·B<>B·A的表述)。
一維相量的點積運算
若A 和 B 均為一維向量屋确,且均包含有n個元素纳击,則A與B的點積為:
A[0]B[0]+A[1]B[1]+...+A[n]*B[n]续扔。
# A 和 B 均為一維向量,且均包含有n個元素焕数,則A與B的點積為:
# A[0]*B[0]+A[1]*B[1]+...+A[n]*B[n]纱昧。
# 即下標(biāo)相同的元素的乘積之和。沒錯堡赔,出來的是一個數(shù)字砌些。
# 舉個例子
A=[1,2,3,4,5]
B=[5,4,3,2,1]
print('A與B的點積為:',np.dot(A,B)) #此處np.dot(A,B)就是求A與B的點積運算
#輸出>A與B的點積為: 35
上例中,35=1*5+2*4+3*3+4*2+5*1=5+8+9+8+5
如果你認(rèn)為這很簡單加匈,那么有沒有想過二維向量的點積會如何呢存璃?
哦,對了雕拼,提一句纵东。一般我們使用大寫字母表示向量,小寫字母表示具體的某一項啥寇。不出意外的話偎球,是國際通用的。
二維向量的點積運算
二維數(shù)組的點積相對復(fù)雜一些辑甜。
先來個簡單的例子解釋一下:
我們還是假設(shè)有A衰絮,B兩個向量。如果A磷醋,B都是(2,2)向量猫牡,那么A和B的點積將會組成一個新的向量,我們叫做C邓线。
猜猜C會長什么樣子呢淌友?C將是(2,2)向量。先來看例子骇陈,再來解釋震庭。
A = [[1, 2],[3,7]]
B = [[4, 3],[5, 0]]
print('A與B的點積為:\n',np.dot(A,B))
#輸出>a與b的點積為:
[[14 3]
[47 9]]
這個結(jié)果是如何出來的呢?請原諒我沒有手寫板你雌,直接在紙上畫了器联。
或許你已經(jīng)看出規(guī)律:
1.A的第一行與B的第一列,對應(yīng)元素的乘積之和婿崭,構(gòu)成了新向量C的第一行第一列拨拓,坐標(biāo)為(0,0)的元素。
2.A的第一行與B的第二列逛球,對應(yīng)元素的乘積之和千元,構(gòu)成了新向量C的第一行第二列苫昌,坐標(biāo)為(0,1)的元素颤绕。
3.A的第二行與B的第一列幸海,對應(yīng)元素的乘積之和,構(gòu)成了新向量C的第二行第一列奥务,坐標(biāo)為(1,0)的元素物独。
總結(jié)來看,新向量元素的坐標(biāo)氯葬,y值取決于A向量所處的行挡篓,x值取決于B向量所處的列。而每個元素的計算帚称,總是A的行元素與B的列元素的點積官研。
所以,如果兩個二維向量想實現(xiàn)點積運算闯睹,是需要有一定條件的戏羽。條件是什么呢?
假如要計算 A·B楼吃,那么始花,A(點擊號前面的向量)中x方向元素的數(shù)量應(yīng)該于B(點積號后面的向量)中y方向的數(shù)量相同。
關(guān)于我在文章中對向量的標(biāo)識孩锡,這里需要稍微提一下酷宵。如果A為(3,2)向量,則代表A在y方向有3個元素躬窜,在x方向有兩個元素浇垦,就像下圖那樣。
是不是比手寫的漂亮了很多荣挨?恩恩溜族,是的。
接下來垦沉,我們將對上面提出的兩個向量點積的前提條件煌抒,做個實例。
A=np.array([1,2,3,4]).reshape(4,1)
B=np.array([1,2,3,4,5,6,7,8]).reshape(2,4)
print('A與B的點積為:\n',np.dot(A,B))
#>報錯:shapes (4,1) and (2,4) not aligned: 1 (dim 1) != 2 (dim 0)
上面的代碼中厕倍,我們將A聲明為(4,1)向量寡壮,將B聲明為(2,4)向量。A和B的具體形式為:
A:[ [1]
[2]
[3]
[4] ]
B:[ [1 2 3 4]
[5 6 7 8] ]
當(dāng)我們執(zhí)行點積運算時讹弯,報錯了况既,因為A的x方向為1個元素,而b的y方向為2個元素组民。無法進(jìn)行點積運算棒仍。 如果我們稍作修改,將A和B的位置顛倒臭胜,事情將大不相同莫其。如下:
A=np.array([1,2,3,4]).reshape(4,1)
B=np.array([1,2,3,4,5,6,7,8]).reshape(2,4)
print("A\n",A)
print("B\n",B)
print('B與A的點積為:\n',np.dot(B,A))
#>輸出:
A:[ [1]
[2]
[3]
[4] ]
B:[ [1 2 3 4]
[5 6 7 8] ]
B與A的點積為:
[ [30]
[70] ]
B與A的值均未變癞尚,我們只是更換了A與B的位置,B·A中乱陡,B的x方向有4個元素浇揩,A的y方向有四個元素。最終的結(jié)果憨颠,C在y方向上跟隨B胳徽,有兩個元素;在x方向上跟隨A爽彤,有一個元素养盗。C:(2,1)。
這有什么用
點擊運算是向量運算中的一種适篙,在程序中使用向量運算爪瓜,可以大大提升執(zhí)行效率。就點積運算而言匙瘪,對于機器學(xué)習(xí)的算法編寫铆铆,是大有幫助的。接下來我們將做一個簡單的介紹丹喻,如果你并沒有接觸機器學(xué)習(xí)薄货,依然可以看一下,這個例子并不復(fù)雜碍论。
而關(guān)于機器學(xué)習(xí)谅猾,后期會有一系列文章。
在下面例子中鳍悠,你只需要知道它是機器(深度)學(xué)習(xí)中的一部分就可以了税娜,無需考慮太多關(guān)于機器學(xué)習(xí)的內(nèi)容。
現(xiàn)在我們有兩組數(shù)據(jù)藏研,用L1和L2表示敬矩,L1,1表示第一組元素的第一個數(shù),L2,3表示第二組元素的第三個數(shù)蠢挡。
用L2,1舉例弧岳,我們要求L2,2=w2,1×L1,1+w2,2×L1,2
其中 wx,y表示L2中,第x個元素對應(yīng)于L1中第y個元素所特有的參數(shù)业踏。上圖L1和L2構(gòu)成了一個2×3的網(wǎng)絡(luò)禽炬。則L2中對應(yīng)的w的總數(shù)量應(yīng)該為2×3=6個。
要實現(xiàn)一個等式計算出所有L2中三個元素最終的值勤家,我們就用到了點積腹尖。如下:
1.向量A1表示L1中兩個元素的輸出值,則A1:(2,1)
2.向量W表示L2中所有的w伐脖,則W:(3,2)热幔。L2中總共三個元素乐设,每個元素對應(yīng)2個w值。
3.用展開的方式書寫:
L2,1=w1,1×A11,1+w1,2×A11,2
L2,2=w2,1×A11,1+w2,2×A11,2
L2,3=w3,1×A11,1+w3,2×A11,2
最終構(gòu)成的L2 我們用向量A2表示断凶,則A2:(3,1)伤提。
所以巫俺,有沒有想到上面我們提到的點積认烁?用點積表示:A2=W·A1
在程序里試一下:
A1=np.array([1,2]).reshape(2,1)
W=np.array([1,2,3,4,5,6]).reshape(3,2)
print('A2=W·A1:\n',np.dot(W,A1))
#>輸出:
A2=W·A1:
[ [ 5]
[11]
[17] ]
如果不用點積,你要寫多少代碼呢介汹?更重要的是却嗡,點積節(jié)約了大量運算的時間。