“深度学习”学习日记。与学习有关的技巧--权重的初始值

news2024/11/15 13:45:34

2023.1.22

在深度学习的学习中,权重的初始值特别重要。这关系到神经网络的学习能否成功;

在以前误差反向传播法和神经网络学习的算法实现这两篇文章中,对权重的初始值的确定是这样的:

class TwoLayerNet:
    def __init__(self, input, hidden, output, weight__init__std=0.01):
        # 权重的初始化 假设一个权重
        # 通过本函数可以返回一个或一组服从标准正态分布的随机样本值。平均数为0,方差为1
        self.params = {}
        self.params['w1'] = weight__init__std * np.random.randn(input, hidden)
        self.params['b1'] = np.zeros(hidden)
        self.params['w2'] = weight__init__std * np.random.randn(hidden, output)
        self.params['b2'] = np.zeros(output)

 神经网络学习算法的实现:https://blog.csdn.net/m0_72675651/article/details/128671496

误差反向传播法的算法实现:https://blog.csdn.net/m0_72675651/article/details/128729159

 都是通过一个np.random.randn( )函数去返回一个或一组服从标准正态分布的随机样本值,平均数为0,方差为1。

先说结论:有一种抑制过拟合、提高泛化能力的技巧,称为“权值衰减”。顾名思义,就是一个让权重值减小的方法去抑制过拟合、提高泛化能力;

所以我们一开始就先设置一个较小的权重都是0.01*np.random.randn( )这样的。(标准差为0.01的高斯分布)

但是,我们不能将权重设置为0,否则神经网络将无法进行学习,因为在神经网络推理处理中,输入层正向传播的权重为0,而传递给下一层神经网络的值也是0,这也意味着在反向传播更新数值时权重更新的内容全是相同的值,就代表着神经网络模型无法学习;

接下来参照教材作一个实验:

观察权重初始值时如何影响隐藏层的激活函数输入值的分布的:假设神经网络有有5层,每层100个神经元,先研究 激活函数使用sigmoid()

import numpy as np
import matplotlib.pyplot as plt


# sigmoid函数的实现
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():
    plt.subplot(1, len(activations), i + 1)
    plt.title(str(i + 1) + "-layer")
    plt.hist(a.flatten(), 30, range=(0, 1))  # 在matplotlib中,hist方法用于绘制直方图
# flatten是numpy.ndarray.flatten的一个函数,即返回一个折叠成一维的数组。但是该函数只能适用于numpy对象,即array或者mat,普通的list列表是不行的。
plt.show()


# subplot(nrows, ncols, index, **kwargs)
# subplot(pos, **kwargs)
# subplot(**kwargs)
# subplot(ax)

输出结果: 

 因为假设有1000个数据,其排列方式是1000×100的矩阵,权重是100×100的排列分布的矩阵,所以z是1000×100的矩阵,所以a.flatten()后是一个(1×100000)的一个向量;

 w = np.random.randn(node_num, node_num) * 1

”1“代表标准差为1的高斯分布,实验的目的就是通过改变这个尺度,观察权重初始值对激活函数的变化;

a经过sigmoid函数处理后成为i一个(0,1)的值;

如上图所示,他的输出不断地靠近0,1;所以他的导数逐渐接近0,在反向传播中他的梯度会不断的减小,最后消失,这样的现象,称他为“梯度消失”;层次加深的深度学习中梯度消失的问题会更加严重。

接着将标准差设置为0.01继续:

w = np.random.randn(node_num, node_num) * 1

更换成

w = np.random.randn(node_num, node_num) * 0.01

再观察结果

 

 这次a的输出值向0.5集中,并不会发生梯度消失的问题,但是,这样的激活值向一个方向偏向也是有问题的,因为如果全部神经元输出相同的值那么就没有价值了,就好比权重初始值设置为0,权重更新为相同的值,出现了权重结构对称的现象,也称为 表现力受损 的问题。

(激活函数值需要有一点的广度,神经网络2才能高效率的学习,如果是有所偏向的数值就会出现“表现力受损”、“梯度消失”的问题)

然后,现在学习Xavier值,先说结论:Xavier值是已经被作为标准使用。比如Caffe框架中,通过设定权重值时,赋予Xavier值参数,以此实现Xavier值得初始化;

简单得来说他得做法是:如果前一层得节点是n,那么初始值设置使用得标准差为 \frac{1}{\sqrt{h}}得分布;

该方法来自有Xavier得相关论文,它不仅考虑了前一层得输出节点得数量,也考虑了后一层得输出节点数量,但是,Caffe等框架得现实中进行了简化,只用前一层得输出节点数量即可。

# 因为这个实验代码每一层得节点数量都是100,所以可以简化实现过程

 

w = np.random.randn(node_num, node_num) / np.sqrt(node_num)

观察输出结果:

可以看出,越是后面得层,图像越是倾斜,也呈现了广度,sigmoid函数得表现力不受限制,能够高效得进型学习。

但是,会不会就觉得后面得图像有点抽象,所以学习了一个与sigmoid函数相同得tanh函数;

