上一講薈薈講了一下張量切片、逐元素運算、廣播,這一講再說說張量點積和張量變形,集齊這五種裝備,基本可以開始愉快地玩耍了。
前面我們說過逐元素運算,要將兩個張量進行逐元素相乘,我們使用“*“運算符,比如將兩個矩陣A和B進行逐元素相乘
而在神經(jīng)網(wǎng)絡中,經(jīng)常需要類似圖1的乘法方式,我們將輸入向量和權值向量的對應元素進行相乘后再求和,這種方式我們稱之為張量點積。
圖1
如圖2所示,如果有多個神經(jīng)元需要輸出,則可以把輸入X寫成一個列向量,它的轉置為
輸入權值矩陣可寫為
該矩陣的每一列,代表輸入到中間層某一個神經(jīng)元的權值向量,如下圖中輸入到z2的權值正是上述矩陣的第二列。從圖中可以看出,我們得到的中間層神經(jīng)元的輸出(這里為了簡單起見省略了非線性激活函數(shù),如ReLU)也是一個列向量,如下:
其中的第n個元素正是輸入的每個元素和W的第n列對應元素一一相乘并相加的結果。如果向更高維度擴展,輸入不是一個向量,而是一個矩陣,比如我們將100個輸入樣本向量輸入剛才討論的神經(jīng)網(wǎng)絡,那么XT的形狀就是(100,3),ZT的形狀就是(100,4)。
圖2
看到這里,學過線性代數(shù)的童鞋可能已經(jīng)看出,這不就是我們學過的矩陣乘法嘛,沒錯,這里說的張量點積,如果是2d張量(矩陣),就是我們最常見的矩陣乘法,語法如下。
只不過它還可以繼續(xù)拓展,比如要在神經(jīng)網(wǎng)絡里處理視頻數(shù)據(jù),形狀通常是(幀,長,寬,顏色),如果需要進行點積(對應元素相乘相加),這時候如果有一個底層優(yōu)化過的張量點積運算,我們就可以保持其他維度不變,直接用一次dot把所有幀和顏色的張量都進行相同的點積運算,而按照傳統(tǒng)方法我們則需要進行多重循環(huán)。
在Numpy中,如果A為M維張量,B為N為張量,兩個張量的點積就是將A張量的最后一個軸中的所有元素,與B張量中倒數(shù)第二個軸的所有元素對應相乘后相加的結果,也就是dot(a, b)[i,j,k,m] = sum(a[i,j,:] * b[k,:,m])。有點暈菜對不對,下面用矩陣來解釋一下,如圖3所示,矩陣x的第一個軸是行,第二個軸是列,矩陣一共就兩個軸,所以x的最后一個軸就是列,同理y的倒數(shù)第二個軸是行。可見矩陣x和y的點積就是將x第i行中的所有列(x的最后一個軸)和y第j列中的所有行(y的倒數(shù)第二個軸)對應相乘并相加的結果返回給z(i,j)。從這個例子中也可以發(fā)現(xiàn),這就要求x的列數(shù)必須等于y的行數(shù),也就是A張量最后一個軸的元素數(shù)量必須等于B張量倒數(shù)第二個軸中的元素數(shù)量。
圖3
那么張量點積后的形狀和輸入張量形狀的關系又是什么呢,以一個例子來說明一下,如果A的形狀為(a,b,c,d),B的形狀為(d,e),那么numpy.dot(A,B)的形狀為(a,b,c,e)。如果A的形狀為(a,b,c,d), B的形狀為(c,d),那么就呵呵了,因為A的最后一個軸元素數(shù)量為d,而B的倒數(shù)第二個軸元素數(shù)量為c,不匹配,會報錯。
下面給出了一個矩陣乘法的實際案例,小伙伴們?nèi)プ屑氀芯恳幌掳伞?/p>
此外,Numpy還提供了一種更為靈活的張量點乘函數(shù)numpy.tensordot(a,b,axes),可以指定需要和并的軸,但是不太容易理解,這里就不寫出來混淆試聽了,有興趣的朋友們可以看看Chenxiao Ma的博客,寫的還挺清楚的https://www.machenxiao.com/blog/tensordot
對于初學者來說知道numpy.dot就是求矩陣乘法也基本夠用了。
reshape
張量變形其實咱們在第二講中已經(jīng)見過,當時我們需要把一個形狀為(60000,28,28)的手寫字符圖像張量輸入一個中間層為784個神經(jīng)元的密集連接型神經(jīng)網(wǎng)絡。所以需要將這個張量變形為(60000,28*28)的形狀,才好和后面的全連接神經(jīng)網(wǎng)絡進行加權點乘。當時我們的預處理代碼是:
train_images =train_images.reshape((60000, 28 * 28))
reshape函數(shù)很簡單,輸入?yún)?shù)就是你想要的新形狀,只要新張量中的元素個數(shù)和原始張量中的元素個數(shù)是一樣的即可。元素的安排順序默認和c語言是一致的,即依次進行排列。下面兩個例子可以讓你清楚地理解這一操作。
轉置Transpose
另一種常見的張量變形就是轉置了,即把矩陣的行換成列,列換成行,也就是x[i,:]變?yōu)閤[:,i],語法為np.transpose(x)。
到這里,張量最常見的幾種常見的操作和運算算是告一段落,總結一下本講的內(nèi)容:1. 張量點積(相乘相加,2D張量就是矩陣乘法);2. 張量變形(張量在神經(jīng)網(wǎng)絡逐層傳播,每一層的輸入和輸出形狀有可能發(fā)生變化,需要變形加以適應)。下一講我們會從卷積神經(jīng)網(wǎng)絡開始正式進入深度學習的實際操作,過程中我們會反復操練這些張量操作方法。