AttributeError: cannot assign module before Module.__init__() call even if initialized

I’m getting the following error:
AttributeError: cannot assign module before Module.__init__() call.

I’m trying to create an instance of my class :

class ResNetGenerator(nn.Module):
    def __init__(self, input_nc=3, output_nc=3, n_residual_blocks=9, use_dropout=False):
        # super(ResNetGenerator, self).__init__()
        super().__init__()

I’m calling super().__init__() but in vain.

What I am doing wrong here?

Your posted code looks alright and is working on my machine.
Did you check the right code indent?

@ptrblck Thanks for your response. Yes, I checked the indentation. Indeed, my code runs normally and executes __init__ until the end, the problem rises when the __setattr__ function is called.

Here is the code of my Class:

class ResNetGenerator(nn.Module):
    def __init__(self, input_nc=3, output_nc=3, n_residual_blocks=9, use_dropout=False):
        print("*"*50)
        super(ResNetGenerator, self).__init__()
        # super().__init__()
        # nn.Module.__init__(self)

        # Input layer
        model = [nn.ReflectionPad2d(3),
                 nn.Conv2d(input_nc, 64, kernel_size=7, padding=0),
                 nn.InstanceNorm2d(64),
                 nn.ReLU(True)]

        # Encoding layers
        in_features = 64
        out_features = in_features * 2

        for _ in range(2):
            model += [nn.Conv2d(in_features, out_features, kernel_size=3, stride=2, padding=1),
                      nn.InstanceNorm2d(out_features),
                      nn.ReLU(True)]
            in_features = out_features
            out_features = in_features * 2

        # Transformations layers (Residual blocks)
        for _ in range(n_residual_blocks):
            model += [ResidualBlock(in_features, use_dropout)]
        # Decoding layers
        out_features = in_features // 2

        for _ in range(2):
            model += [nn.ConvTranspose2d(in_features, out_features, kernel_size=3, stride=2, padding=1, output_padding=1),
                      nn.InstanceNorm2d(out_features),
                      nn.ReLU(True)]
            in_features = out_features
            out_features = in_features // 2

        # Output layer
        model += [nn.ReflectionPad2d(3),
                  nn.Conv2d(64, output_nc, kernel_size=7, padding=0),
                  nn.Tanh()]

        self.model = nn.Sequential(*model)
        print("#"*50)

    def forward(self, x):
        return self.model(x)

And Here is the complete Traceback:

File "train.py", line 40, in <module>
    model = ColorizationCycleGAN(args)
File "/path/cycle_gan.py", line 27, in __init__
    self.G_A2B = ResNetGenerator(input_nc=self.input_nc, output_nc=self.output_nc, n_residual_blocks=9, use_dropout=False)
File "/path/.local/lib/python3.6/site packages/torch/nn/modules/module.py", line 544, in __setattr__
    "cannot assign module before Module.__init__() call")
AttributeError: cannot assign module before Module.__init__() call

Could you post the definition of ResidualBlock?
If I remove it, the code still works, so the error might be in the definition of ResidualBlock.

@ptrblck , Here is the definition of ResidualBlock:

class ResidualBlock(nn.Module):
    def __init__(self, in_features, use_dropout):
        # super(ResidualBlock, self).__init__()
        super().__init__()
        conv_block = [nn.ReflectionPad2d(1),
                      nn.Conv2d(in_features, in_features, 3, padding=0),
                      nn.InstanceNorm2d(in_features),
                      nn.ReLU(inplace=True),
                      nn.ReflectionPad2d(1),
                      nn.Conv2d(in_features, in_features, 3, padding=0),
                      nn.InstanceNorm2d(in_features)]
        if use_dropout:
            conv_block.insert(4, nn.Dropout(0.5))

        self.conv_block = nn.Sequential(*conv_block)

    def forward(self, x):
        return x + self.conv_block(x)

Thanks for the code. It still works on my machine with PyTorch 1.0.0.dev20181217 and Python3.7.
As far as I know, you would have to use the first super call with the class name and self in Python2.x.
Could this be the reason for the error you are getting?

Thanks for your response. I checked my Python and Pytorch versions. I’m using Python 3.6.7 and Pytorch 0.4.1, maybe should I update my Pytorch version?
Concerning the super call, I tried the two methods but in vain.

Oh, it seems I’ve missed an important line in the stack trace.

File "train.py", line 40, in <module>
    model = ColorizationCycleGAN(args)

Could you check your definition of ColorizationCycleGAN?
I would always recommend to update to the latest release, but this error seems unrelated to your PyTorch version.

3 Likes

@ptrblck, Thank you very much for your support. Indeed, I realized that I did not call super().__init__() in ColorizationCycleGAN.
This mistake took me a long time, I thank you very much for your help.

2 Likes

Good to hear it’s working!
Now you should update PyTorch to 1.0. :wink:
You’ll find the install instructions here.

1 Like