def tanh(x):
    return np.tanh(x)

使用tanh函数得输出结果:

sigmoid\left ( x \right )=\frac{1}{e^{-x}+1} ; tanh\left ( x \right ) =2sigmoid\left ( 2x \right )-1

tanh(x)得图像:关于原点对称;

 

tanh图像代码实现:

import numpy as np
import matplotlib.pyplot as plt


def tanh(x):
    return np.tanh(x)


x = np.arange(-10, 10)
y = tanh(x)

plt.plot(x, y)
plt.hlines(0, -10, 10, colors='red', linestyles='--')
plt.title('tanh')
plt.show()

 tanh函数和sigmoid函数一样都是S型曲线函数,而sigmoid函数是关于(0,0.5)对称得S型曲线。总所周知,用作激活函数得函数最好具有关于原点对称得性质。

( Xavier初始值是以激活函数是线性函数为前提而推出来的,因为sigmoid函数和tanh函数左右对称,且中央附近可以视为线性函数,所以适合Xavier初始值。)

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

当即或函数用的ReLU函数时,一般推荐时用kaiming He 提出的“He初始值”。当前一个函数节点数为n时,He初始值使用的标准差为\sqrt{\frac{2}{n}}的高斯分布;分别通过标准差为0.01,Xavier值,He值观察参数分布;

拿代码运行看结果。

import numpy as np
import matplotlib.pyplot as plt


# sigmoid函数的实现
def sigmoid(x):
    return 1 / (1 + np.exp(-x))


def tanh(x):
    return np.tanh(x)


def ReLU(x):
    return np.maximum(0, 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) / np.sqrt(node_num)  # Xavier值
    # w = np.random.randn(node_num, node_num) * 0.01 # std=0.01
    # w = (np.random.randn(node_num, node_num) * np.sqrt(2)) / np.sqrt(node_num)# He值 

    z = np.dot(x, w)
    # a = tanh(z)
    # a=sigmoid(z)
    a = ReLU(z)
    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))  # 在matplotlib中,hist方法用于绘制直方图
# flatten是numpy.ndarray.flatten的一个函数,即返回一个折叠成一维的数组。但是该函数只能适用于numpy对象,即array或者mat,普通的list列表是不行的。
plt.show()

# subplot(nrows, ncols, index, **kwargs)
# subplot(pos, **kwargs)
# subplot(**kwargs)
# subplot(ax)

当标准差为0.01时:

 各层的激活值非常小,神经网络传递的时非常小的值,反向传播的值也很小,说明权重该参数不会怎么更新,学习效果差;

当标准差为Xavier值:

 随着层的加深,偏向越来越大,会出现 梯度消失现象 ;

当标准差为He值时:

 随着层数的加深,各层中分布的广度相同,因此其逆向传播的效果也很好;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/175725.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

在2022年的最后一天我学会了哈希表

文章目录前言STL相关容器unordered_setunordered_map哈希表哈希冲突闭散列开散列STL相关容器的模拟实现用一个哈希表改造两个容器哈希表的迭代器总结前言 首先先提前祝贺大家新年快乐!本文是农历2022年的最后一篇博客。而今天我们介绍的也是STL里面重要的一个数据结…

2023年, 前端路上的开源总结(最新更新...)

19年至今, 笔者利用空余时间陆陆续续做了一些开源项目, 大部分开源项目都是以实际价值为开源基础, 所以我觉得有必要做一个总结和复盘,在复盘的过程中希望也能对大家有所帮助.今后笔者的开源项目都会放在这篇文章中,如果想学习的可以收藏交流.1. 基于react实现的滑动验证码组件…

[LeetCode周赛复盘] 第 96 场双周赛20230121

[LeetCode周赛复盘] 第 96 场双周赛20230121 一、本周周赛总结二、 [Easy] 6300. 最小公共值1. 题目描述2. 思路分析3. 代码实现三、[Medium] 6275. 使数组中所有元素相等的最小操作数 II1. 题目描述2. 思路分析3. 代码实现四、[Medium] 6302. 最大子序列的分数1. 题目描述2. 思…

【JavaScript】33_对象的序列化----JSON

3、对象的序列化 对象的序列化 JS中的对象使用时都是存在于计算机的内存中的 序列化指将对象转换为一个可以存储的格式 在JS中对象的序列化通常是一个对象转换为字符串(JSON字符串)序列化的用途(对象转换为字符串有什么用)&…

Linux嵌入式开发——文件系统结构

文章目录Linux嵌入式开发——文件系统结构一、根目录“/”二、Ubuntu文件系统结构三、绝对路径和相对路径Linux嵌入式开发——文件系统结构 一、根目录“/” ​ Linux下“/”就是根目录!所有的目录都是由根目录衍生出来的。 二、Ubuntu文件系统结构 /bin 存放二进…

第十届蓝桥杯省赛 C++ A/B组 - 完全二叉树的权值

✍个人博客:https://blog.csdn.net/Newin2020?spm1011.2415.3001.5343 📚专栏地址:蓝桥杯题解集合 📝原题地址:蜂巢 📣专栏定位:为想参加蓝桥杯的小伙伴整理常考算法题解,祝大家都能…

