

PytorchでAIモデルを構築中です。  
畳み込み層を作成中に以下のエラーメッセージが発生しました。

[code]

        RuntimeError                              Traceback (most recent call last)
    <ipython-input-42-277e33b168b8> in <module>
        767 
        768 if __name__== '__main__':
    --> 769   run()
    
    9 frames
    <ipython-input-42-277e33b168b8> in run()
        763      scaling=False,
        764      overfitting=False,
    --> 765      train_counts=6)
        766 
        767 
    
    <ipython-input-42-277e33b168b8> in main(gpu_id, lr, num_epochs, batch_size, weight_decay, pretrained_model, pretrained_type, start_idx, end_idx, freeze_layer, output_dir, early_stopping, downscale_median, scaling, augmentation, overfitting, train_counts)
        564                               loss_type='MSE&Cosine',
        565                               corr_w=corr_w,
    --> 566                               score_metric="spearmanr")
        567 
        568 
    
    <ipython-input-34-85643d1c012f> in val(val_loader, model, use_gpu_number, criterion, loss_type, corr_w, score_metric, mean_outputs)
         20           time_course = Variable(time_course.cuda(use_gpu_number)).type(torch.cuda.FloatTensor)
         21 
    ---> 22           output = model(track)
         23 
         24           if loss_type == 'RMSE':
    
    /usr/local/lib/python3.7/dist-packages/torch/nn/modules/module.py in _call_impl(self, *input, **kwargs)
       1128         if not (self._backward_hooks or self._forward_hooks or self._forward_pre_hooks or _global_backward_hooks
       1129                 or _global_forward_hooks or _global_forward_pre_hooks):
    -> 1130             return forward_call(*input, **kwargs)
       1131         # Do not call functions when jit is used
       1132         full_backward_hooks, non_full_backward_hooks = [], []
    
    <ipython-input-28-c1073582f8a6> in forward(self, input)
        187             if model_number != self.train_counts*-2-1:
        188                 t_out = nn.Upsample(scale_factor=2, mode='nearest')(t_out)
    --> 189             l_out = self.cnn[model_number+1](out_list[out_number])
        190             t_out = transforms.CenterCrop([l_out.shape[2], l_out.shape[3]])(t_out)
        191             out = torch.cat((t_out, l_out), 1)
    
    /usr/local/lib/python3.7/dist-packages/torch/nn/modules/module.py in _call_impl(self, *input, **kwargs)
       1128         if not (self._backward_hooks or self._forward_hooks or self._forward_pre_hooks or _global_backward_hooks
       1129                 or _global_forward_hooks or _global_forward_pre_hooks):
    -> 1130             return forward_call(*input, **kwargs)
       1131         # Do not call functions when jit is used
       1132         full_backward_hooks, non_full_backward_hooks = [], []
    
    /usr/local/lib/python3.7/dist-packages/torch/nn/modules/container.py in forward(self, input)
        137     def forward(self, input):
        138         for module in self:
    --> 139             input = module(input)
        140         return input
        141 
    
    /usr/local/lib/python3.7/dist-packages/torch/nn/modules/module.py in _call_impl(self, *input, **kwargs)
       1128         if not (self._backward_hooks or self._forward_hooks or self._forward_pre_hooks or _global_backward_hooks
       1129                 or _global_forward_hooks or _global_forward_pre_hooks):
    -> 1130             return forward_call(*input, **kwargs)
       1131         # Do not call functions when jit is used
       1132         full_backward_hooks, non_full_backward_hooks = [], []
    
    /usr/local/lib/python3.7/dist-packages/torch/nn/modules/conv.py in forward(self, input)
        455 
        456     def forward(self, input: Tensor) -> Tensor:
    --> 457         return self._conv_forward(input, self.weight, self.bias)
        458 
        459 class Conv3d(_ConvNd):
    
    /usr/local/lib/python3.7/dist-packages/torch/nn/modules/conv.py in _conv_forward(self, input, weight, bias)
        452                             _pair(0), self.dilation, self.groups)
        453         return F.conv2d(input, weight, bias, self.stride,
    --> 454                         self.padding, self.dilation, self.groups)
        455 
        456     def forward(self, input: Tensor) -> Tensor:
    
    RuntimeError: Given groups=1, weight of size [32, 32, 3, 3], expected input[32, 256, 10, 256] to have 32 channels, but got 256 channels instead
    
