《深度学习入门:基于Python的理论与实现》第6章-权重的初始化

权重的初始化

在神经网络的学习中,权重的初始值特别重要。实际上,设定什么样的权重初始值经常关系到神经网络的学习能否成功。

1 可以将权重初始化为0吗

由于神经网络的学习可能会产生过拟合的效果。所谓过拟合就是对训练数据的预测准确度非常高,但应用到其它数据集上表现的结果则非常差,称之为泛化能力不好。

一般会通过一种权值衰减的方式抑制该问题,权值衰减是一种以减小权重参数的值为目的进行学习的方法。通过减小权重参数的值来抑制过拟合的发生。

如果想减小权重的值,一开始就将初始值设置为较小的值才是正途。实际上,原书之前的权重初始值都是下面这种方式。

0.01 * np.random.randn(size1, size2)

randn会生成标准差为1的高斯分布,乘以0.01之后,就得到标准差为0.01(方差是0.0001)的高斯分布。

如果直接把参数设为0会发生什么?实际上,这样会导致无法正确进行学习。

因为在误差反向传播算法中,所有的权重值都会进行相同的更新(可回顾误差反向传播实现方法)。因此,权重被更新为相同的值,这使得神经网络拥有许多不同的权重的意义丧失了。为了防止“权重均一化”(严格讲是为了瓦解权重的对称结果),建议使用随机生成的初始值。

2 隐藏层的激活值的分布

2.1 高斯分布初始化

接下来再考虑下,权重的初始化对隐藏层每层的临时输出的结果分布影响。

下面一个实验,向一个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) # 1000个数据
node_num = 100 			# 各隐藏层的节点数
hidden_layer_size = 5	# 隐藏层有5层
activations = {}		# 保存每层的临时输出

for i in range(hidden_layer_size):
	if i != 0:
		x = activations[i-1]

	# 注意这里采用标准差为1的高斯分布
	w = np.random.randn(node_num, node_num) * 1

	z = np.dot(x, w)
	a = sigmoid(z)	# sigmoid函数
	activations[i] = a

# 绘制直方图
for i, a in activations.items():
	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的数据分布会造成反向传播中梯度的值不断变小,最后消失,这个问题被称为梯度消失。层次越深的深度学习中,梯度消失的问题可能更加严重。

下面,将权重标准差设为0.01(主要就是18行位置),进行相同实验。

import numpy as np
import matplotlib.pyplot as plt

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

x = np.random.randn(1000, 100) # 1000个数据
node_num = 100 			# 各隐藏层的节点数
hidden_layer_size = 5	# 隐藏层有5层
activations = {}		# 保存每层的临时输出

for i in range(hidden_layer_size):
	if i != 0:
		x = activations[i-1]

	# 注意这里换成标准差为0.01的高斯分布
	# w = np.random.randn(node_num, node_num) * 1
	w = np.random.randn(node_num, node_num) * 0.01

	z = np.dot(x, w)
	a = sigmoid(z)	# sigmoid函数
	activations[i] = a

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

这次呈集中在0.5附近的分布。因为不像刚那样偏向0和1,因此不会发生梯度消失的问题。但是激活值仍有偏向,说明在表现力上会有问题。如果有多个神经元都输出几乎相同结果,那它们的意义就不大了,理论上也可以由一个神经元来表达这个基本相同的事情。因此激活值在分布上有所偏向会出现“表现力受限”的问题。

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

2.2 尝试Xavier初始值

Xavier的论文中,为了使各层的激活值呈现出具有相同广度的分布,推导了合适的权重尺度。推导出的结论是,如果前一层的节点数为n,则初始值使用标准差为\frac{1}{\sqrt{n}}的高斯分布。

使用Xavier初始值后,前一层的节点数越多,要设定为目标节点的初始值的权重尺度就越小。现在,使用Xavier初始值进行实验(注意19行)。

import numpy as np
import matplotlib.pyplot as plt

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

x = np.random.randn(1000, 100) # 1000个数据
node_num = 100 			# 各隐藏层的节点数
hidden_layer_size = 5	# 隐藏层有5层
activations = {}		# 保存每层的临时输出

for i in range(hidden_layer_size):
	if i != 0:
		x = activations[i-1]

	# 这里使用Xavier初始值
	# w = np.random.randn(node_num, node_num) * 1
	# w = np.random.randn(node_num, node_num) * 0.01
	w = np.random.randn(node_num, node_num) / np.sqrt(node_num)

	z = np.dot(x, w)
	a = sigmoid(z)	# sigmoid函数
	activations[i] = a

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

由图可知,越往后面的层,图像具有更广度的分布。因为各层之间传递的数据具有适当的广度,所以sigmoid函数的表现力不受限制,有望进行高效的学习。

3 使用ReLU激活函数的权重初始值

前面的激活函数是sigmoid(换成tanh也可以,而且会有更好效果),如果换成ReLU之后再来看看权重的分布。

当激活函数换成ReLu时,一般推荐使用ReLU专用的初始值——“He初始值”。当前一层的节点数为n时,He初始值使用标准差为\sqrt{\frac{2}{n}}的高斯分布。

当使用ReLU作为激活函数时,看看四个实验(1.标准差为1的高斯分布,2.标准差为0.01的高斯分布,3.Xavier初始值,4.He初始值)的分布效果。

