在主函数中创建模型,其中conv_relu_res_relu_block()函数生成一个网络块,经过resblock()为结构体,将block为主体循环block_num次创建网络,输入通道输出通道数分别为input_channel和output_channel。先建立block,然后再将模型块传递到结构体,该种方法在参数传递的过程中会出现误差。因此不能直接传递block。
block = conv_relu_res_relu_block()
print(block)
model = resblock(block=block, block_num=16,input_channel=3,output_channel=31)
# print(model)
if torch.cuda.is_available():
model.cuda()
model.eval()
打印结果为:
#block为内容为:
conv_relu_res_relu_block(
(conv1): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(relu1): ReLU(inplace=True)
(conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(relu2): ReLU(inplace=True)
)
#最后训练结果为:
Epoch [1], Iter[8], Time:33.130220890, learning rate : 0.000199998, Train Loss: 9778.415039062 Test Loss: 0.000000000, testLoss: 0.000000000
Epoch [2], Iter[16], Time:29.219235897, learning rate : 0.000199995, Train Loss: 415.426544189 Test Loss: 0.000000000, testLoss: 0.000000000
Epoch [3], Iter[24], Time:29.250241280, learning rate : 0.000199993, Train Loss: 192.262710571 Test Loss: 0.000000000, testLoss: 0.000000000
Process finished with exit code 0
block 结构体为:
def conv3x3(in_channels, out_channels):
return nn.Conv2d(in_channels, out_channels, kernel_size=3,
stride=1, padding=1, bias=True)
class conv_relu_res_relu_block(nn.Module):
def __init__(self):
super(conv_relu_res_relu_block, self).__init__()
self.conv1 = conv3x3(64, 64)
self.relu1 = nn.ReLU(inplace=True)
self.conv2 = conv3x3(64, 64)
self.relu2 = nn.ReLU(inplace=True)
def forward(self, x):
residual = x
out = self.conv1(x)
out = self.relu1(out)
out = self.conv2(out)
out = torch.add(out,residual)
out = self.relu2(out)
return out
class resblock(nn.Module):
def __init__(self, block, block_num, input_channel, output_channel):
super(resblock, self).__init__()
self.in_channels = input_channel
self.out_channels = output_channel
self.input_conv = conv3x3(self.in_channels, out_channels=64)
self.conv_seq = self.make_layer(block, block_num)
self.conv = conv3x3(64, 64)
self.relu = nn.ReLU(inplace=True)
self.output_conv = conv3x3(in_channels=64, out_channels=self.out_channels)
for m in self.modules():
if isinstance(m, nn.Conv2d):
n=m.kernel_size[0]*m.kernel_size[1]*m.out_channels
m.weight.data.normal_(0,sqrt(2./n))# the devide 2./n carefully
def make_layer(self,block,num_layers):
layers = []
for i in range(num_layers):
layers.append(block) # 在该过程传入的是已经定义的模型
return nn.Sequential(*layers)
def forward(self, x):
out = self.input_conv(x)
residual = out
out = self.conv_seq(out)
out = self.conv(out)
out = torch.add(out,residual)
out = self.relu(out)
out = self.output_conv(out)
return out
我们将主函数改为:
cudnn.benchmark = True
block = conv_relu_res_relu_block
print(block)
model = resblock(block=block, block_num=16,input_channel=3,output_channel=31)
# print(model)
if torch.cuda.is_available():
model.cuda()
model.eval()
将block创建时的“()”去掉,因此传递的参数为class型,而没有真正创建好模型。同样的在定义resblock()时要用到block()。
<class 'resblock.conv_relu_res_relu_block'>
Epoch [1], Iter[8], Time:31.917398214, learning rate : 0.000199998, Train Loss: 277.220520020 Test Loss: 0.000000000, testLoss: 0.000000000
Epoch [2], Iter[16], Time:28.568632841, learning rate : 0.000199995, Train Loss: 8.912072182 Test Loss: 0.000000000, testLoss: 0.000000000
Epoch [3], Iter[24], Time:28.751415253, learning rate : 0.000199993, Train Loss: 2.755993366 Test Loss: 0.000000000, testLoss: 0.000000000
Process finished with exit code 0