深度学习模型训练的过程本质是对weight(即参数W)进行更新,这需要每个参数有相应的初始值。

有人可能会说:“参数初始化有什么难点?直接将所有weight初始化为0或者初始化为随机数!” 对一些简单的机器学习模型,或当optimization function是convex function时,这些简单的方法确实有效。

然而对于深度学习而言,非线性函数被疯狂叠加,这便是一个非凸函数,如何选择参数初始值便成为一个值得探讨的问题。

研究的目的是:选择更适合的初始化方法,使得目标函数更容易被优化。

初始化为0

如果所有参数都被初始化为0,那么所有神经元的输出将是相同的,反向传播时每一层内所有的神经元的梯度也是相同的,这显然是一个不可行的方案。

预训练

pre-training是早期训练神经网络的有效初始化方法。第一步,将神经网络的每一层取出来,构建auto-encoder做训练,使得输入层和输出层保持一致。在这个过程中参数得到更新,形成初始值;第二步,将每一层放回神经网络中,使用训练数据fine-tuning网络。

随着数据量的增加以及activation function的发展,这种方案已很少采用,大家直接奔着训练的主题去了。现在我们往往是拿任务A(imagenet竞赛)中训练好的模型(可称为pre-training model),将其放在任务B上做fine-tuning。

random initialization

随机初始化,是最容易想到的方案。但是一旦随机分布选择不当,会导致网络优化陷入困境。

data = tf.constant(np.random.randn(2000, 800))
layer_sizes = [800 - 50 * i for i in range(0,10)]
num_layers = len(layer_sizes) fcs = [] # To store fully connected layers' output
for i in range(0, num_layers - 1):
X = data if i == 0 else fcs[i - 1]
node_in = layer_sizes[i]
node_out = layer_sizes[i + 1]
W = tf.Variable(np.random.randn(node_in, node_out)) * 0.01
fc = tf.matmul(X, W)
fc = tf.nn.tanh(fc)
fcs.append(fc)

这里我们创建了一个10层的神经网络,非线性变换为tanh,每一层的参数都是随机正态分布,均值为0,标准差为0.01。每一层输出值分布的直方图:

随着层数的增加,网络输出迅速向0靠拢。在反向传播中,根据链式法则,梯度等于当前输入x(上一层的输出)乘以后一层的梯度,x趋向于0,意味着梯度将很小,参数更新缓慢。

调整初始化策略,增加方差:

W = tf.Variable(np.random.randn(node_in, node_out))

均值仍然为0,标准差现在变为1,此时每一层输出值分布的直方图:

此时,所有值会集中到-1或1附近,神经元饱和saturated了,也就是说tanh在-1和1附近的gradient都接近0,参数亦难更新。

Xavier initialization

泽维尔初始化的基本思想是:保持输入和输出的方差一致。注意:Xavier推到过程是基于线性函数的,但是它在非线性的神经元中依然表现不错。

W = tf.Variable(np.random.randn(node_in, node_out)) / np.sqrt(node_in)

输出值在很多层之后依然保持着良好的分布,这很有利于我们优化神经网络!之前谈到Xavier是在线性函数上推导得出,这说明它对非线性函数并不具有普适性,所以这个例子仅仅说明它对tanh很有效,那么对于目前最常用的ReLU神经元呢?

W = tf.Variable(np.random.randn(node_in, node_out)) / np.sqrt(node_in)
...
fc = tf.nn.relu(fc)

前面看起来还不错,但是后面的趋势却是越来越接近0。幸运的是,He initialization可以用来解决ReLU初始化的问题。

He initialization

He initialization的思想是:在ReLU网络中,假定每一层有一半的神经元被激活,另一半为0,所以,要保持variance不变,只需要在Xavier的基础上再除以2。

W = tf.Variable(np.random.randn(node_in,node_out)) / np.sqrt(node_in/2)
...
fc = tf.nn.relu(fc)

效果得到了很大改善。

Batch Normalization Layer

BN是一种巧妙又粗暴的方法,可以来削弱bad initialization的影响。在网络传播中,我们想要的是在非线性activation之前,输出值应该有较好的分布(如高斯分布),以便于反向传播时计算梯度。BN的做法就是将输出值强制做一次高斯归一化和线性变换。BN的知识可以参考LRN和Batch Norm

随机初始化,有Batch Normalization:

W = tf.Variable(np.random.randn(node_in, node_out)) * 0.01
...
fc = tf.contrib.layers.batch_norm(fc, center=True, scale=True, is_training=True)
fc = tf.nn.relu(fc)

很容易看到,Batch Normalization的效果非常好。

参考

