Bootstrap

深度学习--神经网络权重初始化

背景知识:
高斯分布:
 f(x)=12πσexp((xμ)22σ2)

使用标准高斯分布对权重和偏向进行初始化

问题:会导致学习速度慢

根据独立标准高斯分布变量来选择权重和偏置,  μ=0  σ=1
标准高斯分布概率密度函数曲线:

这里写图片描述

假设神经网络有1000个输入,并使用标准高斯分布初始化了连接第一个隐藏层的权重,现在只看该层的连接权重:
该层神经元的输入  z=jwjxj+b0
这里写图片描述

假设使用的输入x,一半的输入神经元值为1,其余为0,则  jwjxj 就是500个标准高斯分布的随机变量的和.所以:
 E(jwjxj)=0  
 D(jwjxj)=500×1500

可得:

 μ=E(z)=E(jwjxj+b0)=0  
 σ2=D(z)=D(jwjxj+b0)=500×1+1501

则该层神经元的输入z的概率密度函数为:

 f(x)=12π×501exp(x22×501)

概率密度函数曲线:

这里写图片描述

可以看到z有一个非常宽的高斯分布,z有很大的比例会分布在|z|>>1的区域,即z>>1或z<<-1.此时由激活函数  σ() (采用sigmoid函数)的图像可以看出:

这里写图片描述

隐藏神经元的输出  σ(z) 就会接近0或1,使隐藏层神经元达到饱和.此时对神经元权重进行微小调整只能给神经元的激活值带来非常微弱的变化.结果,在进行梯度下降算法时会导致神经网络学习缓慢.

code2中使用标准高斯分布对权重和偏向进行初始化:

    # 使用均值=0 标准差=1的高斯分布,对权重和偏向进行初始化
    def large_weight_initializer(self):
        self.biases = [np.random.randn(y, 1) for y in self.sizes[1:]]
        self.weights = [np.random.randn(y, x) for x, y in zip(self.sizes[:-1], self.sizes[1:])]

改进方法

使用  μ=0  σ=1nin 高斯分布的随机值,对权重和偏向进行初始化

此时  nin=1000  即  σ=11000
仍假设输入为500个1和500个0,该层神经元的输入  z=jwjxj+b0
所以:

 E(jwjxj)=0  
 D(jwjxj)=500×110000.5

可得:

 μ=E(z)=E(jwjxj+b0)=0  
 σ2=D(z)=D(jwjxj+b0)=500×11000+11.5

则该层神经元的输入z的概率密度函数为:

 f(x)=12π×1.5exp(x22×1.5)

概率密度函数曲线:

这里写图片描述

可以看到z有一个非常窄的高斯分布.
将横坐标拉伸可以看到:

这里写图片描述

大部分z的分布集中在-1到1之间,避免了使隐藏层神经元达到饱和,由激活函数图像可以看到:

这里写图片描述

在-1到1区间上  σ(z) 的斜率非常大,对神经元权重进行微小调整能给神经元的激活值带来非常明显的变化,解决了神经网络学习缓慢的问题.

code2中使用  μ=0  σ=1nin 高斯分布的随机值,对权重和偏向进行初始化

    # 从正太分布(均值=0,标准差=1/sqrt(n_in))随机赋值,对权重和偏向进行初始化
    def default_weight_initializer(self):
        # 第一层为输入层不设置偏差,从第二行开始
        self.biases = [np.random.randn(y, 1) for y in self.sizes[1:]]
        # 在同一个神经元的权值的平方根的平方根上用高斯分布平均0和标准偏差1初始化每个权值
        self.weights = [np.random.randn(y, x)/np.sqrt(x) for x, y in zip(self.sizes[:-1], self.sizes[1:])]

悦读

道可道,非常道;名可名,非常名。 无名,天地之始,有名,万物之母。 故常无欲,以观其妙,常有欲,以观其徼。 此两者,同出而异名,同谓之玄,玄之又玄,众妙之门。

;