今天重新研究了一下pytorch如何自定義權重,可以根據條件篩選賦值,也可以根據自定義某個張量賦值,還可以根據pth文件部分賦值等情況,
我總結了三種方法(self.modules(),self.state_dict(),self.named_parameters()),每種方法有約2種情況,希望對大家有所幫助,
然具體各自函數代表什么,可自行查閱,如self.parameters函數,我給出具體實現權重的初始化方法(已使用代碼驗證),具體實現如下:
code模塊:
import torch
import torch.nn as nn
class MYMODEL(nn.Module):
def __init__(self, val):
super(MYMODEL, self).__init__()
self.val = val
self.layer1 = self.layer1()
self.layer2 = self.layer2()
self.layer3 = self.layer3()
# self.inite_weight_1()
# self.inite_weight_2()
self.inite_weight_3()
''' 權重修改方法 '''
''' 方法一 使用self.modules() 修改'''
def inite_weight_1(self):
for m in self.modules():
if isinstance(m, nn.Conv2d):
# 修改方法一
m.weight.data=torch.ones(m.weight.data.shape)*300 # 這樣是可以修改的
# 修改方法二
# nn.init.kaiming_normal_(m.weight.data, mode='fan_out', nonlinearity='relu')
elif isinstance(m, nn.BatchNorm2d):
m.weight.data.fill_(1.)
m.bias.data.fill_(1e-4)
elif isinstance(m, nn.Linear):
m.weight.data.normal_(0.0, 0.0001)
m.bias.data.zero_()
print('[finishing]:assign weight by inite_weight_1')
''' 方法二 使用state_dict() 修改'''
def inite_weight_2(self): # value 可以賦值
t=self.state_dict()
'''賦值方法一'''
for key, value in self.state_dict().items():
if 'layer1' in key: # 篩選條件
a=torch.ones(t[key].shape)*99 # 可以自己修改權重值
t[key].copy_(a)
'''賦值方法二'''
# for name, value in self.state_dict().items():
# if 'layer1' in name:
# nn.init.constant_(value, 40)
print('[finishing]:assign weight by inite_weight_2')
''' 方法三 self.named_parameters() 修改'''
def inite_weight_3(self):
t = self.state_dict()
'''方法一'''
for name, param in self.named_parameters():
if 'layer1' in name: # 篩選條件
a=torch.ones(param.shape)*99 # 可以自己修改權重值
t[name].copy_(a)
b = torch.ones(param.shape) * 88 # 可以自己修改權重值
param.data.copy_(b)
def layer1(self):
layer1 = torch.nn.Sequential()
layer1.add_module('conv1', torch.nn.Conv2d(3, 32, 3, 1, padding=1))
layer1.add_module('relu1', torch.nn.ReLU(True))
layer1.add_module('pool1', torch.nn.MaxPool2d(2, 2)) # b, 32, 16, 16 //池化為16*16
return layer1
def layer2(self):
layer2 = torch.nn.Sequential()
layer2.add_module('conv2', torch.nn.Conv2d(32, 64, 3, 1, padding=1))
# b, 64, 16, 16 //處理成64維, 16*16
layer2.add_module('relu2', torch.nn.ReLU(True))
layer2.add_module('pool2', torch.nn.MaxPool2d(2, 2)) # b, 64, 8, 8
return layer2
def layer3(self):
layer3 = torch.nn.Conv2d(64, 32, 1, 1)
return layer3
def forward(self, x):
layer1 = self.layer1(x)
layer2 = self.layer2(layer1)
layer3 = self.layer3(layer2) * self.val
return layer3
if __name__ == '__main__':
batch_size = (4, 6, 8, 3)
input_features = 8
state_size = 9
X = torch.randn((4, 64, 64, 3))
model = MYMODEL(4)
# model.inite_weight_2() # 也可以調用這個函數進行賦值
for params, value in model.state_dict().items():
if 'layer1' in params:
print('[params]:{} [value.size]:{}\n value{}'.format(params, value.shape, value))
結果顯示模塊:
self.modules()實現展示效果:
self.state_dict()展示效果:
self.named_parameters()展示效果:
以下是我2020年9月份寫的,我現在將主要介紹核心代碼提出來,如下所示:
b=torch.ones(m.weight.size())*15
b=torch.Tensor(b)
m.weight=torch.nn.Parameter(b)
可知,以下代碼也是用self.modules()賦值,但主要是用m.weight賦值與
我今天所有m.weight.data賦值手法,有些差異,請仔細閱讀。
import torch
import torch.nn as nn
import torch.optim as optim
import torch.nn.functional as F
# 定義模型
class TheModelClass(nn.Module):
def __init__(self):
super(TheModelClass, self).__init__()
self.conv1 = nn.Conv2d(3, 6, 5)
self.pool = nn.MaxPool2d(2, 2)
self.conv2 = nn.Conv2d(6, 16, 5)
self.fc1 = nn.Linear(16 * 5 * 5, 120)
self.fc2 = nn.Linear(120, 84)
self.fc3 = nn.Linear(84, 10)
for m in self.modules():
if isinstance(m,nn.Conv2d):
m.weight.data.fill_(7)
def forward(self, x):
x = self.pool(F.relu(self.conv1(x)))
x = self.pool(F.relu(self.conv2(x)))
x = x.view(-1, 16 * 5 * 5)
x = F.relu(self.fc1(x))
x = F.relu(self.fc2(x))
x = self.fc3(x)
return x
# 初始化模型
model = TheModelClass()
# 初始化優化器
optimizer = optim.SGD(model.parameters(), lr=0.001, momentum=0.9)
# 模型自定義初始化
for m in model.modules():
if isinstance(m,nn.Conv2d):
b=torch.ones(m.weight.size())*15
b=torch.Tensor(b)
m.weight=torch.nn.Parameter(b)
print(m.weight)