前言
设置什么样的初始值关系到神经网络学习能否成功。上一节说到权重初始值不能设为0
一、激活层的激活值分布
激活层的激活值指的是激活函数的输出数据。权重初始值会影响激活值。
示例:
import numpy as np
import matplotlib.pyplot as plt
def sigmoid(x):
return 1 / (1 + np.exp(-x))
def ReLU(x):
return np.maximum(0, x)
def tanh(x):
return np.tanh(x)
input_data = np.random.randn(1000, 100) # 1000个数据
node_num = 100 # 各隐藏层的节点(神经元)数
hidden_layer_size = 5 # 隐藏层有5层
activations = {} # 激活值的结果保存在这里
x = input_data
for i in range(hidden_layer_size):
if i != 0:
x = activations[i-1]
#当i=0时,activations是空的,所以不执行该语句
#当i=1时,activations有上一轮输出的z,此时让x=上一轮的z
# 改变初始值进行实验!
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(1.0 / node_num)
# w = np.random.randn(node_num, node_num) * np.sqrt(2.0 / node_num)
a = np.dot(x, w)
# 将激活函数的种类也改变,来进行实验!
z = sigmoid(a)
# z = ReLU(a)
# z = tanh(a)
activations[i] = z
# 绘制直方图
for i, a in activations.items():
plt.subplot(1, len(activations), i+1)
plt.title(str(i+1) + "-layer")
if i != 0: plt.yticks([], [])
# plt.xlim(0.1, 1)
# plt.ylim(0, 7000)
plt.hist(a.flatten(), 30, range=(0,1))
plt.show()
结果:
分析:
(1)神经网络有5层,每层有100个神经元。用高斯分布生成1000个数据作为输入数据,并将他们传给5层神经网络。
具体高斯分布如何生成数据见往期文章:
【知识点】np.random.randn()_Rachel MuZy的博客-CSDN博客【知识点】np.random.randn()的应用https://blog.csdn.net/mzy20010420/article/details/126820187(2)为了使各层的激活值呈现出具有相同广度的分布,一般使用如下初始值:
(3)代码分析:
先随机生成1000*100的数据,共有1000组,作为x(输入数据),定义一个空的激活值字典activations = {}
然后开始在五个隐藏层间进行循环,i = 0, 1, 2, 3,4.当i = 0进行第一次循环时,x就是一开始随机生成的数据,不再if部分进行(因为不符合条件)。此时有了activations[0]的值
然后当进行后面的循环时,令输入的x = 上一轮的输出z,即x = activations[i-1],然后再往下进行。
当5次循环执行结束后,画图。
二、ReLU的权重初始值
第一部分的初始值是以激活函数为线性函数为前提推导的,如 sigmoid 函数和 tanh 函数。但是当激活函数使用ReLU函数时,就要用专用的初始值。
此时初始值选用最后一个,即 # w = np.random.randn(node_num, node_num) * np.sqrt(2.0 / node_num)
三、Batch Normalization
为了使各层拥有适当的广度,使用Batch Normalization。它的思路是调整各层激活值的分布使其拥有适当的广度。为此,要向神经网络中插入对数据分布进行正则化的层,即Batch Normalization层。
具体而言,就是使用数据分布的均值为0,方差为1的正则化。
四、正则化
1. 权值衰减
可以通过权值衰减的方法来抑制过拟合现象,具体表述为:
该方法通过在学习过程中对大的权重进行惩罚,来抑制过拟合。很多过拟合就是因为权重参数取值过大导致的。
2. Dropout
dropout是一种在学习过程中随机删除神经玩的方法。训练时,随机选出隐藏层的神经元,然后将其删除。测试时,虽然会传递所有的神经元信号,但是对于各个神经元的输出,要乘上训练时的删除比例后再输出。
总结
本系列讲到这里就结束了。虽然在书中,还介绍了卷积神经网络、CNN、DQN等相关知识,但只是浅尝辄止,并未上升到代码、原理的层面。
这个系列只是深度学习的一个入门,在学习的过程中有不少疑问、不少错误的理解,也有许多收获。后续进一步的深度学习还会在新的系列中继续更新。敬请期待!