[/code]

現在作成しているのはTDMという脳内の処理を模倣したAIの実装です。  
恐らくエラーが出ているのは、L_0というレイヤーだと思います。  
しかしこのレイヤーは lateral layerと言って、入力と出力のチャンネル数が等しくないといけません。  
元になっている資料は以下のものです。  
<https://www.arxiv-vanity.com/papers/1612.06851/>

それも考慮すると、どう対処していいのかわからず質問させていただきました。  
書いたコードは以下の通りです。

[code]

    from pandas.core.api import to_datetime
    from operator import ifloordiv
    from torchvision import transforms
    
    
    class CRNN_VGG_BN_3FC_MaxPool(nn.Module):
        """
        Adapted from Choi, 2017 and Malik, 2017
        """
        def __init__(self, weight_init=False,
                     verbose=False,
                     gpu_id=0,
                     cnc=[32, 64, 128 ,128,256,256,512],
                     transfer=False,
                     train_counts=6):
          
            super(CRNN_VGG_BN_3FC_MaxPool, self).__init__()
            pooling = [(2, 2), (2, 2), (2, 2), (2,2), (2,2), (2,4),(4,4)]
            kernel_size = (2, 2)
            conv_num_channels = cnc
            num_conv = 7
    
            self.verbose = verbose
            self.train_counts = train_counts
    
            # cnn construction
            cnn = nn.Sequential()
            cnn.add_module("BN" + str(0), 
                           nn.BatchNorm2d(1))
            for i in range(num_conv):
    
              if i == 0:
                    prev_out_channels = 1
    
              else:
                prev_out_channels = conv_num_channels[i - 1]
    
              cnn.add_module("Conv" + str(i), 
                             self.conv_elu(i, prev_out_channels, conv_num_channels[i])) 
              cnn.add_module("MaxPooling" + str(i), 
                             nn.MaxPool2d(pooling[i],
                                          stride=(2,2)))
              
            self.cnn = cnn
         
    
            # ====================================================
            # ====================== TDM =========================
            # ====================================================
    
            tdm = nn.Sequential()
    
            t_dim_list = [(512, 512), (768, 384), (640, 384), (512, 128),(256,64),(128,32)]
            l_dim_list = [(256, 256), (256, 256), (128, 128), (128, 128),(64,64),(32,32)]
            model_number_list = [5,4,3, 2, 1, 0]
            # ============= Add TDM =============
            for i in range(self.train_counts):
              model_number = model_number_list[i]
                # ============ Make T Layer ============
              block = nn.Sequential()
              block.add_module('Conv_T', nn.Conv2d(t_dim_list[i][0],
                                                   t_dim_list[i][1],
                                                   kernel_size=(3, 3),
                                                   stride=1,
                                                   padding=1))
              
              block.add_module('ReLU_T', nn.ReLU())
              tdm.add_module(f'T_{model_number+1},{model_number}', block)
                # ============ Make L Layer ============
              block = nn.Sequential()
              block.add_module('Conv_L', nn.Conv2d(l_dim_list[i][0],
                                                 l_dim_list[i][1],
                                                 kernel_size=(3, 3),
                                                 stride=1,
                                                 padding=1))
              block.add_module('ReLU_L', nn.ReLU())
              tdm.add_module(f'L_{model_number}', block)
    
              
            ##################
            ########.  T_out layerをここに追加してしまおう
    
            block = nn.Sequential()
            block.add_module('Conv_T_out', 
                             nn.Conv2d(64,
                                       512,
                                       kernel_size=(3,3)))
            block.add_module('ReLU_T_out', nn.ReLU())
            tdm.add_module('T_out_0', block)
            
    
            self.tdm = tdm
    
    
    
            self.AdaptiveMaxPool2d = nn.AdaptiveMaxPool2d((1, 16)) 
            self.AdaptiveAvgPool2d = nn.AdaptiveAvgPool2d((1, 16))
    
            # rnn construction
            self.rnn_nHidden = 64
            self.rnn_nLayer = 2
            self.rnn = nn.LSTM(input_size=512,
                               hidden_size=self.rnn_nHidden,
                               num_layers=self.rnn_nLayer,
                               dropout=0.75,
                               bidirectional=True)
            self.linear = nn.Sequential(TimeDistributed(nn.Linear(self.rnn_nHidden * 2, self.rnn_nHidden)),
                                        nn.BatchNorm1d(16),
                                        nn.ELU(), #Expotential Linear Unit
                                        nn.Dropout(0.5),
                                        TimeDistributed(nn.Linear(self.rnn_nHidden, int(self.rnn_nHidden/2))),
                                        nn.BatchNorm1d(16),
                                        nn.ELU(),
                                        nn.Dropout(0.1),
                                        nn.Linear(int(self.rnn_nHidden/2), 1))
            self.gpu_id = gpu_id
            if weight_init:
                self.cnn.apply(self.weight_init)
                self.linear.apply(self.weight_init)
    
       
    
        def conv_elu(self, i, in_channels, out_channels):
            """
            Convolution Block consists of Conv2d + BatchNorm + Elu
            """
            block = nn.Sequential()
            if i >0:
                for j in range(3):
                    if j < 2:
                        block.add_module("Conv_{}_{}".format(i, j), nn.Conv2d(in_channels,
                                                                    in_channels,
                                                                    kernel_size=(3, 3),
                                                                    stride=1,
                                                                    padding=1))
                        block.add_module("ELU_{}_{}".format(i, j), nn.ELU())
                    else:
                        block.add_module("Conv_{}_{}".format(i, j), nn.Conv2d(in_channels,
                                                                              out_channels,
                                                                              kernel_size=(3, 3),
                                                                              stride=1,
                                                                              padding=1))
                        block.add_module("BN_{}_{}".format(i, j), nn.BatchNorm2d(out_channels))
                        block.add_module("ELU_{}_{}".format(i, j), nn.ELU())
            else:
                block.add_module("Conv_{}".format(i), nn.Conv2d(in_channels,
                                                                  out_channels,
                                                                  kernel_size=(3, 3),
                                                                  stride=1,
                                                                  padding=1))
                block.add_module("BN_{}".format(i), nn.BatchNorm2d(out_channels))
                block.add_module("ELU_{}".format(i), nn.ELU())
            return block
    
        def weight_init(self, m):
            """
            Kaiming He Weight init
            """
            if isinstance(m, (nn.Conv2d, nn.Linear)):
              nn.init.kaiming_normal(m.weight, mode='fan_in', nonlinearity='relu') 
            elif isinstance(m, (nn.BatchNorm2d, nn.BatchNorm1d)):
                nn.init.constant_(m.weight, 1) 
                nn.init.constant_(m.bias, 0)
    
        def forward(self, input):
            # =========== CNN Forward ============
            conv = self.cnn.BN0(input)
            conv0 = self.cnn.Conv0(conv)
            conv0 = self.cnn.MaxPooling0(conv0)
            conv1 = self.cnn.Conv1(conv0)
            #conv1 = self.cnn.MaxPooling1(conv1)
            conv2 = self.cnn.Conv2(conv1)
            conv2 = self.cnn.MaxPooling2(conv2)
            conv3 = self.cnn.Conv3(conv2)
            #conv3 = self.cnn.MaxPooling3(conv3)
            conv4 = self.cnn.Conv4(conv3)
            conv4 = self.cnn.MaxPooling4(conv4)
            conv5 = self.cnn.Conv5(conv4)
            #conv5 = self.cnn.MaxPooling5(conv5)
            out = self.cnn.Conv6(conv5)
            # ============ T, L Layer Forward ============
            out_list = [conv5,conv4,conv3, conv2, conv1, conv0]
            for model_number, out_number in zip(range((self.train_counts*-2)-1, -1, 2), range(4)):
                t_out = self.cnn[model_number](out)
                if model_number != self.train_counts*-2-1:          
                    t_out = nn.Upsample(scale_factor=2, mode='nearest')(t_out) 
                l_out = self.cnn[model_number+1](out_list[out_number])
                t_out = transforms.CenterCrop([l_out.shape[2], l_out.shape[3]])(t_out)
                out = torch.cat((t_out, l_out), 1)
    
            # ============ T out Layer Forward ============
            if self.train_counts > 0:
                out = self.cnn[-1](out)
            # =========== Pooling ============
            if self.train_counts == 0 or self.train_counts == 1:
                out = self.cnn.MaxPooling4(out)
            else:
                out = self.AdaptiveMaxPool2d(out)
    
            # =========== Reshape ============
            b, c, h, w = out.size()
            out = out.view(b, c, -1)
            conv = out.permute(2, 0, 1) 
            # ============ RNN ===========
            rnn, hidden = self.rnn(conv)
            rnn = rnn.permute(1, 0, 2)
            # =========== linear regression ===========
            output = self.linear(rnn)
            # =========== Reshape ===========
            b, c, w = output.size()
            output = output.view(b, -1)
    
            return output
    
