谈谈Tensorflow的Batch Normalization

tensorflow中关于BN(Batch Normalization)的函数主要有两个,分别是:

  • tf.nn.moments
  • tf.nn.batch_normalization

关于这两个函数,官方API中有详细的说明,具体的细节可以点链接查看,关于BN的介绍可以参考这篇论文,我来说说自己的理解。
不得不吐槽一下,tensorflow的官方API很少给例子,太不人性化了,人家numpy做的就比tensorflow强。
对了,moments函数的计算结果一般作为batch_normalization的部分输入!这就是两个函数的关系,下面展开介绍!

一、tf.nn.moments函数

官方的输入定义如下:

def moments(x, axes, name=None, keep_dims=False)

解释如下:

  • x 可以理解为我们输出的数据,形如 [batchsize, height, width, kernels]
  • axes 表示在哪个维度上求解,是个list,例如 [0, 1, 2]
  • name 就是个名字,不多解释
  • keep_dims 是否保持维度,不多解释

这个函数的输出有两个,用官方的话说就是:

Two Tensor objects: mean and variance.

解释如下:

  • mean 就是均值啦
  • variance 就是方差啦

关于这个函数的最基本的知识就介绍完了,但依然没明白这函数到底是干啥的,下面通过几个例子来说明:

  • 1、计算2×3维向量的mean和variance,程序节选如下:
img = tf.Variable(tf.random_normal([2, 3]))
axis = list(range(len(img.get_shape()) - 1))
mean, variance = tf.nn.moments(img, axis)

输出的结果如下:

img = [[ 0.69495416  2.08983064 -1.08764684]
         [ 0.31431156 -0.98923939 -0.34656194]]
mean =  [ 0.50463283  0.55029559 -0.71710438]
variance =  [ 0.0362222   2.37016821  0.13730171]

有了例子和结果,就很好理解了,moments函数就是在 [0] 维度上求了个均值和方差,对于axis这个参数的理解,可以参考这里
另外,针对2×3大小的矩阵,axis还可以这么理解,若axis = [0],那么我们2×3的小矩阵可以理解成是一个包含了2个长度为3的一维向量,然后就是求这两个向量均值方差啦!多个向量的均值、方差计算请自行脑补。
当然了,这个例子只是一个最简单的例子,如果换做求形如“[batchsize, height, width, kernels]”数据的mean和variance呢?接下来来简单分析一下。

  • 2、计算卷积神经网络某层的的mean和variance
    假定我们需要计算数据的形状是 [batchsize, height, width, kernels],熟悉CNN的都知道,这个在tensorflow中太常见了,例程序如下:
img = tf.Variable(tf.random_normal([128, 32, 32, 64]))
axis = list(range(len(img.get_shape()) - 1))
mean, variance = tf.nn.moments(img, axis)

形如[128, 32, 32, 64]的数据在CNN的中间层非常常见,那么,为了给出一个直观的认识,这个函数的输出结果如下,可能输出的数字比较多。。。

mean =  [ -1.58071518e-03   9.46253538e-04   9.92774963e-04  -2.57909298e-04
             4.31227684e-03   2.85443664e-03  -3.51431966e-03  -2.95847654e-04
            -1.57856941e-03  -7.36653805e-04  -3.81006300e-03   1.95848942e-03
            -2.19231844e-03   1.88898295e-04   3.09050083e-03   1.28045678e-04
            -5.45501709e-04  -7.49588013e-04   3.41436267e-03   4.55856323e-04
             1.21808052e-03   1.71916187e-03   2.33578682e-03  -9.98377800e-04
             1.01172924e-03  -3.25803459e-03   1.98090076e-03  -9.53197479e-04
             3.37207317e-03   6.27857447e-03  -2.22939253e-03  -1.75476074e-04
             1.82938576e-03   2.28643417e-03  -2.59208679e-03  -1.05714798e-03
            -1.82652473e-03   4.51803207e-05  -1.38700008e-03   1.88308954e-03
            -3.67999077e-03  -4.22883034e-03   8.54551792e-04  -1.30176544e-04
            -1.02388859e-03   3.15248966e-03  -1.00244582e-03  -3.58343124e-04
             9.68813896e-04  -3.17507982e-03  -2.61783600e-03  -5.57708740e-03
            -3.49491835e-04   7.54106045e-03  -9.98616219e-04   5.13806939e-04
             1.08468533e-03   1.58560276e-03  -2.76589394e-03  -1.18827820e-03
            -4.92024422e-03   3.14301252e-03   9.12249088e-04  -1.98567938e-03]
