Tensorflow的LRN是怎么做的
LRN全称是local response normalization,局部响应归一化,想了解原理的点这个AlexNet(http://papers.nips.cc/paper/4824-imagenet-classification-with-deep-convolutional-neural-networks)。
看了Alex写的论文,里面介绍了LRN,稀里糊涂的,第一遍根本没看懂,于是我就想,先看看tensorflow怎么做的LRN吧,然后我就看明白了,但我貌似讲不太明白。。。。首先,公式是这样的:
LRN
其次,官方API的介绍是这样的:
sqr_sum[a, b, c, d] = sum(input[a,b, c, d - depth_radius : d + depth_radius + 1] ** 2) output = input / (bias +alpha * sqr_sum) ** beta
以alexnet的论文为例,输入暂且定为 [batch_size, 224, 224, 96],这里224×224是图片的大小,经过第一次卷积再经过ReLU,就是LRN函数的输入。
注意上面API说明里的sum函数,意思就是,可能解释起来比较拗口,针对batch里每一个图的后3维向量,[224, 224, d - depth_radius : d + depth_radius + 1],对它按照半径 depth_radius求每个图里的每个像素的平方,再把这2× depth_radius+1个平方过后的图片加起来,就得到了这个batch的sqr_sum。
不得不说,上面一段解释太差强人意了,貌似还不太对,于是我又思考了一下,从新解释,顺便给出一个小程序以验证,程序如下:
import numpy as npimport tensorflow as tf a = 2 * np.ones([2, 2, 2, 3]) b = tf.nn.local_response_normalization(a, 1, 0, 1, 1) sess = tf.Session()print sess.run(b)
为了简化,上面的程序中令depth_radius=1,bias=0,alpha=1,beta=1,这样算出的结果就相当于:
output = input / sqr_sum
实际运行的结果是这样的:
# a的原始值
array([[[[ 2., 2., 2.],
[ 2., 2., 2.]],
[[ 2., 2., 2.],
[ 2., 2., 2.]]],
[[[ 2., 2., 2.],
[ 2., 2., 2.]],
[[ 2., 2., 2.],
[ 2., 2., 2.]]]]
# a经过LRN之后的值
array([[[[ 0.25 , 0.16666667, 0.25 ],
[ 0.25 , 0.16666667, 0.25 ]],
[[ 0.25 , 0.16666667, 0.25 ],
[ 0.25 , 0.16666667, 0.25 ]]],
[[[ 0.25 , 0.16666667, 0.25 ],
[ 0.25 , 0.16666667, 0.25 ]],
[[ 0.25 , 0.16666667, 0.25 ],
[ 0.25 , 0.16666667, 0.25 ]]]], dtype=float32)
这样就很明显了,针对上面的例子,解释如下:
先求某个图(就叫图A吧)周围1半径内(这个半径在第四个维度上,包括图A本身)的图的像素的平方和S,S是三个图像素平方和相加的结果,S的shape是[2, 2],然后A除以S,如下
A = [[2, 2], S = [[12, 12], [2, 2]] [12, 12]] O = A/S = [[0.16666667, 0.16666667], [0.16666667, 0.16666667]]
这就是上面0.16666667这个数的由来了,总的来讲,当depth_radius=1,bias=0,alpha=1,beta=1时,LRN就是“每个图”除以“半径以内的其他图对应像素的平方和”,就是结果啦!
只能解释到这里了。。
最后还想再说一句,根据Stanford的CS231(http://cs231n.github.io/)所讲,最近LRN用的并不多,因为效果不好吧。
- 技能 | R语言的igraph画社交关系图示例
- 魔兽世界中招:一条命令行就能劫持你的游戏!
- R语言 apply函数家族详解
- 基于R语言的梯度推进算法介绍
- R语言数据可视化综合指南
- 关于CLR内存管理一些深层次的讨论[上篇]
- 关于CLR内存管理一些深层次的讨论[下篇]
- Python渗透工具的架构探讨
- 提供第三种代码生成方式——通过自定义BuildProvider为ASP.NET提供代码生成
- 小心,Android木马工具SpyNote免费啦!远程监听就是这么简单
- R语言的kmeans客户细分模型聚类
- .NET的资源并不限于.resx文件,你可以采用任意存储形式[下篇]
- 量化投资教程:用R语言打造量化分析平台
- 也谈事件(Event)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Ubuntu20的tzselect设置时间失效的问题,树莓派服务器(推荐)
- 安装Ubuntu 20.04后要做的事(小白教程)
- Ubuntu20.04安装Python3的虚拟环境教程详解
- Android编程实现播放视频时切换全屏并隐藏状态栏的方法
- Android UI设计与开发之仿人人网V5.9.2最新版引导界面
- PopupWindow使用方法详解
- Android 中cookie的处理详解
- Android UI设计与开发之ViewPager仿微信引导界面以及动画效果
- Android UI设计与开发之ViewPager介绍和简单实现引导界面
- Android RollPagerView实现轮播图
- Android UI设计与开发之使用ViewPager实现欢迎引导页面
- Android ListView里控件添加监听方法的实例详解
- Android实现底部图片选择Dialog
- AndroidImageSlider实现炫酷轮播广告效果
- Android获取手机本机号码的实现方法