症状:前向计算一切正常、梯度反向传播的时候就出现异常,梯度从某一层开始出现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)なんというプログラムは、
こういうの異常を引いたときはたくさん見ました。