权值初始化

一、梯度消失与爆炸

在神经网络中,梯度消失和梯度爆炸是训练过程中常见的问题。

梯度消失指的是在反向传播过程中,梯度逐渐变小,导致较远处的层对参数的更新影响较小甚至无法更新。这通常发生在深层网络中,特别是使用某些激活函数(如sigmoid函数)时。当梯度消失发生时,较浅层的权重更新较大,而较深层的权重更新较小,使得深层网络的训练变得困难。

梯度爆炸指的是在反向传播过程中,梯度逐渐变大,导致权重更新过大,网络无法收敛。这通常发生在网络层数较多,权重初始化过大,或者激活函数的导数值较大时。

为了解决梯度消失和梯度爆炸问题,可以采取以下方法:

  • 权重初始化:合适的权重初始化可以缓解梯度消失和梯度爆炸问题。常用的方法包括Xavier初始化和He初始化。
  • 使用恰当的激活函数:某些激活函数(如ReLU、LeakyReLU)可以缓解梯度消失问题,因为它们在正半轴具有非零导数。
  • 批归一化(Batch Normalization):通过在每个批次的输入上进行归一化,可以加速网络的收敛,并减少梯度消失和梯度爆炸的问题。
  • 梯度裁剪(Gradient Clipping):设置梯度的上限,防止梯度爆炸。
  • 减少网络深度:减少网络的层数,可以降低梯度消失和梯度爆炸的风险。

综上所述,梯度消失和梯度爆炸是神经网络中常见的问题,可以通过合适的权重初始化、激活函数选择、批归一化、梯度裁剪和减少网络深度等方法来缓解这些问题。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

二、Xavier初始化

对于具有饱和函数(如Sigmoid、Tanh)的激活函数和方差一致性的要求,可以推导出权重矩阵的初始化范围。
假设输入的维度为 n_in,权重矩阵为 W,我们希望满足方差一致性的要求:
在这里插入图片描述

方差一致性:

保持数据尺度维持在恰当范围,通常方差为1

激活函数:ReLU及其变种
在这里插入图片描述


三、十种初始化方法

以下是常用的权重初始化方法:

  1. Xavier均匀分布(Xavier Uniform Distribution):根据输入和输出的维度,从均匀分布中采样权重,范围为 [-a, a],其中 a = sqrt(6 / (n_in + n_out))。适用于具有饱和函数(如Sigmoid、Tanh)的激活函数。
  2. Xavier正态分布(Xavier Normal Distribution):根据输入和输出的维度,从正态分布中采样权重,均值为 0,标准差为 sqrt(2 / (n_in + n_out))。适用于具有饱和函数的激活函数。
  3. Kaiming均匀分布(Kaiming Uniform Distribution):根据输入维度,从均匀分布中采样权重,范围为 [-a, a],其中 a = sqrt(6 / n_in)。适用于具有ReLU激活函数的网络。
  4. Kaiming正态分布(Kaiming Normal Distribution):根据输入维度,从正态分布中采样权重,均值为 0,标准差为 sqrt(2 / n_in)。适用于具有ReLU激活函数的网络。
  5. 均匀分布(Uniform Distribution):从均匀分布中采样权重,范围为 [-a, a],其中 a 是一个常数。
  6. 正态分布(Normal Distribution):从正态分布中采样权重,均值为 0,标准差为 std。
  7. 常数分布(Constant Distribution):将权重初始化为常数。
  8. 正交矩阵初始化(Orthogonal Matrix Initialization):通过QR分解或SVD分解等方法,初始化权重为正交矩阵。
  9. 单位矩阵初始化(Identity Matrix Initialization):将权重初始化为单位矩阵。
  10. 稀疏矩阵初始化(Sparse Matrix Initialization):将权重初始化为稀疏矩阵,其中只有少数非零元素。

不同的初始化方法适用于不同的网络结构和激活函数,选择合适的初始化方法可以帮助网络更好地进行训练和收敛。

nn.init.calculate_gain

nn.init.calculate_gain 是 PyTorch 中用于计算激活函数的方差变化尺度的函数。方差变化尺度是指激活函数输出值方差相对于输入值方差的比例。这个比例对于初始化神经网络的权重非常重要,可以影响网络的训练和性能。

主要参数如下:

  • nonlinearity:激活函数的名称,用字符串表示,比如 ‘relu’、‘leaky_relu’、‘tanh’ 等。
  • param:激活函数的参数,这是一个可选参数,用于指定激活函数的特定参数,比如 Leaky ReLU 的 negative_slope

这个函数的返回值是一个标量,表示激活函数的方差变化尺度。在初始化网络权重时,可以使用这个尺度来缩放权重,以确保网络在训练过程中具有良好的数值稳定性。

