从零开始机器学习(八)

关于权重

权重初始化

在这里提出一个问题,可以将权重初始值设为0吗?
答案是不能。

  • 这是因为在误差反向传播法中,所有的权重值都会进行相同的更新。比如,在2 层神经网络中,假设第1 层和第2 层的权重为0。这样一来,正向传播时,因为输入层的权重为0,所以第2 层的神经元全部会被传递相同的值。第2 层的神经元中全部输入相同的值,这意味着反向传播时第2 层的权重全部都会进行相同的更新。因此,权重被更新为相同的值,并拥有了对称的值(重复的值)。这使得神经网络拥有许多不同的权重的意义丧失了。为了防止“权重均一化”(严格地讲,是为了瓦解权重的对称结构),必须随机生成初始值。
隐藏层的激活值的分布

我们来做一个简单的实验,观察权重初始值是如何影响隐藏层的激活值的分布的。这里要做的实验是,向一个5 层神经网络(激活函数使用sigmoid 函数)传入随机生成的输入数据,用直方图绘制各层激活值的数据分布。

import numpy as np
import matplotlib.pyplot as plt

def sigmoid(x):
	return 1/(1+np.exp(-x))

x = np.random.randn(1000, 100)
node_num = 100 # 隐藏层的神经元数
hidden_layer_size = 5
activations = {} # 每层激活值保存在这里。这里我们将激活函数的输出数据称为“激活值

for i in range(hidden_layer_size):
	if i != 0:
		x = activations[i-1]
	w = np.random.randn(node_num, node_num)*1
	
	z = np.dot(x, w)
	a = sigmoid(z)
	activations[i] = a

# 绘制直方图
for i, a in activations.items(): # activations是个字典
	plt.subplot(1, len(activations), i+1)
	plt.title(str(i+1)+"-layer")
	plt.hist(a.flatten(), 30, range=(0, 1))
plt.show()

可得到这样的直方图:
在这里插入图片描述
各层的激活值呈偏向0 和1 的分布。这里使用的sigmoid函数是S型函数,随着输出不断地靠近0(或者靠近1),它的导数的值逐渐接近0。因此,偏向0 和1 的数据分布会造成反向传播中梯度的值不断变小,最后消失。这个问题称为梯度消失(gradient vanishing)。层次加深的深度学习中,梯度消失的问题可能会更加严重。

将权重的标准差设为0.01,进行相同的实验,结果如图:
在这里插入图片描述
这次呈集中在0.5 附近的分布。因为不像刚才的例子那样偏向0 和1,所以不会发生梯度消失的问题。但是,激活值的分布有所偏向,说明在表现力上会有很大问题。为什么这么说呢?因为如果有多个神经元都输出几乎相同的值,那它们就没有存在的意义了。比如,如果100 个神经元都输出几乎相同的值,那么也可以由1 个神经元来表达基本相同的事情。因此,激活值在分布上有所偏向会出现“表现力受限”的问题。

  • 各层的激活值的分布都要求有适当的广度。为什么呢?因为通过在各层间传递多样性的数据,神经网络可以进行高效的学习。反过来,如果传递的是有所偏向的数据,就会出现梯度消失或者“表现力受限”的问题,导致学习可能无法顺利进行。

  • 在一般的深度学习框架中,采用了Xavier Glorot论文中提出的初始化方法,如图:
    Xavier 的论文中,为了使各层的激活值呈现出具有相同广度的分布,推导了合适的权重尺度。推导出的结论是,如果前一层的节点数为n,则初始值使用标准差为 1 n \frac{1}{\sqrt[]{n}} n 1的分布

在这里插入图片描述
像这样:
在这里插入图片描述
使用Xavier 初始值后的结果如图所示:
在这里插入图片描述
从这个结果可知,越是后面的层,图像变得越歪斜,但是呈现了比之前更有广度的分布。因为各层间
传递的数据有适当的广度,所以sigmoid 函数的表现力不受限制,有望进行高效的学习。

  • 如果用tanh函数(双曲线函数)代替sigmoid函数,这个稍微歪斜的问题就能得到改善。
  • tanh函数是关于原点(0, 0)对称的S 型曲线,而sigmoid函数是关于(x, y)=(0, 0.5) 对称的S 型曲
    线。众所周知,用作激活函数的函数最好具有关于原点对称的性质
