机器学习入门之 — 神经网络权值初始化

在初始化权值的时候,常用的一个函数是 np.random.randn() 函数。这个函数会产生一个均值是0,方差是1的的分布。

import numpy as np
import matplotlib.pyplot as plt

w= np.random.randn(10000)   #产生1*1w的数组
print(w.mean())
print(w.var())

plt.hist(w,bins=100)  #绘制数据分布的直方图
plt.show()

数据分布直方图,如下图所示:
绝大多数的随机数都产生在0附近,从0开始到+4和-4的区间上面,数据量越来越小。(服从正态分布)


产生的数据基本服从正态分布

但是,这样的初始化方式,放入神经网络训练的时候,在比较深的网络里面,往往效果一般。

举个例子,分析一下。

Z = weight * X+bias

我们来看一下Z的分布:
z分布在范围是(-100 -- +100 )之间。绝大多数数据分布在[-50,+50]之间。

z的分布

但是,如果我们的激活函数是sigmod的话,那么就会遇到这样一个问题。也就是梯度消失的问题。

sigmod函数

sigmod函数的导数:


image.png

以sigmoid函数为例,当z的绝对值变大时,函数值越来越平滑,趋于饱和,这个时候函数的导数趋于0。

例如,在z=2时,函数的导数约为1/10,而在z=10时,函数的导数已经变成约为1/22000,也就是说,激活函数的输入是10的时候比2的时候神经网络的学习速率要慢2200倍!

为了神经网络保持一个很好的性能,我们希望z的值绝大多数分布在[-5,+5]之间。

对于梯度消失,有很多种解决办法,比如:

  • batch normalization
  • 使用relu
  • 更改初始化的方式

这里我们只分析更改初始化的方式。有一个很有意思的trick:
一种简单的做法是修改w的分布,使得z服从均值为0、方差为1的标准正态分布。根据正太分布期望与方差的特性,将w除以sqrt(n = 输入的结点个数) 即可。

这个可以简单的理解,在正常初始化weight之后,然后给它除以权值个数的平方根。
weight= np.random.randn(inputnode_num)/np.sqrt(inputnode_num)
我的理解是,这样做的方法是将输出重新归一化到均值是0,方差是1。

调整weight的分布之后z的分布.png

如果把它放到之前的图的坐标系上面,即[-100,100]上面。效果更加明显。返回z的值的分布更加集中。

如果把它放到之前的图的坐标系上面.png
import numpy as np
import matplotlib.pyplot as plt

def show_weight_distribution():
    w= np.random.randn(10000)
    print(w.mean())
    print(w.var())
    plt.hist(w,bins=100)
    plt.show()

def train():
    train_num=1000
    z_output=[]
    for i in range(train_num):
        bias=0
        x=np.ones(1000)
        weight= np.random.randn(1000)
        z=np.sum(weight * x)+bias
        z_output.append(z)
    print (" mean : ",np.mean(z_output))     #均值是1
    print (" var  : ",np.var(z_output))      #方差是1000
    plt.hist(z_output,bins=100)
    plt.show()


def update_train():
    train_num=1000
    z_output=[]
    for i in range(train_num):
        inputnode_num=50001
        bias=0
        x=np.ones(inputnode_num)
        weight= np.random.randn(inputnode_num)/np.sqrt(inputnode_num)   #修改的地方
        z=np.sum(weight * x)+bias
        z_output.append(z)
    print (" mean : ",np.mean(z_output))    #均值是0
    print (" var  : ",np.var(z_output))     #方差是1
    plt.hist(z_output,bins=100)
    plt.show()

def update_train2():
    train_num=1000
    z_output=[]
    for i in range(train_num):
        inputnode_num=5000
        bias=0
        x=np.ones(inputnode_num)
        weight= np.random.randn(inputnode_num)/np.sqrt(inputnode_num)  #修改的地方
        z=np.sum(weight * x)+bias
        z_output.append(z)
    print (" mean : ",np.mean(z_output))  #均值是0
    print (" var  : ",np.var(z_output))   #方差是1
    plt.xlim([-100,100])
    plt.hist(z_output,bins=100)
    plt.show()

if __name__ =="__main__":
    update_train2()

关于梯度消失和梯度爆炸的问题:

梯度消失的表现:

对于下图所示的含有3个隐藏层的神经网络,梯度消失问题发生时,接近于输出层的hidden layer 3等的权值更新相对正常,但前面的hidden layer 1的权值更新会变得很慢,导致前面的层权值几乎不变,仍接近于初始化的权值。

这就导致hidden layer 1相当于只是一个映射层,对所有的输入做了一个同一映射,这是此深层网络的学习就等价于只有后几层的浅层网络的学习了。

为什么会产生这样的情况?
以下图的反向传播为例(假设每一层只有一个神经元且对于每一层)
如下公式所示:


网络结构如图所示:


可以推到出:


而sigmoid的导数如下图所示:


这样,梯度爆炸问题的出现原因就显而易见了
sigmod的导数的最大值是1/4,如果w的权值小于1 的话,那么 | sigmod‘ * w | 会小于1。如果网络有很多层的话,那么这个导数会指数倍减小。也就是前几层的权值基本上不改变。因而导致梯度消失的情况出现。

如果 | sigmod‘ * w | > 1 , (也就是w比较大的情况)(虽然这种情况很少出现)这样就是梯度爆炸的情况了。

so,小结一下:
其实梯度爆炸和梯度消失问题都是因为网络太深,网络权值更新不稳定造成的,本质上是因为梯度反向传播中的连乘效应。对于更普遍的梯度消失问题,可以考虑用ReLU激活函数取代sigmoid激活函数。

  • 由于网络太深,导致反向传播出现一个连乘的效应。梯度指数倍减小。
  • sigmod的导数两边都很小

参考:

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

推荐阅读更多精彩内容