神经网络的初始化方式都有哪些?

news/2025/1/8 14:39:18/

一、概念

        神经网络的初始化是深度学习中的一个关键步骤,它指的是在训练开始前为神经网络的权重和偏置设置初始值。合适的初始化方法可以加速模型的收敛,提高训练效果,甚至影响模型的最终性能。当然,目前我们使用Torch、TensorFlow等深度学习库进行建模的过程中,这些第三方库已经默认为我们选择了初始化的方式来设置神经网络的权重和偏置(不同神经网络有不同的默认方法),从而使得很多人往往都会忽略初始化竟然还能玩花样。

二、类型

1、随机初始化

        随机初始化是神经网络中常用的一种权重初始化方法,其基本思想是在训练开始前为网络的权重和偏置赋予随机值。随机初始化有助于打破网络的对称性,使得不同的神经元可以学习不同的特征,从而避免神经元之间冗余。随机初始化方法一般是从某个概率分布中随机抽取权重值,常见的分布有:

  • 均匀分布(Uniform Distribution):权重从一个均匀分布中随机抽取,通常范围是[−a,a],其中 a 是一个较小的正数,可以根据网络的具体需求来设置。
  • 正态分布(Normal Distribution):权重从一个正态分布(高斯分布)中随机抽取,均值为0,标准差为 σ,而标准差控制了权重值的分散程度。
python">import torch
import torch.nn as nn# 定义一个简单的神经网络
class SimpleNet(nn.Module):def __init__(self):super(SimpleNet, self).__init__()self.fc1 = nn.Linear(10, 50)self.fc2 = nn.Linear(50, 1)# 初始化网络
net = SimpleNet()# 应用随机初始化
def init_weights(m):if type(m) == nn.Linear:# 均匀分布初始化nn.init.uniform_(m.weight, -0.1, 0.1)# 正态分布初始化# nn.init.normal_(m.weight, mean=0.0, std=0.01)# 初始化偏置为0nn.init.zeros_(m.bias)# 遍历网络中的所有模块并应用初始化
net.apply(init_weights)

2、Xaiver初始化

        Xavier初始化,也称为Glorot初始化,由Xavier Glorot提出,目的是解决在深度神经网络中随机初始化可能导致的梯度消失或梯度爆炸问题。Xavier初始化的基本思想是保持每一层输出的方差与输入的方差一致,以防止信号在深度网络中的传播过程中出现衰减或放大。

        Xavier初始化考虑了前一层的节点数(n_{in})和当前层的节点数(n_{out})。权重的初始化范围是- \sqrt{\frac{6}{n_{in}+n_{out}}}\sqrt{\frac{6}{n_{in}+n_{out}}},这个范围确保了权重既不会太小也不会太大,从而避免了梯度消失或爆炸的问题。这个公式是基于保持激活值方差的稳定性来推导的,使得每层的输出值(激活值)保持高斯分布。尽管Xavier初始化在很多情况下都非常有效,但它假设激活函数是线性的(因此更适合sigmoid或者tanh之类的激活函数),这在实际中并不总是成立。例如,在ReLU激活函数的网络中,Xavier初始化可能不是最优的选择,因此出现了He初始化作为替代。

python">import torch
import torch.nn as nn
import torch.nn.init as init# 定义一个简单的神经网络
class SimpleNet(nn.Module):def __init__(self):super(SimpleNet, self).__init__()self.fc1 = nn.Linear(10, 50)  # 输入层到隐藏层self.fc2 = nn.Linear(50, 1)  # 隐藏层到输出层def forward(self, x):x = torch.relu(self.fc1(x))x = self.fc2(x)return x# 初始化网络
net = SimpleNet()# 使用Xavier均匀分布初始化
init.xavier_uniform_(net.fc1.weight)
init.xavier_uniform_(net.fc2.weight)# 或者使用Xavier正态分布初始化
init.xavier_normal_(net.fc1.weight)
init.xavier_normal_(net.fc2.weight)# 打印初始化后的权重
print(net.fc1.weight)
print(net.fc2.weight)

3、He初始化

        He初始化(也称为Kaiming初始化,由何凯明提出)是一种专门为ReLU激活函数设计的权重初始化方法。He初始化的目的是为了解决在使用ReLU激活函数的深度神经网络中出现的梯度消失或爆炸问题。它通过合理设置权重的初始值,使得在网络的前向传播和反向传播过程中,激活值和梯度的方差保持相对稳定。

        He初始化基于以下原理:在ReLU激活函数下,权重应该按照均值为0的正态分布进行初始化,其标准差为\sqrt{\frac{2}{n_{in}}}​​,其中n_{in}是前一层的节点数。这样做的目的是为了保持每层激活值的方差大致相同,从而避免梯度消失或爆炸。

