症狀:前向計算一切正常、梯度反向傳播的時候就出現異常,梯度從某一層開始出現Nan值(Nan: Not a number縮寫,在numpy中,np.nan != np.nan,是唯一個不等於自身的數)。
フォワードの計算に異常なしでも、その模型の変量をアプデートする時に異常な數字が出る。Pythonのプログラムにあるなら、Nanというもの現れることです。
根因:原因目前遇到的分為兩種,其一——你使用了power(x, a) (a < 1)這樣的算子,因為power函數這樣的算子,在梯度反向傳播階段時,求導會產生1/(x^(a-1))這樣的形式,
而如果前向時某層的某個值為0或者趨近於0的數,那么求導后,梯度為無窮大,超出表示范圍,成為Nan類型,這一類型會彌散到整個網絡直至下一輪迭代出現loss為Nan被發現。
所以,任何能導致梯度爆炸出現Nan的算子都應該重點關注,求導后才產生的‘’除零錯誤”極易被忽略,因此這一點尤其需要注意。包括ln(x),1/x,pow(x, a<1)等等。
其二——采用了歸一化操作,隱含了除零錯誤的隱患:如x = x / mean(x),能將x的分布更加接近在(0,1)之間的均勻分布,但如果一開始網絡初始化不好,導致某層輸出全為0,這樣mean(x)==0!
就會出現除零錯誤。這一點有時也是很難發現的。
その原因は、多分二つがある:一つは、power(x, a<1)また1/xまたln(x)といろいろタイプの操作を使われて、あるときに計算結果はゼロ存在して、そして、
その微分は數の範囲にいないものが出ていく。
その二つは、normalizationという操作です。実はこれまた「1/x」というかたちの操作だね。x = x / np.mean(x)なんというプログラムは、
こういうの異常を引いたときはたくさん見ました。