Pytorch提取参数及自定义初始化
点击上方“视学算法”,选择加"星标"或“置顶”
重磅干货,第一时间送达
导读
有时候提取出的层结构并不够,还需要对里面的参数进行初始化,那么如何提取出网络的参数并对其初始化呢?本文对其进行简单的介绍。
首先 nn.Module 里面有两个特别重要的关于参数的属性,分别是 named_parameters()和 parameters()。named_parameters() 是给出网络层的名字和参数的迭代器,parameters()会给出一个网络的全部参数的选代器。
import os
import torch
import torch.nn as nn
import torch.optim as optim
import torch.backends.cudnn as cudnn
import torch.nn.init as init
import argparse
import torch.autograd.variable as variable
class SimpleCNN(nn.Module):
def __init__(self):
super(SimpleCNN,self).__init__() #b,3,32,32
layer1=nn.Sequential()
layer1.add_module('conv1',nn.Conv2d(in_channels=3,out_channels=32,kernel_size=3,stride=1,padding=1))
#b,32,32,32
layer1.add_module('relu1',nn.ReLU(True))
layer1.add_module('pool1',nn.MaxPool2d(2,2))
#b,32,16,16
self.layer1=layer1
layer2=nn.Sequential()
layer1.add_module('conv2',nn.Conv2d(in_channels=32,out_channels=64,kernel_size=3,stride=1,padding=1))
#b,64,16,16
layer2.add_module('relu2',nn.ReLU(True))
layer2.add_module('pool2',nn.MaxPool2d(2,2))
#b,64,8,8
self.layer2=layer2
layer3=nn.Sequential()
layer3.add_module('conv3', nn.Conv2d(in_channels=64, out_channels=128, kernel_size=3 ,stride=1, padding = 1))
#b,128,8,8
layer3.add_module('relu3', nn.ReLU(True))
layer3.add_module('poo13', nn.MaxPool2d(2, 2))#b,128,4,4
self.layer3=layer3
layer4 =nn.Sequential()
layer4.add_module('fc1',nn.Linear(in_features=2048, out_features=512 ))
layer4.add_module('fc_relu1', nn.ReLU(True))
layer4.add_module('fc2 ', nn.Linear(in_features=512, out_features=64 ))
layer4.add_module('fc_relu2', nn.ReLU(True))
layer4.add_module('fc3', nn.Linear(64, 10))
self.layer4 = layer4
def forward(self,x):
conv1=self.layer1(x)
conv2=self.layer2(conv1)
conv3=self.layer3(conv2)
fc_input=conv3.view(conv3.size(0),-1)
fc_output=self.layer4(fc_input)
return fc_output
model=SimpleCNN()
for param in model.named_parameters():
print(param[0])
可以得到每一层参数的名字,输出为
如何对权重做初始化呢 ? 非常简单,因为权重是一个 Variable ,所以只需要取出其中的 data 属性,然后对它进行所需要的处理就可以了。
for m in model.modules():
if isinstance(m,nn.Conv2d):
init.normal(m.weight.data) #通过正态分布填充张量
init.xavier_normal(m.weight.data)
#xavier均匀分布的方法来init,来自2010年的论文“Understanding the difficulty of training deep feedforward neural networks”
init.kaiming_normal(m.weight.data)
#来自2015年何凯明的论文“Delving deep into rectifiers: Surpassing human-level performance on ImageNet classification”
m.bias.data.fill_(0)
elif isinstance(m,nn.Linear):
m.weight.data.normal_()
通过上面的操作,对将卷积层中使用 PyTorch 里面提供的方法的权重进行初始化,这样就能够使用任意我们想使用的初始化,甚至我们可以自己定义初始化方法并对权重进行初始化 。
更多初始化方法参考:https://pytorch-cn.readthedocs.io/zh/latest/package_references/nn_init/
点个在看 paper不断!
评论