local response normalization最早是由Krizhevsky和Hinton在关于ImageNet的论文里面使用的一种数据标准化方法,即使现在,也依然会有不少CNN网络会使用到这种正则手段,现在记录一下lrn方法的计算流程以及tensorflow的实现,方便后面查阅
以上是这种归一手段的公式,其中a的上标指该层的第几个feature map,a的下标x,y表示feature map的像素位置,N指feature map的总数量,公式里的其它参数都是超参,需要自己指定的。
这种方法是受到神经科学的启发,激活的神经元会抑制其邻近神经元的活动(侧抑制现象),至于为什么使用这种正则手段,以及它为什么有效,查阅了很多文献似乎也没有详细的解释,可能是由于后来提出的batch normalization手段太过火热,渐渐的就把local response normalization掩盖了吧
tf.nn.local_response_normalization(input, depth_radius=None, bias=None, alpha=None, beta=None, name=None)
第一个参数input:这个输入就是feature map了,既然是feature map,那么它就具有[batch, height, width, channels]这样的shape
第二个参数depth_radius:这个值需要自己指定,就是上述公式中的n/2
第三个参数bias:上述公式中的k
第四个参数alpha:上述公式中的α
第五个参数beta:上述公式中的β
返回值是新的feature map,它应该具有和原feature map相同的shape
我们可以写一个示例程序演示TensorFlow中tf.nn.local_response_normalization方法的计算过程
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 a,get the feature map [batch:1 height:2 width:2 channels:8]
a = tf.reshape(a, [1, 2, 2, 8])
normal_a=tf.nn.local_response_normalization(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,举个例子,比如对于一通道的第一个像素“1”来说,我们把参数代人公式就是1/(1^2+2^2+3^2)=0.07142857,对于四通道的第一个像素“4”来说,公式就是4/(2^2+3^2+4^2+5^2+6^2)=0.04444445,以此类推