import numpy as np
import matplotlib.pyplot as plt

def ReLU(x):
	return np.maximum(0, x)

x = np.random.randn(1000, 100) # 1000个数据
node_num = 100 			# 各隐藏层的节点数
hidden_layer_size = 5	# 隐藏层有5层
activations = {}		# 保存每层的临时输出

for i in range(hidden_layer_size):
	if i != 0:
		x = activations[i-1]

	# 标准差为1的高斯分布
	# w = np.random.randn(node_num, node_num) * 1
	# 标准差为0.01的高斯分布
	# w = np.random.randn(node_num, node_num) * 0.01
	# Xavier初始值, 标准差为sqrt(1/n)的高斯分布
	# w = np.random.randn(node_num, node_num) / np.sqrt(node_num)
	# He初始值, 标准差为sqrt(2/n)的高斯分布
	w = np.random.randn(node_num, node_num) * np.sqrt(2/node_num)

	z = np.dot(x, w)
	a = ReLU(z)	# sigmoid函数
	activations[i] = a

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

前两张图可以看到各层激活值非常小(标准差为1的几乎没有激活值)。神经网络上传递的值也非常小,说明逆向传播时的梯度也非常小。这会导致学习几乎没有进展。

然后是Xavier初始值的结果,这种情况下,随着层的加深,偏向一点点变大。实际上,层加深后,激活值的偏向变大,学习时会出现梯度消失的问题。

而He初始值,各层中分布广度相同。由于即便层加深,数据的广度也能保持不变,因此逆向传播时,也会传递合适的值。

总结一下,当激活函数使用ReLU时,权重初始值使用He初始值,当激活函数为sigmoid或tanh等s型函数时,初始值使用Xavier初始值。这是目前的最佳实践。

### 回答1: 深度学习是一种机器学习技术,可以通过模拟人类大脑的神经网络结构来实现智能决策和预测。Python是一种广泛使用的编程语言,也是深度学习中使用最多的语言之一。 如果你想入门深度学习并使用Python进行实现,可以参考一些经典的教材和资源,例如《Python深度学习》(Francois Chollet著)、《深度学习入门:基于Python理论实现》(斋藤康毅著)等。这些教材通常会介绍深度学习的基础理论Python的基本语法和深度学习框架(如TensorFlow、Keras等)的使用方法,同时也会提供一些实例代码和练习题帮助你快速上手。 此外,你也可以通过在线课程和MOOC平台学习深度学习Python编程。例如,Coursera、Udacity和edX等平台都提供了相关课程,可以根据自己的需求和兴趣进行选择。 ### 回答2: 深度学习入门:基于Python理论实现,是一本介绍深度学习的较为全面的教程。本书主要介绍了人工神经网络,包括基于反向传播算法的多层感知器、卷积神经网络、循环神经网络等基本模型以及它们的实现方法,同时还介绍了一些高级话题,如深度强化学习、生成模型等等。 在本书中,作者通过大量的编程实例来演示深度学习的应用。这些实例包括用深度学习算法进行手写数字识别、图像分类、语音识别和自然语言处理等任务。由于Python是目前流行的机器学习工具之一,因此这本书的实现过程都使用了Python编程语言。 具体来说,本书的主要内容包括人工神经网络基础知识、多层感知器模型、卷积神经网络模型、循环神经网络模型、生成模型、 强化学习、深度学习框架等方面,同时还包括很多深度学习的应用案例。作者采用了基础理论、数学公式、实例程序和实验数据等不同形式的阐释方法,使读者既能够理解深度学习的基本原理,也能够掌握它的实现方法。 此外,本书还提供了大量的参考文献和网上资源,使读者可以进一步深入学习和研究深度学习。在阅读本书的同时,读者可以根据作者提供的代码和数据,通过实际操作来进一步巩固理论知识和应用技能。 总之,深度学习入门:基于Python理论实现是一本非常实用的深度学习教材,可以帮助初学者更好地了解深度学习的基本概念和方法,提高实际应用的技能。 ### 回答3: 深度学习是一种人工智能技术,可用于训练计算机识别和理解大量数据。《深度学习入门:基于Python理论实现》这本书是入门者学习深度学习的必读之书。以下是本书的内容概述。 本书的第一部分介绍了深度学习的基础概念和理论,包括神经网络、反向传播算法、损失函数等。介绍了基本的深度学习模型,如前馈神经网络、卷积神经网络和循环神经网络。此外,还介绍了优化算法和正则化技术。 在第二部分中,作者使用Python编程语言实现了各种深度学习模型,使用的是许多广泛使用的深度学习框架,如TensorFlow和PyTorch。学习者获得从头开始编写深度学习算法的经验,同时实际应用中必备的PyTorch和TensorFlow经验。 在第三部分中,本书涵盖了几个应用案例,包括图像分类、语音识别和自然语言处理。幸运的是,这些案例通过代码演示展示,确保即使您没有实际应用经验也能操作成功。 总的来说,《深度学习入门:基于Python理论实现》是一本适合想要学习深度学习的初学者的绝佳书籍。其提供了深度学习的基本理论和核心技术,同时应用Python编程语言演示了实现技术。由此学习者可以建立深度学习专业的技术栈和能力,在人工智能领域有更广阔的发展空间。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值