LRN全稱為Local Response Normalization,即局部響應歸一化層,LRN函數類似DROPOUT和數據增強作為relu激勵之后防止數據過擬合而提出的一種處理方法。這個函數很少使用,基本上被類似DROPOUT這樣的方法取代,見最早的出處AlexNet論文對它的定義, 《ImageNet Classification with Deep ConvolutionalNeural Networks》
i:代表下標,你要計算像素值的下標,從0計算起
j:平方累加索引,代表從j~i的像素值平方求和
x,y:像素的位置,公式中用不到
a:代表feature map里面的 i 對應像素的具體值
N:每個feature map里面最內層向量的列數
k:超參數,由原型中的blas指定
α:超參數,由原型中的alpha指定
n/2:超參數,由原型中的deepth_radius指定
β:超參數,由原型中的belta指定
背景知識:
tensorflow官方文檔中的tf.nn.lrn函數給出了局部響應歸一化的論文出處 ,詳見http://papers.nips.cc/paper/4824-imagenet-classification-with-deep-convolutional-neural-networks
為什么要有局部響應歸一化(Local Response Normalization)?詳見http://blog.csdn.net/hduxiejun/article/details/70570086
tensorflow中調用:
看一個栗子,理解上訴的參數,進而理解rln函數
import tensorflow as tf a = tf.constant([ [[1.0, 2.0, 3.0, 4.0], [5.0, 6.0, 7.0, 8.0], [8.0, 7.0, 6.0, 5.0], [4.0, 3.0, 2.0, 1.0]], [[4.0, 3.0, 2.0, 1.0], [8.0, 7.0, 6.0, 5.0], [1.0, 2.0, 3.0, 4.0], [5.0, 6.0, 7.0, 8.0]] ]) #reshape 1批次 2x2x8的feature map a = tf.reshape(a, [1, 2, 2, 8]) normal_a=tf.nn.lrn(a,2,0,1,1) with tf.Session() as sess: print("feature map:") image = sess.run(a) print (image) print("normalized feature map:") normal = sess.run(normal_a) print (normal)
你將得到輸出:
feature map: [[[[ 1. 2. 3. 4. 5. 6. 7. 8.] [ 8. 7. 6. 5. 4. 3. 2. 1.]] [[ 4. 3. 2. 1. 8. 7. 6. 5.] [ 1. 2. 3. 4. 5. 6. 7. 8.]]]] normalized feature map: [[[[ 0.07142857 0.06666667 0.05454545 0.04444445 0.03703704 0.03157895 0.04022989 0.05369128] [ 0.05369128 0.04022989 0.03157895 0.03703704 0.04444445 0.05454545 0.06666667 0.07142857]] [[ 0.13793103 0.10000001 0.0212766 0.00787402 0.05194805 0.04 0.03448276 0.04545454] [ 0.07142857 0.06666667 0.05454545 0.04444445 0.03703704 0.03157895 0.04022989 0.05369128]]]]
分析如下:
由調用關系得出 n/2=2,k=0,α=1,β=1,N=8
第一行第一個數來說:i = 0
a = 1,min(N-1, i+n/2) = min(7, 2)=2,j = max(0, i - k)=max(0, 0)=0,下標從0~2個數平方求和, b=1/(1^2 + 2^2 + 3^2)=1/14 = 0.071428571
同理,第一行第四個數來說:i = 3
a = 4,min(N-1, i+n/2) = min(7, 5 )=5, j = max(0,1) = 1,下標從1~5進行平方求和,b = 4/(2^2 + 3^2 + 4^2 + 5^2 + 6^2) = 4/90=0.044444444
再來一個,第二行第一個數來說: i = 0
a = 8, min(N-1, i+n/2) = min(7, 2) = 2, j=max(0,0)=0, 下標從0~2的3個數平方求和,b = 8/(8^2 + 7^2 + 6^2)=8/149=0.053691275
其他的也是類似操作
ps:
1、AlexNet將LeNet的思想發揚光大,把CNN的基本原理應用到了很深很寬的網絡中。AlexNet主要使用到的新技術點如下:
(1)成功使用ReLU作為CNN的激活函數,並驗證其效果在較深的網絡超過了Sigmoid,成功解決了Sigmoid在網絡較深時的梯度彌散問題。雖然ReLU激活函數在很久之前就被提出了,但是直到AlexNet的出現才將其發揚光大。
(2)訓練時使用Dropout隨機忽略一部分神經元,以避免模型過擬合。Dropout雖有單獨的論文論述,但是AlexNet將其實用化,通過實踐證實了它的效果。在AlexNet中主要是最后幾個全連接層使用了Dropout。
(3)在CNN中使用重疊的最大池化。此前CNN中普遍使用平均池化,AlexNet全部使用最大池化,避免平均池化的模糊化效果。並且AlexNet中提出讓步長比池化核的尺寸小,這樣池化層的輸出之間會有重疊和覆蓋,提升了特征的豐富性。
(4)提出了LRN層,對局部神經元的活動創建競爭機制,使得其中響應比較大的值變得相對更大,並抑制其他反饋較小的神經元,增強了模型的泛化能力。
2、為什么輸入數據需要歸一化(Normalized Data)?
歸一化后有什么好處呢?原因在於神經網絡學習過程本質就是為了學習數據分布,一旦訓練數據與測試數據的分布不同,那么網絡的泛化能力也大大降低;另外一方面,一旦每批訓練數據的分布各不相同(batch 梯度下降),那么網絡就要在每次迭代都去學習適應不同的分布,這樣將會大大降低網絡的訓練速度,這也正是為什么我們需要對數據都要做一個歸一化預處理的原因。
對於深度網絡的訓練是一個復雜的過程,只要網絡的前面幾層發生微小的改變,那么后面幾層就會被累積放大下去。一旦網絡某一層的輸入數據的分布發生改變,那么這一層網絡就需要去適應學習這個新的數據分布,所以如果訓練過程中,訓練數據的分布一直在發生變化,那么將會影響網絡的訓練速度。
參考文獻:
https://blog.csdn.net/banana1006034246/article/details/75204013
https://blog.csdn.net/u011204487/article/details/76026537
https://blog.csdn.net/yangdashi888/article/details/77918311