深度学习模型训练的过程本质是对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. opencv3 学习笔记(一)

    1.cv2.imread(path,cv2.IMREAD_ANYCOLOR) IMREAD_ANYCOLOR=4(全彩模式)/IMREAD_GRAYSCALE=0(灰度模式)2.cv2.imwrite ...

  2. UVA 232 Corssword Answer

    题意:输入m*n大小的字符串(里面有*,*为黑格,其他为白格),然后对它编号,编号规则为从左到右,从上往下,且左边或上面没有白格(可能是黑格或越界),如下图: 注意: ①除第一次输出答案外,其余每次输 ...

  3. HOJ3237----BFS/DFS

    /* 注意两点 . 不可以使用替换可用节点为不可用节点的方法进行DFS 因为角落也可能有油,替换了就出不来.(某学长指导) . 可用通过开一个数组(例如我的b[][]数组) 用了存储到当前位置剩余最大 ...

  4. 小型资源管理器之动态添加TreeView节点

    FrmMain主界面 using System; using System.Collections.Generic; using System.ComponentModel; using System ...

  5. [QTree6]Query on a tree VI

    Description: 给你一棵n个点的树,编号1~n.每个点可以是黑色,可以是白色.初始时所有点都是黑色.下面有两种操作请你操作给我们看: 0 u:询问有多少个节点v满足路径u到v上所有节点(包括 ...

  6. 数据结构 Sunday算法

    Sunday算法是Daniel M.Sunday于1990年提出的字符串模式匹配算法.相对比较KMP和BM算法而言,简单了许多. Sunday算法的思想类似于BM算法中的坏字符思想,有点像其删减版.差 ...

  7. day3字典_字符串_文件操作

    一.知识回顾 1.jmeter怎样增加压力机:在主控机配置文件 jmeter.perperties 文件中添加对应压力的IP和对应端口,多台压力机IP用","隔开,保证所有负载机和 ...

  8. 关于多线程之GCD的一些学习要点

    GCD是当前多线程使用最方便的,也是使用比较多的. 学习GCD主要集中在一下几点: 一.队列,同步,异步 1.主队列:dispatch_get_main_queue(); 2.串行队列:dispatc ...

  9. Zepto tap 穿透bug、解决移动端点击穿透问题

    当两个层重叠在一起时,或是有个弹窗,使用Zepto的tap事件时,点击上面的一层时会触发下面一层的事件,特别是底层如果是input框时,必“穿 透”,“google”说原因是“tap事件实际上是在冒泡 ...

  10. JS膏集02

    JS膏集02 1.复习 函数也是对象 2.贪食蛇案例 <!DOCTYPE html> <html lang="en"> <head> <m ...