Internal Covariate Shift:每一次參數迭代更新后,上一層網絡的輸出數據經過這一層網絡計算后,數據的分布會發生變化,為下一層網絡的學習帶來困難(神經網絡本來就是要學習數據的分布,要是分布一直在變,學習就很難了)
Covariate Shift:由於訓練數據和測試數據存在分布的差異性,給網絡的泛化性和訓練速度帶來了影響。
歸一化的效果圖:
BatchnormBatchnorm是歸一化的一種手段,極限來說,這種方式會減小圖像之間的絕對差異,突出相對差異,加快訓練速度。
若將每一層輸出后的數據都歸一化到0均值,1方差,滿足正太分布,其完全學習不到輸入數據的特征,因為,費勁心思學習到的特征分布被歸一化了。
加入可訓練的參數做歸一化,那就是BatchNormBatchNorm實現的了。
β 和γ分別稱之為平移參數和縮放參數 。這樣就保證了每一次數據經過歸一化后還保留的有學習來的特征,同時又能完成歸一化這個操作,加速訓練。
def Batchnorm_simple_for_train(x, gamma, beta, bn_param): """ param:x : 輸入數據,設shape(B,L) param:gama : 縮放因子 γ param:beta : 平移因子 β param:bn_param : batchnorm所需要的一些參數 eps : 接近0的數,防止分母出現0 momentum : 動量參數,一般為0.9, 0.99, 0.999 running_mean :滑動平均的方式計算新的均值,訓練時計算,為測試數據做准備 running_var : 滑動平均的方式計算新的方差,訓練時計算,為測試數據做准備 """ running_mean = bn_param['running_mean'] #shape = [B] running_var = bn_param['running_var'] #shape = [B] results = 0. # 建立一個新的變量 x_mean=x.mean(axis=0) # 計算x的均值 x_var=x.var(axis=0) # 計算方差 x_normalized=(x-x_mean)/np.sqrt(x_var+eps) # 歸一化 results = gamma * x_normalized + beta # 縮放平移 running_mean = momentum * running_mean + (1 - momentum) * x_mean running_var = momentum * running_var + (1 - momentum) * x_var #記錄新的值 bn_param['running_mean'] = running_mean bn_param['running_var'] = running_var return results , bn_param
batchnorm mean var 是根據樣本計算出來的,而不是反向傳播計算而來的
在訓練過程中,mean var參數的更新由原來的running_mean*0.9加上新計算的x_mean*0.1
batchnorm的優點:
1.較大的學習率極大的提高了學習速度。
2.batchnorm本身也是一種正則方式,可以代替其他的正則化方法,如dropout。
3.batchnorm降低了數據之間的絕對差異,更多的考慮相對差異,在分類任務上有更好的效果。