例如,可以在初始化网络权重时使用 nn.init.xavier_uniform_nn.init.xavier_normal_,并通过 calculate_gain 函数计算激活函数的方差变化尺度,将其作为相应初始化方法的参数。这样可以根据激活函数的特性来调整权重的初始化范围,有助于更好地训练神经网络。

小案例

import os
import torch
import random
import numpy as np
import torch.nn as nn
from tools.common_tools import set_seed

set_seed(1)  # 设置随机种子


class MLP(nn.Module):
    def __init__(self, neural_num, layers):
        super(MLP, self).__init__()
        self.linears = nn.ModuleList([nn.Linear(neural_num, neural_num, bias=False) for i in range(layers)])
        self.neural_num = neural_num

    def forward(self, x):
        for (i, linear) in enumerate(self.linears):
            x = linear(x)
            x = torch.relu(x)

            print("layer:{}, std:{}".format(i, x.std()))
            if torch.isnan(x.std()):
                print("output is nan in {} layers".format(i))
                break

        return x

    def initialize(self):
        for m in self.modules():
            if isinstance(m, nn.Linear):
                # nn.init.normal_(m.weight.data, std=np.sqrt(1/self.neural_num))    # normal: mean=0, std=1

                # a = np.sqrt(6 / (self.neural_num + self.neural_num))
                #
                # tanh_gain = nn.init.calculate_gain('tanh')
                # a *= tanh_gain
                #
                # nn.init.uniform_(m.weight.data, -a, a)

                # nn.init.xavier_uniform_(m.weight.data, gain=tanh_gain)

                # nn.init.normal_(m.weight.data, std=np.sqrt(2 / self.neural_num))
                nn.init.kaiming_normal_(m.weight.data)

flag = 0
# flag = 1

if flag:
    layer_nums = 100
    neural_nums = 256
    batch_size = 16

    net = MLP(neural_nums, layer_nums)
    net.initialize()

    inputs = torch.randn((batch_size, neural_nums))  # normal: mean=0, std=1

    output = net(inputs)
    print(output)

# ======================================= calculate gain =======================================

# flag = 0
flag = 1

if flag:
    # 生成随机张量并通过tanh激活函数计算输出
    x = torch.randn(10000)
    out = torch.tanh(x)

    # 计算激活函数增益
    gain = x.std() / out.std()
    print('gain:{}'.format(gain))

    # 使用PyTorch提供的calculate_gain函数计算tanh激活函数的增益
    tanh_gain = nn.init.calculate_gain('tanh')
    print('tanh_gain in PyTorch:', tanh_gain)

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

领导风格测试

领导风格指的是管理者在开展管理工作时的思维和行为模式,通常我们也称之为习惯,或者是人格特征。这种习惯是固化的,是长期的经历所形成的,其中包含了个人的知识,经验,人际关系等。领导风格测试是企业人才选…

记录 | ubuntu软链接查看、删除、创建

软连接查看 ls -il 软连接删除 rm -rf ** 软连接创建 ln -s 源文件 目标文件 实例,软连接报错: 若要建立libtiny_reid.so*间软连接: 先删除 rm -rf libtiny_reid.so libtiny_reid.so.3 libtiny_reid.so.3.1 再建立 ln -s libtiny_re…

Matlab数学建模算法之模拟退火算法(SA)详解

🔗 运行环境:Matlab 🚩 撰写作者:左手の明天 🥇 精选专栏:《python》 🔥 推荐专栏:《算法研究》 🔐#### 防伪水印——左手の明天 ####🔐 💗 大家…

基于深度学习的婴儿啼哭识别项目详解

基于深度学习的婴儿啼哭识别项目详解 基于深度学习的婴儿啼哭识别项目详解一、项目背景1.1 项目背景1.2 数据说明 二、PaddleSpeech环境准备三、数据预处理3.1 数据解压缩3.2 查看声音文件3.3 音频文件长度处理 四、自定义数据集与模型训练4.1 自定义数据集4.2 模型训练4.3 模型…

【JaveWeb教程】(21) MySQL数据库开发之多表设计:一对多、一对一、多对多的表关系 详细代码示例讲解

目录 2. 多表设计2.1 一对多2.1.1 表设计2.1.2 外键约束 2.2 一对一2.3 多对多2.4 案例 2. 多表设计 关于单表的操作(单表的设计、单表的增删改查)我们就已经学习完了。接下来我们就要来学习多表的操作,首先来学习多表的设计。 项目开发中,在进行数据库…

Python基本语法与变量的相关介绍

python基本语法与变量 python语句的缩进 Python代码块使用缩进对齐表示代码逻辑,Python每段代码块缩进的空白数量可以任意,但要确保同段代码块语句必须包含相同的缩进空白数量。建议在代码块的每个缩进层次使用单个制表符或两个空格或四个空格 , 切记不…

Linux系统中的IP地址、主机名、和域名解析

