

pspnetを実装しようとしているのですが、pspnetのエンコーダ部分で2048のチャンネル数を求められているのに実際は1024のチャンネル数で一致しないというエラーが表示され、この問題についてパラメータを変更したりインターネットで調べてみたのですが、結局わからなかったです。どこが原因なのでしょうか。  
回答お願いします。

見づらくて申し訳ないのですが、エラー文は一番下の方にあります。

[code]

    class PyramidModule(nn.Module):
        def __init__(self, in_channels, out_channels, sizes=(1, 2, 3, 6)):
            super(PyramidModule, self).__init__()
            self.stages = nn.ModuleList([self._make_stage(in_channels, size) for size in sizes])
            self.conv = nn.Conv2d(in_channels * (len(sizes) + 1), out_channels, kernel_size=1)
    
        def _make_stage(self, in_channels, size):
            prior = nn.AdaptiveAvgPool2d(output_size=(size, size))
            conv = nn.Conv2d(in_channels, in_channels // 4, kernel_size=1, bias=False)
            return nn.Sequential(prior, conv)
    
        def forward(self, x):
            h, w = x.size(2), x.size(3)
            priors = [F.interpolate(stage(x), size=(h, w), mode='bilinear', align_corners=True) for stage in self.stages]
            priors.append(x)
            output = self.conv(torch.cat(priors, 1))
            return output
        
    class ResNet(nn.Module):
        def __init__(self, block, layers, num_classes=1000, zero_init_residual=True):
            super(ResNet, self).__init__()
            self.inplanes = 128
    
            self.conv1 = nn.Conv2d(3, 64, kernel_size=7, stride=2, padding=3, bias=False)
            self.bn1 = nn.BatchNorm2d(64)
            self.relu = nn.ReLU(inplace = True)
            self.maxpool = nn.MaxPool2d(kernel_size = 3 , stride = 2 , padding = 1)
            
            self.layer1 = self._make_layer(block , 64 , layers[0] , stride = 1)
            self.layer2 = self._make_layer(block , 128 , layers[1] , stride = 2)
            self.layer3 = self._make_layer(block , 256 , layers[2] , stride = 2)
            self.layer4 = self._make_layer(block , 512 , layers[3] , stride = 2)
      
        def _make_layer(self, block, planes, blocks, stride=1):
            downsample = None
            if stride != 1 or self.inplanes != planes * block.expansion:
                downsample = nn.Sequential(
                    nn.Conv2d(self.inplanes, planes * block.expansion, kernel_size=1, stride=stride, bias=False),
                    nn.BatchNorm2d(planes * block.expansion),
                )
    
            layers = []
            layers.append(block(self.inplanes, planes, stride, downsample))
            self.inplanes = planes * block.expansion
            for _ in range(1, blocks):
                layers.append(block(self.inplanes, planes))
    
            return nn.Sequential(*layers)
        
    class PSPNet(nn.Module):
        def __init__(self, block, layers, num_classes=1000, zero_init_residual=True):
            super(PSPNet, self).__init__()
            self.resnet = ResNet(block, layers, num_classes=num_classes, zero_init_residual=zero_init_residual)
    
            psp_out_channels = 512 
            decoder_out_channels = 256
            self.pyramid = PyramidModule(2048, psp_out_channels)
            self.final_conv = nn.Conv2d(decoder_out_channels, num_classes, kernel_size=1)
    
        def forward(self, x):
            x = self.resnet.conv1(x)
            x = self.resnet.bn1(x)
            x = self.resnet.relu(x)
            x = self.resnet.maxpool(x)
    
            x = self.resnet.layer1(x)
            x = self.resnet.layer2(x)
            x = self.resnet.layer3(x)
            x = self.resnet.layer4(x)
            
            x = self.pyramid(x)
            x = self.final_conv(x)
    
            return x
    
[/code]

追加した部分です

[code]

    batch_size = 32
    num_epochs = 10
    learning_rate = 0.001
    
    
    model = PSPNet(Bottleneck, [3,4,6,3])
    
    criterion = torch.nn.CrossEntropyLoss()
    optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)
    
    for epoch in range(num_epochs):
        for images, labels in train_df_loader:
            images = images.to(device)
            labels = labels.to(device)
    
            optimizer.zero_grad()
    
            outputs = model(images)
    
            loss = criterion(outputs, labels)
    
            optimizer.zero_grad()
            loss.backward()
            optimizer.step()
    
            print(f"Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.4f}")
    
    torch.save(model.state_dict(), 'pspnet_model.pth')
    
[/code]

エラー内容

[code]

    ---------------------------------------------------------------------------
    RuntimeError                              Traceback (most recent call last)
    <ipython-input-15-8404aaecff27> in <cell line: 6>()
         11         optimizer.zero_grad()
         12 
    ---> 13         outputs = model(images)
         14 
         15         loss = criterion(outputs, labels)
    
    9 frames
    /usr/local/lib/python3.10/dist-packages/torch/nn/modules/conv.py in _conv_forward(self, input, weight, bias)
        457                             weight, bias, self.stride,
        458                             _pair(0), self.dilation, self.groups)
    --> 459         return F.conv2d(input, weight, bias, self.stride,
        460                         self.padding, self.dilation, self.groups)
        461 
    
    RuntimeError: Given groups=1, weight of size [512, 2048, 1, 1], expected input[16, 1024, 1, 1] to have 2048 channels, but got 1024 channels instead
    
[/code]


CC BY-SA 4.0
2023-07-26T13:23:35.817
95768
2023-07-26T15:05:55.790
2023-07-26T15:05:55.790
59240
59240
question
python 画像認識
pspnetのコードを実装する際に表示されるエラーの理由がわかりません。