class NLayerDiscriminator(nn.Module): def init(self, input_nc=3, ndf=64, n_layers=3, norm_layer=nn.BatchNorm2d, use_sigmoid=False, use_parallel=True): super(NLayerDiscriminator, self).init() self.use_parallel = use_parallel if type(norm_layer) == functools.partial: use_bias = norm_layer.func == nn.InstanceNorm2d else: use_bias = norm_layer == nn.InstanceNorm2d self.conv1 = nn.Conv2d(input_nc, ndf, kernel_size=3, padding=1) self.conv_offset1 = nn.Conv2d(ndf, 18, kernel_size=3, stride=1, padding=1) init_offset1 = torch.Tensor(np.zeros([18, ndf, 3, 3])) self.conv_offset1.weight = torch.nn.Parameter(init_offset1) # 初始化为0 self.conv_mask1 = nn.Conv2d(ndf, 9, kernel_size=3, stride=1, padding=1) init_mask1 = torch.Tensor(np.zeros([9, ndf, 3, 3]) + np.array([0.5])) self.conv_mask1.weight = torch.nn.Parameter(init_mask1) # 初始化为0.5 kw = 4 padw = int(np.ceil((kw-1)/2)) nf_mult = 1 for n in range(1, n_layers): nf_mult_prev = nf_mult nf_mult = min(2n, 8) self.sequence2 = [ nn.Conv2d(ndf * nf_mult_prev, ndf * nf_mult, kernel_size=kw, stride=2, padding=padw, bias=use_bias), norm_layer(ndf * nf_mult), nn.LeakyReLU(0.2, True) ] nf_mult_prev = nf_mult nf_mult = min(2n_layers, 8) self.sequence2 += [ nn.Conv2d(ndf * nf_mult_prev, ndf * nf_mult, kernel_size=kw, stride=1, padding=padw, bias=use_bias), norm_layer(ndf * nf_mult), nn.LeakyReLU(0.2, True) ] self.sequence2 += [nn.Conv2d(ndf * nf_mult, 1, kernel_size=kw, stride=1, padding=padw)] if use_sigmoid: self.sequence2 += [nn.Sigmoid()] def forward(self, input): input = self.conv1(input) offset1 = self.conv_offset1(input) mask1 = torch.sigmoid(self.conv_mask1(input)) sequence1 = [ torchvision.ops.deform_conv2d(input=input, offset=offset1, weight=self.conv1.weight, mask=mask1, padding=(1, 1)) ] sequence2 = sequence1 + self.sequence2 self.model = nn.Sequential(*sequence2) nn.LeakyReLU(0.2, True) return self.model(input),上述代码中:出现错误:torchvision.ops.deform_conv2d(input=input, offset=offset1,RuntimeError: Expected weight_c.size(1) * n_weight_grps == input_c.size(1) to be true, but got false. (Could this error message be improved? If so, please report an enhancement request to PyTorch.)
时间: 2023-08-21 22:06:26 浏览: 205
NDF.rar_NDF_牛顿法_牛顿法方程组
这个错误是由于输入的通道数和权重的通道数不匹配导致的。在这段代码中,使用了deformable convolution操作,该操作需要使用偏移量和掩码对输入进行卷积,其中偏移量和掩码都是通过卷积层生成的。在这个模型中,第一个卷积层的输出通道数为ndf,而第一个偏移量卷积层的输出通道数为18,第一个掩码卷积层的输出通道数为9。因此,当使用deformable convolution对输入进行卷积时,需要使用第一个卷积层的权重,偏移量和掩码,但是由于通道数不匹配,导致出现了上述错误。
要解决这个问题,可以修改偏移量和掩码卷积层的输出通道数,使其与第一个卷积层的输出通道数相同。具体来说,可以将偏移量卷积层的输出通道数修改为ndf*2,掩码卷积层的输出通道数修改为ndf。同时,需要相应地修改初始化偏移量和掩码的代码。修改后的代码如下:
```
class NLayerDiscriminator(nn.Module):
def __init__(self, input_nc=3, ndf=64, n_layers=3, norm_layer=nn.BatchNorm2d, use_sigmoid=False, use_parallel=True):
super(NLayerDiscriminator, self).__init__()
self.use_parallel = use_parallel
if type(norm_layer) == functools.partial:
use_bias = norm_layer.func == nn.InstanceNorm2d
else:
use_bias = norm_layer == nn.InstanceNorm2d
self.conv1 = nn.Conv2d(input_nc, ndf, kernel_size=3, padding=1)
self.conv_offset1 = nn.Conv2d(ndf, ndf*2, kernel_size=3, stride=1, padding=1)
init_offset1 = torch.Tensor(np.zeros([ndf*2, ndf, 3, 3]))
self.conv_offset1.weight = torch.nn.Parameter(init_offset1) # 初始化为0
self.conv_mask1 = nn.Conv2d(ndf, ndf, kernel_size=3, stride=1, padding=1)
init_mask1 = torch.Tensor(np.zeros([ndf, ndf, 3, 3]) + np.array([0.5]))
self.conv_mask1.weight = torch.nn.Parameter(init_mask1) # 初始化为0.5
kw = 4
padw = int(np.ceil((kw-1)/2))
nf_mult = 1
for n in range(1, n_layers):
nf_mult_prev = nf_mult
nf_mult = min(2**n, 8)
self.sequence2 = [
nn.Conv2d(ndf * nf_mult_prev, ndf * nf_mult, kernel_size=kw, stride=2, padding=padw, bias=use_bias),
norm_layer(ndf * nf_mult),
nn.LeakyReLU(0.2, True)
]
nf_mult_prev = nf_mult
nf_mult = min(2**n_layers, 8)
self.sequence2 += [
nn.Conv2d(ndf * nf_mult_prev, ndf * nf_mult, kernel_size=kw, stride=1, padding=padw, bias=use_bias),
norm_layer(ndf * nf_mult),
nn.LeakyReLU(0.2, True)
]
self.sequence2 += [nn.Conv2d(ndf * nf_mult, 1, kernel_size=kw, stride=1, padding=padw)]
if use_sigmoid:
self.sequence2 += [nn.Sigmoid()]
def forward(self, input):
input = self.conv1(input)
offset1 = self.conv_offset1(input)
mask1 = torch.sigmoid(self.conv_mask1(input))
sequence1 = [
torchvision.ops.deform_conv2d(input=input, offset=offset1[:, :18, :, :], weight=self.conv1.weight, mask=mask1, padding=(1, 1))
]
sequence2 = sequence1 + self.sequence2
self.model = nn.Sequential(*sequence2)
nn.LeakyReLU(0.2, True)
return self.model(input)
```
阅读全文