pytorch对网络参数进行自定义初始化

在使用pytorch构建网络时,如果不自定义进行参数初始化,那么将使用默认的初始化方法,具体查看 pytorch默认参数初始化以及自定义参数初始化
Pytorch提供了几种不同类型的初始化方法 https://pytorch.org/docs/stable/nn.init.html ,如果想使用自定义的初始化方式,则有两种方法:

  • 在定义模型的类的里面定义初始化函数,然后在类的__init__()函数中进行参数初始化
  • 在在定义模型的类的外部定义初始化函数,然后将类实例化之后再进行参数的初始化
    下面将具体介绍两种方法。
    1、在定义模型的类的里面定义初始化函数
    1.1、如果想对模型里面的不同module,比如线性层,卷积层等采用不同的初始化方法,那么可以使用 self.modules()获取模型中的module,然后使用 isinstance函数判断module的类型,代码如下:
import torch
import torch.nn as nn
import torch.nn.functional as F

torch.manual_seed(1)

class MyModel(nn.Module):
    def __init__(self):
        super(MyModel, self).__init__()
        self.linear1 = nn.Linear(3, 3)
        self.linear2 = nn.Linear(3, 3)
        
        self._init_parameters()
        
    def forward(self, x):
        output = self.linear1(x)
        output = self.linear1(output)
        
    def _init_parameters(self):
        for m in self.modules():
            if isinstance(m, nn.Linear):
                nn.init.xavier_uniform_(m.weight.data)
                nn.init.constant_(m.bias.data, 0)

net = MyModel()
for name, p in net.named_parameters():
    print(name)
    print(p)

output:

linear1.weight
Parameter containing:
tensor([[-0.3204, 0.0479, 0.5961],
[ 0.5435, -0.9776, 0.6199],
[ 0.2794, 0.9486, 0.6601]], requires_grad=True)
linear1.bias
Parameter containing:
tensor([0., 0., 0.], requires_grad=True)
linear2.weight
Parameter containing:
tensor([[-0.9111, -0.9508, -0.4823],
[ 0.8781, -0.1666, 0.4280],
[-0.4647, 0.9812, -0.4231]], requires_grad=True)
linear2.bias
Parameter containing:
tensor([0., 0., 0.], requires_grad=True)

1.2、如果想对所有类型的module都使用相同的初始化方法,可以采用self.parameters()获取参数,代码如下:

import torch
import torch.nn as nn
import torch.nn.functional as F

torch.manual_seed(1)

class MyModel(nn.Module):
    def __init__(self):
        super(MyModel, self).__init__()
        self.linear1 = nn.Linear(3, 3)
        self.linear2 = nn.Linear(3, 3)
        
        self._init_parameters()
        
    def forward(self, x):
        output = self.linear1(x)
        output = self.linear1(output)
        
    def _init_parameters(self):
        for p in self.parameters():
            # 对weights进行初始化
            if p.dim() > 1:
                nn.init.xavier_uniform_(p)
            # 对bias进行初始化
            else:
                nn.init.constant_(p, 0)

net = MyModel()
for name, p in net.named_parameters():
    print(name)
    print(p)

outputs:

linear1.weight
Parameter containing:
tensor([[-0.3204, 0.0479, 0.5961],
[ 0.5435, -0.9776, 0.6199],
[ 0.2794, 0.9486, 0.6601]], requires_grad=True)
linear1.bias
Parameter containing:
tensor([0., 0., 0.], requires_grad=True)
linear2.weight
Parameter containing:
tensor([[-0.9111, -0.9508, -0.4823],
[ 0.8781, -0.1666, 0.4280],
[-0.4647, 0.9812, -0.4231]], requires_grad=True)
linear2.bias
Parameter containing:
tensor([0., 0., 0.], requires_grad=True)

2、在在定义模型的类的外部定义初始化函数
2.1、同样的,如果想对模型里面的不同module,比如线性层,卷积层等采用不同的初始化方法,那么可以使用 net.modules()获取模型中的module,然后使用 isinstance函数判断module的类型,代码如下:

import torch
import torch.nn as nn
import torch.nn.functional as F

torch.manual_seed(1)

class MyModel(nn.Module):
    def __init__(self):
        super(MyModel, self).__init__()
        self.linear1 = nn.Linear(3, 3)
        self.linear2 = nn.Linear(3, 3)
        
    def forward(self, x):
        output = self.linear1(x)
        output = self.linear1(output)

def init_parameters(net):
    for m in net.modules():
        if isinstance(m, nn.Linear):
            nn.init.xavier_uniform_(m.weight.data)
            nn.init.constant_(m.bias.data, 0)

net = MyModel()
for name, p in net.named_parameters():
    print(name)
    print(p)

init_parameters(net)
print("\n在执行自定义的初始化后:")
for name, p in net.named_parameters():
    print(name)
    print(p)

outputs:

