专栏首页人工智能LeadAIGoogLeNet的心路历程(二)

GoogLeNet的心路历程(二)

本文介绍关于GoogLeNet的续作,习惯称为inception v2,如下:

[v2] Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift,top5 error 4.8%

这篇文章做出的贡献不是一般的大,它提出了Batch Normalization(BN),以至于网上关于它的介绍铺天盖地,但中文优秀原创没几个,都是转载来转载去,挑几个好的比如:这个(http://blog.csdn.net/hjimce/article/details/50866313)、这个(http://blog.csdn.net/u012816943/article/details/51691868)、这个(http://blog.csdn.net/happynear/article/details/44238541)。我之前也写过一个谈谈Tensorflow的Batch Normalization(https://www.jianshu.com/p/0312e04e4e83),讲了讲BN在Tensorflow中的实现。

前人关于BN介绍的已经太详细了,我就不再重复的了。本文就是想讲一讲BN的反向传播,BN需要调节的参数有两个,γ 和 β,反向传播的计算方式就是下面这张图:

Batch Normalization反向传播

又是令人作呕的公式。

几乎所有介绍BN的文章都把这部分略过了,估计是怕讲不清楚,或者作者根本就不明白也不想深究。BN的理念很好理解,它的优良效果也很好理解,可BN的训练到底是怎么回事?怎么反向传播?Szegedy在论文原文里也只是一句话带过了:

During training we need to backpropagate the gradient of loss ℓ through this transformation, as well as compute the gradients with respect to the parameters of the BN transform. We use chain rule...

上面那一坨公式对于深度学习的老鸟们应该不会构成理解障碍,但对于接触不久的人群,简直就是天书!鉴于此,参考xiaia的cs231n_2016_winter(https://github.com/xiaia/cs231n_2016_winter)作业,捋一捋BN的反向传播到底是怎么实现的,好有个直观理解。

下面的介绍基于cs231n_2016_winter/assignment2的全连接网络,隐藏层5个,每个100个神经元(hidden_dims = [100, 100, 100, 100, 100]),激活函数ReLU,每个隐藏层激活函数前都加了BN层,输出层是softmax-10,optimizer是adam。

Batch Normalization反向传播实现

根据上面那一坨公式,写出来的代码是这样子的:

def batchnorm_backward(dout, cache):   
"""   
Backward pass for batch normalization.      
For this implementation, you should write out a computation graph for   
batch normalization on paper and propagate gradients backward through   intermediate nodes.      
Inputs:   
- dout: Upstream derivatives, of shape (N, D)   
- cache: Variable of intermediates from batchnorm_forward.      

Returns a tuple of:   
- dx: Gradient with respect to inputs x, of shape (N, D)   
- dgamma: Gradient with respect to scale parameter gamma, of shape (D,)   
- dbeta: Gradient with respect to shift parameter beta, of shape (D,)   
"""   
dx, dgamma, dbeta = None, None, None      
x, gamma, beta, var, miu, x_hat, eps = cache   
m = len(x)   
dx_hat = dout * gamma   
dvar = np.sum(dx_hat * (x-miu), axis=0) * -0.5 * (var + eps) ** (-1.5)   
dmiu = np.sum(dx_hat * (-1) / np.sqrt(var+eps), axis=0) + dvar * np.mean(-2 * (x - miu), axis=0)   
dx = dx_hat / np.sqrt(var + eps) + dvar * 2 * (x - miu) / m + dmiu / m   
dgamma = np.sum(dout * x_hat, axis=0)   
dbeta = np.sum(dout, axis=0)  
  return dx, dgamma, dbeta

Tensorflow的源码里应该也会有相应的实现,以后我再找找看。

上面的batchnorm_backward函数就是BN反向传播的python实现版本,仅仅是把公式改写成了python语言而已,这篇博文对代码做了一些解释,可以参考,这里不再赘述。

问题就来了,dout是个什么东西?作为函数的输入,它怎么来的?我再翻一翻源码,找到了这个函数:

def softmax_loss(x, y):   """   Computes the loss and gradient for softmax classification.    Inputs:   - x: Input data, of shape (N, C) where x[i, j] is the score for the jth class     for the ith input.   - y: Vector of labels, of shape (N,) where y[i] is the label for x[i] and     0 <= y[i] < C    Returns a tuple of:   - loss: Scalar giving the loss   - dx: Gradient of the loss with respect to x   """   probs = np.exp(x - np.max(x, axis=1, keepdims=True))   probs /= np.sum(probs, axis=1, keepdims=True)   N = x.shape[0]   loss = -np.sum(np.log(probs[np.arange(N), y])) / N   dx = probs.copy()   dx[np.arange(N), y] -= 1   dx /= N  return loss, dx

softmax_loss用来计算最后softmax层的loss和gradient,函数返回两个值,一个是loss,一个是dx(gradient),这个dx就是dout的源头!也是反向传播的最最最开始的地方!它是这么得来的:

dx = probs.copy() dx[np.arange(N), y] -= 1

注:其中probs是softmax的输出结果。

上面的程序代码是如此的简洁!让人完全蒙圈!逼得我重温了一下反向传播算法,输出层的残差是这么算的:

sigmoid输出层残差计算

代码里的f'(z)去哪儿了???或者这种计算方式是softmax独有?深深的感觉到了自己基础知识的薄弱。我又查阅了Neural Networks and Deep Learning(http://neuralnetworksanddeeplearning.com/chap3.html#problems_68177),终于找到了,其中的公式 (84) 是 softmax 层的残差计算方法,如下:

softmax 残差计算

可是作者让读者自己推倒公式!又蒙圈了,有兴趣的可以自己推倒试一试。

简而言之,dx就是最后一层的gradient,这个dx要一层一层的反向传播回去,不同层的反向传播计算方式也不同,比如ReLU的反向传播计算是这样的:

def relu_backward(dout, cache):   
"""   
Computes the backward pass for a layer of rectified linear units (ReLUs).    
Input:   
- dout: Upstream derivatives, of any shape   
- cache: Input x, of same shape as dout    Returns:   
- dx: Gradient with respect to x   
"""   
dx, x = None, cache    dx = dout   dx[x <= 0] = 0
     return dx

当然还有 dropout_backward、affine_backward(全连层) 还有上面的 batchnorm_backward 计算函数,不再一一列举。反向传播其实就是把gradient作为输入,按照前向传播相反的方向再计算一遍而已。

总的来讲,加入BN层的反向传播没有发生根本的改变,只是多了一个反向计算过程(batchnorm_backward函数)而已,上述网络的最后几层的前向和反向传播示意图如下:

正反传播

图也画了,代码也给了,公式还是没明白,不深究了。

总之,加入BN层的网络,反向传播的时候也相应的多了BN-back,其中的dgamma、dbeta会根据反向传播的gradient(或者叫残差)计算出来,再利用 optimizer 更新 γ 和 β。

本文分享自微信公众号 - 人工智能LeadAI(atleadai)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2018-03-09

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 数据分析中的可视化-常见图形

    import matplotlib.pyplot as plt import pandas as pd from pandas import Series, D...

    用户1332428
  • 计算机视觉任务:图像梯度和图像完成

    该笔记是以斯坦福cs231n课程的python编程任务为主线,展开对该课程主要内容的理解和部分数学推导。这篇文章是关于计算机视觉处理的,分为两篇文章撰写完成。此...

    用户1332428
  • 人工智能迎来第三次发展浪潮,全球人工智能产业生态系统逐步完善

    ? 2016年,人工智能经历了两起两落迎来了第三次发展浪潮,技术驱动下的人工智能从实验室走向了市场,并进入了快速发展阶段。 1950-1969 兴起阶段 ...

    用户1332428
  • Angular网站国际化处理

    angular.js 官方出了一个模块 angular-translate 来解决多语言国际化问题

    聚沙成塔
  • 2019中国计算机高引学者榜单出炉,164人入选,周志华位列第二

    全球最大学术出版商之一爱思唯尔(Elsevier),发布了2019年中国高引学者榜单。

    量子位
  • 引导式Dyna-Q用于移动机器人探索和导航(CS RO)

    基于模型的强化学习(RL)使代理能够从反复试验的经验中学习世界模型,以实现长期目标。 另一方面,自动计划可用于通过声明性行动知识进行推理来完成任务。 尽管他们有...

    时代在召唤
  • 网媒阵容豪华,里约奥运会成移动和直播新媒体竞技场

    8月5日,巴西里约将迎来举世瞩目的第31届奥运会。7月18日,中国豪华军团正式成立,规模达到711人,其中运动员400多人,是中国境外参赛史上规模最大的一届,届...

    罗超频道
  • 浅谈 C++ 元编程

    ? 随着 C++ 11/14/17 标准的不断更新,C++ 语言得到了极大的完善和补充。元编程作为一种新兴的编程方式,受到了越来越多的广泛关注。结合已有文献和...

    腾讯技术工程官方号
  • 【精华】Batch Normalization理论与实践

    batch norm也可以当做调参的一部分,对于有些实验是有效果的,有些实验是几乎没啥效果,但是它的收敛速度还是很客观的,所以我们还是有必要要了解下哒!

    zenRRan
  • spring cloud zuul网关的作用

    zuul一般有两大作用,1是类似于Nginx的网址重定向,但zuul的重定向的一般是整个spring cloud里在Eureka注册中心的模块.

    算法之名

扫码关注云+社区

领取腾讯云代金券