1. 程式人生 > >神經網路中矩陣求導術的應用

神經網路中矩陣求導術的應用

本文假設讀者熟悉一元微積分,線性代數,並已經學習過矩陣求導術:知乎專欄. 在神經網路中,矩陣求導術發揮的最重要的作用便是求lossloss對某個引數的梯度. 比如在多層神經網路(MLP)中,某一層的推導公式為al+1=g(Wal+b)a^{l+1}=g(Wa^l+b),我們就需要求losslossWWbb的導數以更新它們. 然而,WW是矩陣,bb是向量,lossloss是標量,用一元微積分的方式很難求得WWbb的梯度,尤其是有矩陣乘法運算和多層連線存在的時候. 這就迫切的需要應用矩陣求導術在神經網路中. 本文所做的就是在矩陣求導術的基礎上新增一些常用公式,並對知乎專欄中涉及不足的方面加深討論.

記法約定

  • 本文以aa表示標量,以a\bm{a} 表示列向量,以AA表示矩陣.
    • 特殊的,以JJ表示神經網路輸出和真實值間的lossloss,為標量.
    • 特殊的,以1\bm{1}或者1\vec \bm{1}表示元素全是1的列向量,列向量的維數在某題目中第一次出現時標明. 如果在題目剩餘部分未再次提及維數,則預設該題目中所有的1\bm{1}向量維數均相同,都等於第一次提及的維數.
    • 特殊的,以II表示單位矩陣.
  • 本文以ABAB表示矩陣AA和矩陣BB做矩陣乘法,以ABA\odot B表示矩陣element-wise的乘法,也稱為逐元素乘法或Hadamard product
    .
  • 逐元素乘法和矩陣乘法屬同優先順序運算,不加括號的情況下從左到右進行.
  • 本文以括號上標的形式表示神經網路中第ll層的變數,如a(l)a^{(l)}表示網路第ll層的輸出.
  • 本文統一以xx表示神經網路的輸入,雖然網路的輸入可能是向量也可能是矩陣(資料特徵維數是1時網路的輸入是向量). 這裡的xx是一個batch的資料,一個batch的資料量記為NN,每條資料的特徵維數記為DD,由於本文約定每條資料都是列向量,因此xRD×Nx \in\bm{R}^{D\times N}
  • 上述約定在常用公式和定理部分嚴格遵循,在舉例中有些許不遵循,但會清楚地說明每個符號的維度.

常用公式和定理

  1. 標量向量求導法則: df=fxTdx=tr(fxTdx)df=\frac {\partial f}{\partial \bm{x}}^Td\bm{x}=tr(\frac {\partial f}{\partial \bm{x}}^Td\bm{x})
  2. 標量矩陣求導法則: df=tr(fXTdX)df=tr(\frac {\partial f}{\partial{X}}^TdX)
  3. 常數: dc=0,dC=0d\bm{c}=0, dC=0,這裡c\bm{c}CC是相對於求導變數為常數的項.
  4. 加減法:d(X±Y)=d(X)±d(Y)d(X \pm Y)=d(X)\pm d(Y)
  5. 乘法:d(XY)=dXY+XdYd(XY)=dXY+XdY,d(XY)=dXY+Xd(Y)d(X \odot Y)=dX\odot Y+X\odot d(Y)
  6. 轉置和跡:d(XT)=(dX)T,dtr(X)=tr(dX)d(X^T)=(dX)^T,dtr(X)=tr(dX)
  7. 逐元素函式:df(X)=f(X)d(X)df(X)=f'(X)\odot d(X)
  8. 跡技巧:tr(AB)=tr(BA),tr(AT(BC))=tr(ATBTC)tr(AB)=tr(BA),tr(A^T(B\odot C))=tr(A^T \odot B^TC)
  9. 矩陣求導的複合法則:假設f=f(Y),Y=Y(X)f=f(Y),Y=Y(X),已求得fY\frac{\partial f}{\partial Y},則求fX\frac{\partial f}{\partial X}的方式是,利用標量矩陣求導法則,能夠寫出df=tr(fYTdY)=tr(fXTdX)df=tr(\frac {\partial f}{\partial{Y}}^TdY)=tr(\frac {\partial f}{\partial{X}}^TdX),然後把dYdYdXdX表示出來,代入上式消去dYdY,並進行比對,得出fX\frac {\partial f}{\partial{X}}. 注意,本方法在中間變數是向量或自變數是向量或中間變數和自變數都是向量的情況下依然適用.
  10. 多元函式運演算法則:假設f=f(U,V),U=U(X),V=V(X)f=f(U,V),U=U(X),V=V(X),則fX\frac {\partial f}{\partial{X}}應該是兩部分的和,第一部分是通過df=tr(fUTdU)=tr(fXTdX)df=tr(\frac {\partial f}{\partial{U}}^TdU)=tr(\frac {\partial f}{\partial{X}}^TdX)得到的,第二部分是通過df=tr(fVTdV)=tr(fXTdX)df=tr(\frac {\partial f}{\partial{V}}^TdV)=tr(\frac {\partial f}{\partial{X}}^TdX)得到的. 當中間變數變多時,該法則依然適用.
  11. 向量重複:由於numpy中的矩陣加法和逐元素乘法有broadcast的功能,因此numpy的加法和逐元素乘法並不要求兩個矩陣有完全相同的形狀,為了嚴謹的用數學公式表達, 通常我們需要進行一些向量重複的技巧來彌補程式碼和公式之間的差異.向量重複技巧
  12. 1\vec \bm 1與加和 1m×1TXm×n\vec \bm 1^T_{m\times 1} X_{m\times n}表示把XX按行相加,得到1×n1\times n的矩陣,程式碼如下:
    import numpy as np
    np.sum(X,axis=0)
    
    同理,Xm×n1n×1X_{m\times n}\vec \bm 1_{n\times 1}表示把XX按列相加,得到m×1m\times 1的矩陣,程式碼如下:
    import numpy as np
    np.sum(X,axis=1)
    

舉例

  1. 多層神經網路(MLP)的梯度推導

    在MLP中,每個單元(cell)的推導公式我們一般寫作:a(l)=g(W(l)a(l1)+b(l))a^{(l)}=g(W^{(l)} a^{(l-1)}+b^{(l)})