ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

机器学习 神经网络权重初始值设置

2022-04-05 14:32:22  阅读:248  来源: 互联网

标签:node plt 权重 初始值 神经网络 num key np


关于神经网络权重初始值的设置的研究

    • 一、权重初始值
    • 二、权重初始值会影响隐藏层的激活值分布
    • 三、Xavier初始值
    • 四、He初始值
    • 五、基于MNIST数据集的权重初始值的比较

 

一、权重初始值

权值衰减—抑制过拟合、提高泛化能力。

所谓权值衰减,即,以减小权重参数的值为目的进行学习。

所以说人们一开始,就想把权重初始值设置的比较小。

在这里插入图片描述

那如果权重初始值全设为0或者一样的值呢?那可不行,如果输入层权重为0,那么第二层神经元都到的全是0,如果第二层是乘法节点,拿上图举例子,x=y=0,所以返回来的两个梯度是一个样的。就没意义了。所有权重共同进退有何意义?权重共同进退,术语叫做权重均一化。

二、权重初始值会影响隐藏层的激活值分布

先看斯坦福大学做的一个实验:

向一个5层神经网络传入随机生成的输入数据,用直方图绘制各层激活值的数据分布。

实验目的是通过改变标准差,观察激活值的分布如何变化。

实验代码:

这个实验各层激活值的结果保存在activations变量中。

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]

    # 改变初始值进行实验!
    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的高斯分布时,激活值的分布,w = np.random.randn(node_num, node_num) * 1。

在这里插入图片描述

再看使用的权重初始值是标准差为0.01的高斯分布时,激活值的分布:

在这里插入图片描述

看到,使用的权重初始值是标准差为1的高斯分布时,激活值偏向0和1的分布。这会导致,随着输出不断靠近0或1,导数的值逐渐接近0,反向传播中梯度的值不断变小,最后会消失。这就是所谓的梯度消失。

使用的权重初始值是标准差为0.01的高斯分布时,不会发生梯度消失,但是激活值分布偏向0.5,说明表现力有大问题。如果100个神经元输出都几乎相同,那我可以用1个神经元表达100个神经元干的事。术语,所谓的表现力受限问题。

三、Xavier初始值

Xavier提出:如果前一层的节点数为n,则初始值使用标准差为根号n分之一的分布。

代码里就这句话,w = np.random.randn(node_num, node_num) * np.sqrt(1.0 / node_num)

效果如下:呈现了比之前更有广度的分布。

在这里插入图片描述

Xavier的初始值是以激活函数是线性函数为前提而推导得出。

四、He初始值

Kaiming He提出,当前一层的节点数为n时,He的初始值使用标准差为根号(n分之2)的高斯分布。

我们研究一下激活函数用ReLU时,不同权重初始值下,每一层激活值分布的区别。

权重初始值为He初始值时:

在这里插入图片描述

权重初始值为Xavier时:

在这里插入图片描述

权重初始值为标准差为0.01的高斯分布时

在这里插入图片描述

明显ReLU更适合用He初始值。因为分布广度好,表现力好。

初始值为Xavier时,随层次加深,往0那边偏,我猜,如果加深网络,会出现梯度消失现象。

五、基于MNIST数据集的权重初始值的比较

在这里插入图片描述

这个对比,揭示了,很多时候,权重初始值的设定关系到神经网络的学习能否成功。

代码:

import os
import sys

sys.path.append(os.pardir)  # 为了导入父目录的文件而进行的设定
import numpy as np
import matplotlib.pyplot as plt
from dataset.mnist import load_mnist
from common.util import smooth_curve
from common.multi_layer_net import MultiLayerNet
from common.optimizer import SGD


# 0:读入MNIST数据==========
(x_train, t_train), (x_test, t_test) = load_mnist(normalize=True)

train_size = x_train.shape[0]
batch_size = 128
max_iterations = 2000


# 1:进行实验的设置==========
weight_init_types = {'std=0.01': 0.01, 'Xavier': 'sigmoid', 'He': 'relu'}
optimizer = SGD(lr=0.01)

networks = {}
train_loss = {}
for key, weight_type in weight_init_types.items():
    networks[key] = MultiLayerNet(input_size=784, hidden_size_list=[100, 100, 100, 100],
                                  output_size=10, weight_init_std=weight_type)
    train_loss[key] = []


# 2:开始训练==========
for i in range(max_iterations):
    batch_mask = np.random.choice(train_size, batch_size)
    x_batch = x_train[batch_mask]
    t_batch = t_train[batch_mask]
    
    for key in weight_init_types.keys():
        grads = networks[key].gradient(x_batch, t_batch)
        optimizer.update(networks[key].params, grads)
    
        loss = networks[key].loss(x_batch, t_batch)
        train_loss[key].append(loss)
    
    if i % 100 == 0:
        print("===========" + "iteration:" + str(i) + "===========")
        for key in weight_init_types.keys():
            loss = networks[key].loss(x_batch, t_batch)
            print(key + ":" + str(loss))


# 3.绘制图形==========
markers = {'std=0.01': 'o', 'Xavier': 's', 'He': 'D'}
x = np.arange(max_iterations)
for key in weight_init_types.keys():
    plt.plot(x, smooth_curve(train_loss[key]), marker=markers[key], markevery=100, label=key)
plt.xlabel("iterations")
plt.ylabel("loss")
plt.ylim(0, 2.5)
plt.legend()
plt.show()

标签:node,plt,权重,初始值,神经网络,num,key,np
来源: https://www.cnblogs.com/jiangyiming/p/16102275.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有