python">import torch
import torch.nn as nn
import torch.nn.init as initclass SimpleNet(nn.Module):def __init__(self):super(SimpleNet, self).__init__()self.fc1 = nn.Linear(10, 50)  # 输入层到隐藏层self.fc2 = nn.Linear(50, 1)  # 隐藏层到输出层def forward(self, x):x = torch.relu(self.fc1(x))x = self.fc2(x)return x# 初始化网络
net = SimpleNet()# 使用He初始化
init.kaiming_normal_(net.fc1.weight, mode='fan_in', nonlinearity='relu')
init.kaiming_normal_(net.fc2.weight, mode='fan_in', nonlinearity='relu')# 打印初始化后的权重
print(net.fc1.weight)
print(net.fc2.weight)

4、正交初始化

        正交初始化(Orthogonal Initialization)核心目标是使权重矩阵正交化。这种方法通过确保权重矩阵的每一列变成单位向量,并且每个列向量与其他列向量垂直,从而减少神经网络中的冗余性和过拟合,提高网络的泛化能力和性能。

        正交初始化基于保持向量长度和角度的数学性质,通过正交化权重矩阵来减少神经网络中的冗余性和过拟合。具体来说,正交初始化的过程可以分为以下几个步骤:

  • 高斯分布初始化:首先,使用均值为0、方差为1的高斯分布随机生成权重矩阵中的每个元素的初始值。
  • QR分解:然后,对初始权重矩阵进行QR分解或SVD分解,得到两个正交矩阵。
  • 选择正交矩阵:最后,选择其中一个正交矩阵作为权重矩阵。
python">import torch
import torch.nn as nn
import torch.nn.init as initclass Net(nn.Module):def __init__(self):super(Net, self).__init__()self.fc1 = nn.Linear(10, 20)self.fc2 = nn.Linear(20, 10)def forward(self, x):x = torch.relu(self.fc1(x))x = self.fc2(x)return x# 初始化网络
net = Net()# 应用正交初始化
def orthogonal_init(module):if isinstance(module, nn.Linear):init.orthogonal_(module.weight)if module.bias is not None:init.zeros_(module.bias)net.apply(orthogonal_init)


http://www.ppmy.cn/news/1561247.html

相关文章

Unity制作3D场景的脑电运动想象范式(左右手抓握)

使用Unity制作3D场景中的运动想象范式 3D技术可以创建出立体的图像和环境,给用户带来更加真实和沉浸式的体验,本文介绍了一种可控的左右手运动的3D场景范式的设计流程,用于被试在3D场景下完成运动想象脑电信号数据的采集。 目录 1.制作动画…

deepin环境下Docker实用指南:核心命令详解

摘要: Docker作为容器化技术的佼佼者,极大地简化了应用的打包、部署和管理。本文将深入探讨在deepin环境下使用Docker的核心命令,帮助您高效地管理Docker容器和镜像。 阅读更多 支持ing 正文: 一、Docker简介 Docker是一个开源的…

kmodule.dll是什么文件,丢失怎么办

kmodule.dll是一个动态链接库(DLL)文件,它在电脑中起到重要的作用,支持某些软件或游戏的正常运行。如果计算机中丢失了这个文件,可能会导致相关软件或游戏无法启动,并出现错误提示。 当发现kmodule.dll文件…

NeurIPS 2024 | 像素级LLM实现图像视频理解、生成、分割和编辑大统一(昆仑万维等)

Accepted by NeurIPS 2024 文章链接:https://arxiv.org/pdf/2412.19806 项目链接:https://vitron-llm.github.io/ Github链接:https://github.com/SkyworkAI/Vitron 亮点直击 首次提出了一种通用的视觉多模态大语言模型(MLLM&…

基于Leaflet和SpringBoot的全球国家综合检索WebGIS可视化

目录 前言 一、Java后台程序设计 1、业务层设计 2、控制层设计 二、WebGIS可视化实现 1、侧边栏展示 ?2、空间边界信息展示 三、标注成果展示 1、面积最大的国家 2、国土面积最小的国家 3、海拔最低的国家 4、最大的群岛国家? 四、总结 前言 在前面的博文中&am…

iOS 逆向学习 - iOS Architecture Core OS Layer

iOS 逆向学习 - iOS Architecture Core OS Layer 一、Core OS Layer 概述二、Core OS Layer 的核心组成部分1. Kernel(XNU 内核)2. Device Drivers(设备驱动)3. Security Frameworks(安全框架)4. File Syst…

微信小程序处理交易投诉管理,支持多小程序

大家好,我是小悟 1、问题背景 玩过微信小程序生态的,或许就有这种感受,如果收到投诉单,不会及时通知到手机端,而是每天早上10:00向小程序的管理员及运营者推送通知。通知内容为截至前一天24时该小程序账号内待处理的交…

Kubernets之Pod的基本概念和配置文件

一、Pod的基本概念 Pod是一个Kubernets中的一个抽象概念,用于存放一组Container(可以包含一个或多个Container容器)以及这些Container的共享资源。 资源包括: 共享存储,称为卷(Vloume)网络,每个Pod&…