1.IP地址 每一台联网的电脑都会有一个地址,用于和其它计算机进行通讯 IP地址主要有2个版本,V4版本和V6版本(V6很少用,暂不涉及) IPv4版本的地址格式是:a.b.c.d,其中abcd表示0~255的数字&…

pyenv虚拟环境安装和配合pipenv多版本创建

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、下载配置pyenv二、配置多版本虚拟环境总结 前言 最近公司编写了一个自动化用例编写软件,需要适配win7和win10系统,需要同时编译3.8…

leetcode 2114. 句子中的最多单词数

题目: 一个 句子 由一些 单词 以及它们之间的单个空格组成,句子的开头和结尾不会有多余空格。 给你一个字符串数组 sentences ,其中 sentences[i] 表示单个 句子 。 请你返回单个句子里 单词的最多数目 。 解题方法: 1.遍历列表…

JVM,JRE,JDK的区别和联系简洁版

先看图 利用JDK(调用JAVA API)开发JAVA程序后,通过JDK中的编译程序(javac)将我们的文本java文件编译成JAVA字节码,在JRE上运行这些JAVA字节码,JVM解析这些字节码,映射到CPU指令集或…

RAG代码实操之斗气强者萧炎

📑前言 本文主要是【RAG】——RAG代码实操的文章,如果有什么需要改进的地方还请大佬指出⛺️ 🎬作者简介:大家好,我是听风与他🥇 ☁️博客首页:CSDN主页听风与他 🌄每日一句&#x…

【Linux运维】LVM和RAID学习及实践

LVM和RAID学习及实践 背景LVM简介新加硬盘的操作RAID-磁盘阵列应用场景RAID0RAID1其他结构RAID制作RAID 小结 背景 某台服务器的磁盘管理需要自己动手处理,找了一些资料也踩了一些坑,在这里记录一下,先介绍一下LVM和RAID这两个东西。在计算机…

【爬虫实战】-爬取微博之夜盛典评论,爬取了1.7w条数据

前言: TaoTao之前在前几期推文中发布了一个篇weibo评论的爬虫。主要就是采集评论区的数据,包括评论、评论者ip、评论id、评论者等一些信息。然后有很多的小伙伴对这个代码很感兴趣。TaoTao也都给代码开源了。由于比较匆忙,所以没来得及去讲这…

Open3D 从体素网格构建八叉树(14)

Open3D 从体素网格构建八叉树(14) 一、算法简介二、算法实现1.代码2.效果一、算法简介 上一章介绍从点云构建八叉树,对点云所在体素进行了可视化显示,这里可以对体素构建八叉树,可视化显示八叉树的具体划分结构。 二、算法实现 1.代码 代码如下(示例): import op…

【python】搭配Miniconda使用VSCode

现在的spyder总是运行出错,启动不了,尝试使用VSCode。 一、在VSCode中使用Miniconda管理的Python环境,可以按照以下步骤进行: a. 确保Miniconda环境已经安装并且正确配置。 b. 打开VSCode,安装Python扩展。 打开VS…

用通俗易懂的方式讲解:Stable Diffusion WebUI 从零基础到入门

本文主要介绍 Stable Diffusion WebUI 的实际操作方法,涵盖prompt推导、lora模型、vae模型和controlNet应用等内容,并给出了可操作的文生图、图生图实战示例。适合对Stable Diffusion感兴趣,但又对Stable Diffusion WebUI使用感到困惑的同学。…

GBASE南大通用提问:如果程序检索到 NULL 值,该怎么办?

可在数据库中存储 NULL 值,但编程语言支持的数据类型不识别 NULL 状态。程序必须 采用某种方式来识别 NULL 项,以免将它作为数据来处理。 在 SQL API 中,指示符变量满足此需要。指示符变量是与可能收到 NULL 项的主变量相 关联的一个附加的变…

深度学习笔记(五)——网络优化(1):学习率自调整、激活函数、损失函数、正则化

文中程序以Tensorflow-2.6.0为例 部分概念包含笔者个人理解,如有遗漏或错误,欢迎评论或私信指正。 截图和程序部分引用自北京大学机器学习公开课 通过学习已经掌握了主要的基础函数之后具备了搭建一个网络并使其正常运行的能力,那下一步我们还…

Linux环境之Ubuntu安装Docker流程

今天分享Linux环境之Ubuntu安装docker流程,Docker 是目前非常流行的容器,对其基本掌握很有必要。下面我们通过阿里云镜像的方式安装: 本来今天准备用清华大学镜像安装呢,好像有点问题,于是改成阿里云安装了。清华安装…

《矩阵分析》笔记

来源:【《矩阵分析》期末速成 主讲人:苑长(5小时冲上90)】https://www.bilibili.com/video/BV1A24y1p76q?vd_sourcec4e1c57e5b6ca4824f87e74170ffa64d 这学期考矩阵论,使用教材是《矩阵论简明教程》,因为没…