[/code]


CC BY-SA 4.0
2022-09-14T08:19:01.787
91104
2023-02-28T04:11:26.417
2022-09-14T09:43:42.853
54391
54391
question
python pytorch
Given groups=1, weight of size [], expected input[] to have channels, but got channels insteadの解決を手伝っていただけないでしょうか？


時間も経過しており既に解決済みかもしれませんが御参考です。  
参考資料の TDM(Top-Down Modulation) のブロック図（Figure
2）を参照しながらコードを拝見すると，C層（ボトムアップパス）の計算は `self.cnn` が担当し，L層（ラテラルパス）と
T層（トップダウンパス）の計算は `self.tdm` が担当すると読み取れます。  
一方，エラーとなっている `l_out = self.cnn[model_number+1](out_list[out_number])` は
L層の計算をしているにもかかわらず `self.cnn` が使われています。そこで，`t_out =
self.cnn[model_number](out)` も合わせて `self.cnn` を `self.tdm` に置き換えたところ for
ループではエラーは発生しなくなりました。  
次に，出力前の `RNN` ブロックの `rnn, hidden = self.rnn(conv)`
でもチャンネル不整合のエラーが発生するので，`self.rnn` の構築部分の `self.rnn = nn.LSTM(input_size=512,` を
`self.rnn = nn.LSTM(input_size=256` に変更しました。  
提示されたコードに上記の3カ所の変更を行い，先頭に

