Assigning weights to the feature maps of a convolutional layer

Viewed 48

I'm using a class SE_Block (squeeze and excitation block) and give N feature maps (channels) of a convolutional layer as the input to this SE_Block. My goal is that after using the SE_Block, each of its input feature maps obtain their own weight. In other words, the SE_Block aims to assign a weight for each of the feature maps. But I face the following error:

TypeError: init() missing 1 required positional argument: 'c'

class SE_Block(nn.Module):
"credits: https://github.com/moskomule/senet.pytorch/blob/master/senet/se_module.py#L4"
def __init__(self, c, r=16):
    super().__init__()
    self.squeeze = nn.AdaptiveAvgPool2d(1)
    self.excitation = nn.Sequential(
        nn.Linear(c, c // r, bias=False),
        nn.ReLU(inplace=True),
        nn.Linear(c // r, c, bias=False),
        nn.Sigmoid()
    )

def forward(self, x):
    bs, c, _, _ = x.shape
    y = self.squeeze(x).view(bs, c)
    y = self.excitation(y).view(bs, c, 1, 1)
    return x * y.expand_as(x)

My code:

class myclass(nn.Module):
def __init__(self, in_channel=1024, out_channel=[512], out_sigmoid=False):
    super(myclass, self).__init__()
    
    self.out_sigmoid=out_sigmoid
    
    self.SEBlock = SE_Block()

    self.deconvlayer = self._make_deconv(in_channel, out_channel[0], num_conv=3)
    self.upsample=Upsample(scale_factor=2, mode='bilinear')
    
 
def _make_deconv(self, in_channel, out_channel, num_conv=2, kernel_size=3, stride=1, padding=1):
    layers=[]
    layers.append(BasicConv2d(in_channel, out_channel ,kernel_size=kernel_size, stride=stride, padding=padding))
    for i in range(1, num_conv):
        layers.append(_SepConv2d(out_channel, out_channel,kernel_size=kernel_size, stride=stride, padding=padding))
    
    return nn.Sequential(*layers)

def forward(self, x):
    x=self.deconvlayer(x)
    x = self.upsample(x)
    w = self.SEBlock(x)
    
    return x, w
2 Answers

well, as the error says, __init__ is missing the c parameter.

When you initialize your SE_block the __init__ method inside the constructor will be called, so when this line is executed:

self.SEBlock = SE_Block()

And you do not pass any parameter, but when you define it, you are telling him to expect the c parameter

def __init__(self, c, r=16):

That's why when __init__ runs, the error is raised. To solve the error you can:

  • make c optional (as you did with r) by using def __init__(self, c=16, r=16): or some other number you want
  • pass c when you initialize it, with self.SEBlock = SE_Block(c=16) or whatever number you mean.

When you're creating the SE_block you're not passing the c (channel) argument. You need to add:

class myclass(nn.Module):
    def __init__(self, in_channel=1024, out_channel=512, out_sigmoid=False):

        ...

        self.SEBlock = SE_Block(out_channel)   # Adding argument here

        ...

You also have some errors with the forward part in your class implementation, it should be rewritten like:

class myclass(nn.Module):

    ...

    def forward(self, x):
        x = self.deconvlayer(x)  # Remove the 5_5 part
        x = self.upsample(x)     # Remove the 5_5 part
        w = self.SEBlock(x)
    
        return x, w
Related