1. 公式介绍
首先论文中已经有了公式的介绍,但是刚看的时候会觉得有些懵,先看看LRN的定义:
第一眼看上去公式好像很复杂,我一开始也这么觉得。。。后来细看了两边之后发现好像跟某种公式有着差不多的结构,具体什么公式也不记得了,就觉得很像,然后比较好理解了,总之大概意思就是求某一个值在整体值中的占比。
b
i
=
a
i
/
∑
i
n
a
i
2
b_{i} = a_{i}/\sqrt {\sum^n_{i} a_{i}^2}
bi=ai/i∑nai2
然后再来看文章中的这个公式,这里直接根据我的理解举个实际的栗子吧,看栗子比较简单。
就拿这个图举例子吧,首先是一个三通道(3 channels)的图像输入,经过6个kernel的卷积得到了6张feature map,这是前提条件,然后来看文章中的公式。
首先先解释一下每个参数的意思(所有解释都建立在博主的理解之上,如有错误感谢指出):
- a,也就是卷积+ReLU后的输出值,对应feature map上的一个格子;
- b,LRN计算的输出值;
- i,第i个kernnel,这个kernel卷积形成了第i个feature map;
- N,feature map的总数,在上栗中,N=6;
- (x,y),这个根据论文来看应该是输入图片中像素(x,y)的位置(position);
- 其余的都是超参数,其中最重要的就是n,下面会解释。
现在知道了式子中参数的含义,就来通过栗子解释一下这个图在干嘛,首先假设我们取i=3、n=2。
如图所示,这个i=3就相当于是第三个feature map。
然后n=2是什么意思呢?根据公式中求和符号的上下方表达式可以看出,这个n的意思就是在第i个feature map的前后各取n/2个feature map来与这第i个feature map做运算。n=2也就是在第3个feature map前后各取一个,也就是下图中红色剪头所指的fm。
然后这个公式的意思就相当于是在fm的深度方向做一个归一化,求取第i个fm在其周围几个fm中的占比进行输出。
然后从名字上也可以看出一些意思(LRN,局部响应归一化),局部的意思应该就是指某一个(第i个)fm周边的几个fm之间做归一化,而不涉及全体fm,所以是局部;相应应该就是经过卷积+ReLU后的响应值所做的归一化;至于归一化,应该就不用解释了!
本文是我个人的理解,如果有错误感谢指出!然后后面好像有论文指出AlexNet中用到的这个LRN实际上是没卵用的,除了消耗更多的内存和时间!^ _ ^,具体对不对,大佬说了算!
2. 代码实现
后面在看代码的时候,看到Github上是这样写的:
在那一瞬间,我又凌乱了,这个nn.AvgPool3d操作,在所有系数相加之后还要除以一个元素个数啊!!!可是原公式里是直接平方和,并没有除以个数啊!!!看了一晚上,也没看出来为什么要这么写,后来偶然在博客里面看到,caffee的实现就是上面那段代码,除以了个数n,而tensorflow则是用的原论文公式!!!我。。。下图第一张是tf里面用的公式,第二个是caffee,github上的代码就是用的caffee的公式,我xx。。。浪费这么久时间
然后对比这篇博客tensorflow中的lrn函数详解中tf的lrn实现,对github上的代码进行了修改(也就是改掉了除以m的那一行),改成tf也就是原论文的实现方式然后在notebook里测试了一下,结果如下:
然后是结果对比,第一张图是修改Github代码后跑的结果,第二章是上面提到的博客中的结果
数值已经非常接近了,至于这些误差应该是来源于计算公式和浮点数精度吧,不过至少证明了我一晚上是白想了!!!
3. cs231n的cifar10数据集测试
正好cs231n里面assignment2的最后一段自己写代码还没做,就直接套用了alexnet的结构试了一下,先是嫌麻烦,没加LRN的网络,下面是训练截图:
3.1 简化AlexNet测试(无LRN)
3.2 带LRN的AlexNet测试
3.3 不严谨结论
果不其然,加了LRN好像真没什么卵用,除了让训练时间增加了大约20s,测试正确率不相上下,不过这里只跑了一次,没有用大量实验来做支撑,没什么说服力,不过就这样来看好像并没有太大的提升!