Linux C编程一站式学习笔记4

Linux C编程一站式学习笔记 chap4 分支语句 文章目录Linux C编程一站式学习笔记 chap4 分支语句一.if语句语句块习题二.if/else语句引例if/else语句 语法规则if else 的配对原则习题1、写两个表达式,分别取整型变量x的个位和十位2、写一个函数,参数是整型…

常见流对象的使用

文章目录一、缓冲流字节缓冲流字符缓冲流二、转换流字符输入转换流字符输出转换流三、对象序列化对象序列化对象反序列化四、打印流PrintStreamPrintWriter一、缓冲流 缓冲流:也叫高效流或者高级流,我们之前学的字节流称为原始流,缓冲流自带…

【JavaSE】浅析String与StringTable

文章目录1. 前言2. String的两种创建方式2.1 通过new关键字创建一个字符串对象2.2 采用双引号的方式来创建字符串对象2.3 两种方式的区别3. StringTable的位置4. String的intern()方法5. 判断两个字符串是否相等5.1 equals5.2 1. 前言 String类是开发中经常使用的一个类。 对…

第七层:多态

文章目录前情回顾多态多态的基本概念动态多态的满足条件动态多态的使用虚函数多态的优点纯虚函数和抽象类抽象类特点虚析构和纯虚析构虚析构和纯虚析构的共性虚析构和纯虚析构的区别面向对象结束,接下来是什么?本章知识点(图片形式)&#x1…

数据结构进阶 哈希桶

作者:小萌新 专栏:数据结构进阶 作者简介:大二学生 希望能和大家一起进步! 本篇博客简介:模拟实现高阶数据结构 哈希桶 哈希桶哈希冲突的另一种解决方法开散列 -- 链地址法举例哈希表的开散列实现 --哈希桶哈希表的结构…

自动化测试Selenium【基础篇二】

自动化测试Selenium【基础篇二】🍎一.Selenium基础使用🍒1.1 信息打印🍉 1.1.1打印标题🍉 1.1.1打印当前网页标题🍒1.2 窗口🍉1.2.1 获取句柄🍉1.2.2 窗口切换🍉1.2.3 窗口大小设置&…

当你点击浏览器的瞬间都发生了什么----- 网络学习笔记

计算机网络前言web 浏览器协议栈创建套接字阶段。连接阶段。断开阶段。IP模块网卡网络设备 --- 集线器、交换器和路由器集线器交换器路由器路由器的附加功能一 :地址转换路由器的附加功能一 :包过滤功能互联网内部接入网光纤接入网(FTTH&…

JDK8 前后的 Date 日期时间 API

JDK8 前后的 Date 日期时间 API 每博一文案 师父说:人只要活在世界上,就会有很多的烦恼,痛苦或是快乐,取决于逆的内心,只要心里拥有温暖灿烂的阳光, 那么悲伤又有什么好畏惧的呢? 人生如行路&a…

vue学习笔记(更新中)

目录 简介 使用Vue写一个"hello,world" 前置准备 代码书写 MVVM模型理解 插值语法和指令语法 插值语法 指令语法 指令:v-bind 指令:v-model vue中的el和data的两种写法 数据代理 方法:defineProperty() 说明…

新年礼物已收到!2022 Apache IoTDB Commits 数量排名 3/364!

社区喜报!据 The Apache Software Foundation 官方 Projects Statistics(项目信息统计网站)的实时数据显示,Apache IoTDB 在过去 12 个月(即 2022 年度)共发表 6829 Commits,排名 2022 年度 Apa…

2、Three.js开发入门与调试设置

一、添加坐标轴辅助器 AxesHelper 用于简单模拟3个坐标轴的对象. 红色代表 X 轴. 绿色代表 Y 轴. 蓝色代表 Z 轴. 构造函数 AxesHelper( size : Number ) size -- (可选的) 表示代表轴的线段长度. 默认为 1. //添加坐标轴 const axesHelper new THREE.AxesHelper(5); sc…

CSS 特效之心形-彩虹-加载动画

CSS 特效之心形-彩虹-加载动画参考描述效果HTMLCSS重置元素的部分默认样式bodyli动画定义指定animationul抖动代码总汇参考 项目描述搜索引擎BingMDNMDN Web Docs 描述 项目描述Edge109.0.1518.61 (正式版本) (64 位) 效果 HTML <!DOCTYPE html> <html lang"e…

Keil C51工程转VSCode Keil Assistant开发全过程

Keil C51工程转VSCode Keil Assistant开发全过程✨这里以stc15W408AS为例。&#x1f4cc;相关篇《【开源分享】自制STC15W408AS开发板》 &#x1f4fa;编译-烧录演示&#xff1a; &#x1f4cb;转VSCODE开发环境主要原因可能代码提示以及代码跳转功能&#xff0c;或者其他。 &…

在java中操作redis

在普通项目中操作redis 1.导入maven坐标 <dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>2.8.0</version> </dependency>2.打开redis 如果redis-server闪退&#xff0c;那就先打开re…