- 移動深度學習
- 李永會
- 846字
- 2019-12-05 14:22:39
2.6 矩陣乘法
如果矩陣對同一向量做線性變換,就會得到一個變換后的向量;如果矩陣對兩個向量或者一組向量做變換,所做的就是矩陣乘法,如下式所示是矩陣A和B相乘,得到了矩陣C。
A×B=C
在二維空間內,可以把兩個矩陣相乘看作其中一個矩陣所包含的兩個向量,分別對另一個矩陣做線性變換后再疊加,結果矩陣就是疊加后的矩陣。
如圖2-10所示,矩陣2M和M1相乘,等價于M2對M1的兩個向量和
分別進行線性變換。

圖2-10 矩陣M2和M1相乘
注意,只有在第一個矩陣的列數與第二個矩陣的行數相等的時候,矩陣的乘法才有意義。如果要求使用C++實現一個矩陣乘法,可以用下面這種最簡單的方式來實現:采用三層for循環,實現了一個最基本的矩陣乘法。
int aRow = 6; int aCol = 6; int bRow = 6; int bCol = 6; //第一個矩陣 int matrix_a[aRow][aCol] = { {1,3,2,6,5,4}, {6,2,4,3,5,1}, {2,1,3,4,5,6}, {5,2,3,4,1,6}, {4,2,3,1,5,6}, {3,2,1,4,6,5}, }; //第二個矩陣 int matrix_b[bRow][bCol] = { {3,3,2,1,5,4}, {1,2,4,3,5,5}, {2,1,9,4,5,2}, {5,2,6,4,1,1}, {4,7,3,1,5,5}, {3,8,1,4,6,4}, }; int matrix_c[6][6]; //將矩陣的元素初始化為0 for(autoi = 0; i < aRow; i++) { for(autoj = 0; j < bCol; j++) { matrix_c[i][j] = 0; } } for(autoi = 0; i < aRow; i++) { for(autoj = 0; j < bCol; j++) { for(autok = 0; k < bRow; k++) { matrix_c[i][j] += matrix_a[i][k] * matrix_b[k][j]; } } }
這種實現可以完成計算,但是計算性能往往比較差。矩陣乘法的計算性能有很多優化方式,這些優化可以提升硬件在計算過程中的運行速度。第7章會詳細介紹如何更高效地優化矩陣乘法的計算性能。
矩陣的乘法計算過程可以被分割成小塊。例如,上面代碼片段中的兩個矩陣可以表示為下式,它們都可以被拆分為四個小塊(如圖2-11所示),分成對稱的區塊后,矩陣乘法法則同樣適用。

圖2-11 矩陣分塊

將矩陣分塊后得到子矩陣組,對它們做矩陣乘法,如下式所示。

深度學習程序是計算密集型的,在設計代碼時往往需要考慮較多細節,以取得最佳性能,減小不必要的資源消耗。在卷積神經網絡的運算過程中,使用廣義矩陣乘法(GEMM)計算卷積是早期深度學習框架的一個普遍做法,雖然有些新計算方式有后來居上的勢頭,但是廣義矩陣乘法仍然是非常重要的基礎知識。