linear1.weight
Parameter containing:
tensor([[ 0.2975, -0.2548, -0.1119],
[ 0.2710, -0.5435, 0.3462],
[-0.1188, 0.2937, 0.0803]], requires_grad=True)
linear1.bias
Parameter containing:
tensor([-0.0707, 0.1601, 0.0285], requires_grad=True)
linear2.weight
Parameter containing:
tensor([[ 0.2109, -0.2250, -0.0421],
[-0.0520, 0.0837, -0.0023],
[ 0.5047, 0.1797, -0.2150]], requires_grad=True)
linear2.bias
Parameter containing:
tensor([-0.3487, -0.0968, -0.2490], requires_grad=True)
在执行自定义的初始化后:
linear1.weight
Parameter containing:
tensor([[-0.3204, 0.0479, 0.5961],
[ 0.5435, -0.9776, 0.6199],
[ 0.2794, 0.9486, 0.6601]], requires_grad=True)
linear1.bias
Parameter containing:
tensor([0., 0., 0.], requires_grad=True)
linear2.weight
Parameter containing:
tensor([[-0.9111, -0.9508, -0.4823],
[ 0.8781, -0.1666, 0.4280],
[-0.4647, 0.9812, -0.4231]], requires_grad=True)
linear2.bias
Parameter containing:
tensor([0., 0., 0.], requires_grad=True)

2.2、如果想对所有类型的module都使用相同的初始化方法,可以采用net.parameters()获取参数,代码如下:

import torch
import torch.nn as nn
import torch.nn.functional as F

torch.manual_seed(1)

class MyModel(nn.Module):
    def __init__(self):
        super(MyModel, self).__init__()
        self.linear1 = nn.Linear(3, 3)
        self.linear2 = nn.Linear(3, 3)
        
    def forward(self, x):
        output = self.linear1(x)
        output = self.linear1(output)

def init_parameters(net):
    for p in net.parameters():
        if p.dim() > 1:
            nn.init.xavier_uniform_(p)
        else:
            nn.init.constant_(p, 0)

net = MyModel()
for name, p in net.named_parameters():
    print(name)
    print(p)

init_parameters(net)
print("\n在执行自定义的初始化后:")
for name, p in net.named_parameters():
    print(name)
    print(p)

outputs:

linear1.weight
Parameter containing:
tensor([[ 0.2975, -0.2548, -0.1119],
[ 0.2710, -0.5435, 0.3462],
[-0.1188, 0.2937, 0.0803]], requires_grad=True)
linear1.bias
Parameter containing:
tensor([-0.0707, 0.1601, 0.0285], requires_grad=True)
linear2.weight
Parameter containing:
tensor([[ 0.2109, -0.2250, -0.0421],
[-0.0520, 0.0837, -0.0023],
[ 0.5047, 0.1797, -0.2150]], requires_grad=True)
linear2.bias
Parameter containing:
tensor([-0.3487, -0.0968, -0.2490], requires_grad=True)
在执行自定义的初始化后:
linear1.weight
Parameter containing:
tensor([[ 0.2975, -0.2548, -0.1119],
[ 0.2710, -0.5435, 0.3462],
[-0.1188, 0.2937, 0.0803]], requires_grad=True)
linear1.bias
Parameter containing:
tensor([-0.0707, 0.1601, 0.0285], requires_grad=True)
linear2.weight
Parameter containing:
tensor([[ 0.2109, -0.2250, -0.0421],
[-0.0520, 0.0837, -0.0023],
[ 0.5047, 0.1797, -0.2150]], requires_grad=True)
linear2.bias
Parameter containing:
tensor([-0.3487, -0.0968, -0.2490], requires_grad=True)

PyTorch 自定义初始化可以使得我们初始化参数时更加灵活和个性化。在使用 PyTorch 进行深度学习任务时,初始值设置是非常重要的。参数初始值一定程度上影响了算法的收敛速度和精度。因此,自定义初始化是非常有必要的。 PyTorch的torch.nn.init模块提供了一些常用的初始化方式,包括常见的随机初始化(uniform,normal等),常数初始化(zeros,ones等),以及一些比较有名的网络模型特定的初始化方式,如Xavier初始化,Kaiming初始化等。但有时候我们需要自定义初始化方法,此时就需要自定义初始化。 我们可以使用register_parameter方法为模型中的每一个参数自定义初始化方法,如下所示: ``` class CustomModel(nn.Module): def __init__(self): super(CustomModel, self).__init__() self.weight = nn.Parameter(torch.Tensor(1, 100)) self.register_parameter('bias', None) self.reset_parameters() def reset_parameters(self): stdv = 1. / math.sqrt(self.weight.size(1)) self.weight.data.uniform_(-stdv, stdv) model = CustomModel() ``` 在以上的代码中,我们可以看到,在模型内部通过register_parameter方法给bias参数设置值为None,表明bias参数不需要在初始化时使用模型默认的初始化方式。然后在通过重载reset_parameters方法,我们自己进行参数初始化。 通过这种自定义初始化方式,我们可以方便地对网络模型中的参数进行初始化,从而达到优化模型的目的,提高算法的效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值