variance =  [ 1.00330877  1.00071466  1.00299144  1.00269675  0.99600208  0.99615276
                0.9968518   1.00154674  0.99785519  0.99120021  1.00565553  0.99633628
                0.99637395  0.99959981  0.99702841  0.99686354  1.00210547  1.00151515
                1.00124979  1.00289011  1.0019592   0.99810153  1.00296855  1.0040164
                1.00397885  0.99348587  0.99743217  0.99921477  1.00718474  1.00182319
                1.00461221  1.00222814  1.00570309  0.99897575  1.00203466  1.0002507
                1.00139284  1.0015136   1.00439298  0.99371535  1.00209546  1.00239146
                0.99446201  1.00200033  1.00330424  0.99965429  0.99676734  0.99974728
                0.99562836  1.00447667  0.9969337   1.0026046   0.99110448  1.00229466
                1.00264072  0.99483615  1.00260413  1.0050714   1.00082493  1.00062656
                1.0020628   1.00507069  1.00343442  0.99490905]

然后我解释一下这些数字到底是怎么来的,可能对于2×3这么大的矩阵,理解起来比较容易,但是对于 [128, 32, 32, 64] 这样的4维矩阵,理解就有点困难了。
其实很简单,可以这么理解,一个batch里的128个图,经过一个64 kernels卷积层处理,得到了128×64个图,再针对每一个kernel所对应的128个图,求它们所有像素的mean和variance,因为总共有64个kernels,输出的结果就是一个一维长度64的数组啦!
手画示意图太丑了,我重新画了一个!


计算mean和variance

二、tf.nn.batch_normalization函数

官方对函数输入的定义是:

def batch_normalization(x, mean, variance, offset, scale, variance_epsilon, name=None):

关于这几个参数,可以参考这篇论文和这个博客,我这里就直接给出一个公式的截图了,如下

晦涩难懂的公式

官方对参数的解释如下


官方的解释

这一堆参数里面,我们已经知道x、mean、variance这三个,那offset和scale呢??答案是:这两个参数貌似是需要训练的,其中offset一般初始化为0,scale初始化为1,另外offset、scale的shape与mean相同。

variance_epsilon这个参数设为一个很小的数就行,比如0.001。

但是,我这里要但是一下!BN在神经网络进行training和testing的时候,所用的mean、variance是不一样的!这个博客里已经说明了,但具体怎么操作的呢?我们看下面的代码

update_moving_mean = moving_averages.assign_moving_average(moving_mean, mean, BN_DECAY)
update_moving_variance = moving_averages.assign_moving_average(moving_variance, variance, BN_DECAY)
tf.add_to_collection(UPDATE_OPS_COLLECTION, update_moving_mean)
tf.add_to_collection(UPDATE_OPS_COLLECTION, update_moving_variance)
mean, variance = control_flow_ops.cond(['is_training'], lambda: (mean, variance), lambda: (moving_mean, moving_variance))

看不懂没关系,这段代码的意思就是计算moving mean(滑动平均)、moving variance(滑动方差),然后利用 (moving_mean, moving_variance) 进行网络测试。

关于BN的完整实现,在Ryan Dahl的repository里有,名字叫做tensorflow-resnet,可以自行查看。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容