ReLU的权重初始值

Xavier 初始值是以激活函数是线性函数为前提而推导出来的。因为sigmoid函数和tanh函数左右对称,且中央附近可以视作线性函数,所以适合使用Xavier 初始值。但当激活函数使用ReLU时,一般推荐使用ReLU专用的初始值,也就是Kaiming He等人推荐的初始值,也称为“He初始值”
当前一层的节点数为n 时,He 初始值使用标准差为 2 n \frac{2}{\sqrt[]{n}} n 2的高斯分布。当Xavier 初始值是 1 n \frac{1}{\sqrt[]{n}} n 1时,(直观上)可以解释为,因为ReLU的负值区域的值为0,为了使它更有广度,所以需要2 倍的系数

  • 现在来看一下激活函数使用ReLU时激活值的分布。我们给出了3 个实验的结果,依次是权重初始值为标准差是0.01 的高斯分布(下文简写为“std = 0.01”)时、初始值为Xavier 初始值时、初始值为ReLU专用的“He初始值”时的结果

在这里插入图片描述
观察实验结果可知,当“std = 0.01”时,各层的激活值非常小。神经网络上传递的是非常小的值,说明逆向传播时权重的梯度也同样很小。这是很严重的问题,实际上学习基本上没有进展。接下来是初始值为Xavier 初始值时的结果。在这种情况下,随着层的加深,偏向一点点变大。实际上,层加深后,激活值的偏向变大,学习时会出现梯度消失的问题。而当初始值为He初始值时,各层中分布的广度相同。由于即便层加深,数据的广度也能保持不变,因此逆向传播时,也会传递合适的值。总结一下,当激活函数使用ReLU时,权重初始值使用He初始值,当激活函数为sigmoid 或tanh 等S 型曲线函数时,初始值使用Xavier 初始值。这是目前的最佳实践。

Batch Normalization

为什么Batch Norm这么惹人注目呢?因为Batch Norm有以下优点。

  1. 可以使学习快速进行(可以增大学习率)。
  2. 不那么依赖初始值(对于初始值不用那么神经质)。
  3. 抑制过拟合(降低Dropout等的必要性)。

Batch Norm的思路是调整各层的激活值分布使其拥有适当的广度。Batch Norm,顾名思义,以进行学习时的mini-batch 为单位,按minibatch进行正规化。具体而言,就是进行使数据分布的均值为0、方差为1 的正规化。用数学式表示的话,如下所示:

在这里插入图片描述
ε 是一个微小值(比如,10e-7等),它是为了防止出现除以0 的情况。这样就将数据变为了均值为0,方差为一的数据,通过将这个处理插入到激活函数的前面(或者后面),可以减小数据分布的偏向。

接着,Batch Norm层会对正规化后的数据进行缩放和平移的变换,用数学式可以如下表示:
在这里插入图片描述
γ 和β 是参数。一开始γ = 1,β = 0,然后再通过学习调整到合适的值。
整个过程计算图如图:
在这里插入图片描述

Dropout

Dropout 是一种在学习的过程中随机删除神经元的方法。训练时,随机选出隐藏层的神经元,然后将其删除。被删除的神经元不再进行信号的传递,如下图所示:
在这里插入图片描述

从理解角度简单实现一下Dropout:

class Dropout:
	def __init(self, dropout_ratio=0.5):
		self.dropout_ratio = dropout_ratio
		self.mask = None
	def forward(self, x, train_flag=True):
		if train_flag:
			self.mask = np.random.rand(*x.shape) > self.dropout_ratio
			return x * self.mask
		else:
			return x * (1.0 - self.dropout_ratio)
	
	def backward(self, dout):
		return dout*self.mask

每次正向传播时,self.mask中都会以False的形式保存要删除的神经元。self.mask会随机生成和x形状相同的数组,并将值比dropout_ratio大的元素设为True。反向传播时的行为和ReLU相同

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

live_for_myself

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值