通过torch.nn.init更改模型初始化参数

本文介绍了如何在PyTorch中使用He Kaiming均匀分布和正态分布对神经网络模型的参数进行初始化,包括卷积层和全连接层。作者展示了如何在模型外部和内部直接修改预训练层的权重,以及不同初始化方法的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

比如模型如下:

class Net(nn.Module):
    # 初始化定义网络的结构:也就是定义网络的层
    def __init__(self):
        super(Net,self).__init__()
        self.layer1 = nn.Sequential(            
            nn.Conv2d(3,6,kernel_size=5,stride=1,padding=0),
            # 激活函数
            nn.ReLU(),
            # kernel_size:pooling size,stride:down-sample
            nn.MaxPool2d(kernel_size=2,stride=2))
        self.layer2 = nn.Sequential(            
            nn.Conv2d(6,16,kernel_size=5,stride=1,padding=0),
            # 激活函数
            nn.ReLU(),
            # kernel_size:pooling size,stride:down-sample
            nn.MaxPool2d(kernel_size=2,stride=2))

        self.fc1 = nn.Sequential(
            nn.Linear(16 * 5 * 5, 120),
            nn.ReLU()
        )
        self.fc2 = nn.Sequential(
            nn.Linear(120, 84),
            nn.ReLU()
        )
        
        self.fc3 = nn.Linear(84, 10)

    def forward(self, x):
        x = self.layer1(x)
        x = self.layer2(x)
        # x = x.reshape(x.size(0),-1)
        x = torch.flatten(x, 1) # flatten all dimensions except batch
        x = self.fc1(x)
        x = self.fc2(x)
        x = self.fc3(x)
        return x

model= Net().to(device)

在外部修改:

w1 = torch.empty(model.layer1[0].weight.shape) #according to the layer shape to create tensor

nn.init.kaiming_uniform_(w1, mode='fan_in', nonlinearity='relu')

model.layer1[0].weight.data.copy_(w1)

通过这种方式,模型的第一个卷积层的参数就被修改了。

这里用到的是He Kaiming的uniform的初始化方式,还有normal,以及很多其他人的方式也可以用,比如Xavier initialization, 详情可见这个页面, pytorch提供了一系列初始化参数的方法,可以对还没开始训练的模型进行参数修改。

当然也可以放在模型内部就修改。

class Net(nn.Module):
    # 初始化定义网络的结构:也就是定义网络的层
    def __init__(self):
        super(Net,self).__init__()
        self.layer1 = nn.Sequential(            
            nn.Conv2d(3,6,kernel_size=5,stride=1,padding=0),
            # 激活函数
            nn.ReLU(),
            # kernel_size:pooling size,stride:down-sample
            nn.MaxPool2d(kernel_size=2,stride=2))
        self.layer2 = nn.Sequential(            
            nn.Conv2d(6,16,kernel_size=5,stride=1,padding=0),
            # 激活函数
            nn.ReLU(),
            # kernel_size:pooling size,stride:down-sample
            nn.MaxPool2d(kernel_size=2,stride=2))
        w1 = torch.empty(self.layer1[0].weight.shape) #according to the layer shape to create tensor
        
        nn.init.kaiming_normal_(w1, mode='fan_in', nonlinearity='relu')
        
        self.layer1[0].weight.data.copy_(w1)

        self.fc1 = nn.Sequential(
            nn.Linear(16 * 5 * 5, 120),
            nn.ReLU()
        )
        self.fc2 = nn.Sequential(
            nn.Linear(120, 84),
            nn.ReLU()
        )
        
        self.fc3 = nn.Linear(84, 10)

    def forward(self, x):
        x = self.layer1(x)
        x = self.layer2(x)
        # x = x.reshape(x.size(0),-1)
        x = torch.flatten(x, 1) # flatten all dimensions except batch
        x = self.fc1(x)
        x = self.fc2(x)
        x = self.fc3(x)
        return x

model= Net().to(device)
### PyTorch 中 `torch.nn.Linear` 参数初始化方法 在构建神经网络时,权重和偏置的初始值对于训练过程至关重要。不恰当的初始化可能导致梯度消失或爆炸等问题,影响模型的学习效率。 #### 使用默认初始化方式 当创建一个新的线性层实例时,默认情况下会自动调用 Kaiming Uniform 初始化器来设置该模块内部张量的数据分布[^2]: ```python import torch from torch import nn linear_layer = nn.Linear(784, 256) print(linear_layer.weight.data) # 查看当前权重量化后的随机数 ``` #### 自定义初始化函数 除了依赖框架自带的方式外,还可以通过重写 `_initialize_weights()` 或者直接操作 `.weight` 属性来进行个性化配置。这里给出几种常见的做法: ##### Xavier/Glorot 均匀分布初始化 Xavier 是一种广泛采用的技术,它考虑到了每一层输入输出节点数量之间的关系,从而使得信号能够稳定传递给下一层。 ```python def init_xavier_uniform(layer): if type(layer) == nn.Linear: torch.nn.init.xavier_uniform_(layer.weight) model = nn.Sequential( nn.Flatten(), nn.Linear(784, 256), nn.ReLU() ).apply(init_xavier_uniform) ``` ##### 正态/高斯分布初始化 有时也可能会希望按照标准正态分布 N(0, σ²) 来分配这些参数,在这种场景下可以利用 `normal_()` 函数完成任务。 ```python for param in linear_layer.parameters(): if len(param.shape) > 1: # 只处理二维以上的张量(即权重) torch.nn.init.normal_(param, mean=0., std=0.01) ``` ##### 随机均匀分布初始化 如果想要让所有的数值都落在某个特定区间内,则可以选择 uniform_() 方法实现这一点。 ```python nn.init.uniform_(tensor=linear_layer.bias, a=-0.1, b=0.1) ``` 上述三种方案各有优劣之处,实践中可以根据具体情况灵活选用最适合自己项目的那一款。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值