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,以此类推