Xavier initialization是由Xavier Glorot et al.在2010年提出,He initialization是由Kaiming He et al.在2015年提出,Batch Normalization是由Sergey Ioffe et al.在2015年提出。

进一步聊聊weight initialization的更多相关文章

  1. [深度学习] 权重初始化--Weight Initialization

    深度学习中的weight initialization对模型收敛速度和模型质量有重要影响! 在ReLU activation function中推荐使用Xavier Initialization的变种 ...

  2. (转载)深度学习的weight initialization

    本文转自:谷歌工程师:聊一聊深度学习的weight initialization TLDR (or the take-away) Weight Initialization matters!!! 深度 ...

  3. [CS231n-CNN] Training Neural Networks Part 1 : activation functions, weight initialization, gradient flow, batch normalization | babysitting the learning process, hyperparameter optimization

    课程主页:http://cs231n.stanford.edu/   Introduction to neural networks -Training Neural Network ________ ...

  4. 深度学习 weight initialization

    转自: https://www.leiphone.com/news/201703/3qMp45aQtbxTdzmK.htmla https://blog.csdn.net/shuzfan/articl ...

  5. Coursera Deep Learning 2 Improving Deep Neural Networks: Hyperparameter tuning, Regularization and Optimization - week1, Assignment(Initialization)

    声明:所有内容来自coursera,作为个人学习笔记记录在这里. Initialization Welcome to the first assignment of "Improving D ...

  6. (原)torch的训练过程

    转载请注明出处: http://www.cnblogs.com/darkknightzh/p/6221622.html 参考网址: http://ju.outofmemory.cn/entry/284 ...

  7. [Hinton] Neural Networks for Machine Learning - Converage

    Link: Neural Networks for Machine Learning - 多伦多大学 Link: Hinton的CSC321课程笔记 Ref: 神经网络训练中的Tricks之高效BP ...

  8. Understanding the Effective Receptive Field in Deep Convolutional Neural Networks

    Understanding the Effective Receptive Field in Deep Convolutional Neural Networks 理解深度卷积神经网络中的有效感受野 ...

  9. Convolutional Neural Networks for Visual Recognition 5

    Setting up the data and the model 前面我们介绍了一个神经元的模型,通过一个激励函数将高维的输入域权值的点积转化为一个单一的输出,而神经网络就是将神经元排列到每一层,形 ...

随机推荐

  1. [OC] Block的使用

    由ControllerA跳转到controllerB,在controllerB中选择一个参数的值,并将它传回给controllerA. 首先,在controllerB的.h文件中写入: @interf ...

  2. js的cookie和sesession详解

    会话(Session)跟踪是Web程序中常用的技术,用来跟踪用户的整个会话.常用的会话跟踪技术是Cookie与Session.Cookie通过在客户端记录信息确定用户身份,Session通过在服务器端 ...

  3. 在Node.js使用Promise的方式操作Mysql

    最近在学习Node.js,虽然早就听说了回调地狱结果过了一周就遇到了.所以花时间学习了了一下Promise.虽然还有Async/await.co.生成器等选择,但是因为本人基础较差,以及时间问题所以决 ...

  4. ARC101E - Ribbons on Tree

    题目链接 ARC101E - Ribbons on Tree 题解 令边集\(S \subseteq E\) 设\(f(S)\)为边集S中没有边被染色的方案数 容斥一下,那么\(ans = \sum_ ...

  5. entity framework core 2.0 & sqlite 配置教程

    我用的是vs2017,需要下载.net core 2.0 sdk. .net core 下载地址:点我下载 1.在Visual Studio之中创建一个.net core的控制台项目 2.修改cspr ...

  6. Dead Fraction [POJ1930]

    题意: 很有意思的一道题,,将一个无限循环小数转化成分母最小的精确分数值....,循环的部分不一定是最后一位. Sample Input 0.2... 0.20... 0.474612399... 0 ...

  7. day8网络编程,面向对象1

    一.只是回顾 1.导入模块的顺序,首先从当前目录下找,再从环境变量里面找,使用"sys.path.insert(0,'需要导入的环境变量')"加入需要导入文件的环境变量; 2.如果 ...

  8. Python标准库12 数学与随机数

    想用高斯分布生成随机数,在网上看到很强大的总结,保留一下,以备后用 https://www.cnblogs.com/vamei/archive/2012/10/26/2741702.html

  9. vue-cli webpack2项目打包优化

    减小文件搜索范围 配置 resolve.modules Webpack的resolve.modules配置模块库(即 node_modules)所在的位置,在 js 里出现 import 'vue' ...

  10. Could not commit JPA transaction RollbackException: Transaction marked as rollbackOnly

    项目调试时,报以下错误: org.springframework.transaction.TransactionSystemException: Could not commit JPA transa ...