深度学习模型训练的过程本质是对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. DRF的视图

    DRF的视图 APIView 我们django中写CBV的时候继承的是View,rest_framework继承的是APIView,那么他们两个有什么不同呢~~~ urlpatterns = [    ...

  2. 理解JSON对象:JSON.parse、 JSON.stringify

    何时是JSON,何时不是JSON? JSON就是一个有特殊规则的字符串,按照这个规则我们就可以把这个字符串解析成JS对象. JSON是设计成描述数据交换格式的,他也有自己的语法,这个语法是JavaSc ...

  3. [Web]flask-excel实现excel文件下载的前后端实现

    之前同事写了前端表格导出的功能, 前后端逻辑没有梳理, 导致后端代码十分臃肿. 接手之后, 重新选择了前端table插件, 从jqxGrid变更为bootstrapTable. 本来想依赖集成的tab ...

  4. Scrapy基础(三) ------xpath基础

    xpath简介 1,使用路径表达式在xml和html中解析  2,包含标准函数路(所有库支持的xpath语法一致)      3,W3C标准 节点: <body> 第一个节点: <h ...

  5. git rewinding head to replay your work on top of it...

    git fetch origin git reset --hard origin/<branch>

  6. NOIP复习篇

    NOIP复习篇---枚举 --------------------------------------------------------------------------------------- ...

  7. [HNOI2017]礼物

    Description: 给定两个有n个数的序列,你可以将其中一个进行旋转(想象是在一个环上),或者对序列的每个数加上一个非负整数C 求操作后 \(\sum{(a_i-b_i)^2}\)的最小值 De ...

  8. python网络编程(九)

    单进程服务器-非堵塞模式 服务器 #coding=utf-8 from socket import * import time # 用来存储所有的新链接的socket g_socketList = [ ...

  9. yii2过滤器(filter)

    一.VerbFilter VerbFilter检查请求动作的HTTP请求方式是否允许执行, 如果不允许,会抛出HTTP 异常 use yii\filters\VerbFilter; public fu ...

  10. Eclipse 安装Maven插件m2eclipse

    Eclipse->Help->Install New Software->Work with右边Add按钮->Name字段中输入m2e,Location字段中输入http:// ...