[code]

    import torch
    from torch import nn
    from pytorch_forecasting.models.temporal_fusion_transformer.sub_modules import TimeDistributed
    
[/code]

を追加をしたものを「tdm_module.py」に保存し，下記の記述例を実行した場合の出力（32行16列）の一部を示します。

[code]

    import torch
    import tdm_module
    
    torch.manual_seed(11)
    
    model = tdm_module.CRNN_VGG_BN_3FC_MaxPool()
    
    x = torch.randn(32, 1, 10 * 8, 256 * 8)
    print(model(x))
    
[/code]

[code]

    tensor([[-8.8882e-02, -3.1479e-01,  1.3590e-01, -6.0990e-02, -1.1239e-01,
             -3.5339e-02, -1.2717e-01, -8.5867e-02, -7.9190e-01,  7.5079e-01,
              2.9482e-02,  8.2766e-02, -8.2027e-02, -4.4313e-01,  8.1381e-02,
             -3.9718e-01],
            [-4.8103e-02,  5.8515e-02, -3.8677e-01,  1.5168e-01,  3.2936e-01,
              2.8742e-01,  2.9059e-01,  2.2381e-01, -9.4020e-01, -4.1080e-01,
             -5.9306e-02, -1.7687e-01,  1.8825e-01,  6.2861e-02,  5.9015e-01,
             -1.4683e-01],
             ...
            [-1.5363e-02, -4.0786e-01, -5.7508e-01, -5.1503e-01, -3.4224e-01,
             -1.3823e-01, -8.9653e-01, -3.1752e-01, -2.9232e-02, -1.1686e-02,
              2.2664e-01,  2.8617e-01, -2.3849e-01, -3.7007e-02,  3.3500e-02,
             -2.8974e-01],
            [-4.9130e-01, -2.0382e-01,  1.2202e-01, -4.5300e-01,  6.2589e-03,
              5.9880e-02,  1.7218e-01, -2.0273e-01, -5.3178e-01, -3.7083e-01,
             -2.0129e-01, -3.6231e-01,  3.2738e-01,  2.0378e-01, -6.2566e-02,
             -4.6619e-01]], grad_fn=<ViewBackward0>)
    
[/code]


CC BY-SA 4.0
2023-01-18T06:59:18.350
93427
2023-01-18T06:59:18.350
54588
91104
answer