How to add a custom class attribute to a subclass of nn.Module?

Nikola_Andro: <p>I’ve created a module that is a subclass of nn.Module and I cannot add a single attribute to it that is not in the superclass.</p>
<pre><code class="lang-auto">class net(nn.Module):
    def __init__(self, input_nc, output_nc, ngf, norm_type = 'batch', act_type='selu', use_dropout=False, n_blocks=6, padding_type='reflect', gpu_ids=[]):
        assert(n_blocks &gt;= 0)
        super(net, self).__init__()

        self.name = 'net'
        self.input_nc = input_nc
        self.output_nc = output_nc
        self.ngf = ngf
        self.gpulist = gpu_ids
        self.num_gpus = len(self.gpulist)

        self.initialization_counter = 0 # I want to add this attribute
</code></pre>
<p>But when I call net.initialization_counter in my script it throws an error:</p>
<pre><code class="lang-auto">AttributeError: 'net' object has no attribute 'initialization_counter'
</code></pre>
<p>How can I register this attribute to be accessible?</p>

ptrblck: <p>It’s working for me:</p>
<pre><code class="lang-python">model = net(1, 1, 1)
print(model.initialization_counter)
# 0
</code></pre>

Nikola_Andro: <p>It seems that I cannot call any additional functions or attributes. Would packaging (<strong>init</strong>.py) have anything to do with this? Seems weird that I cannot access any function or attribute besides the ones from superclass.</p>

ptrblck: <p>I don’t know which <code>__init__.py</code> you mean and since I cannot reproduce the issue, could you post a minimal, executable code which would raise the error?</p>

Nikola_Andro: <p>Thanks for the response.</p>
<p>What I am ultimately trying to do is to have different weight initialization every time I create a model. That is why I tried to add the attribute. Since I cannot, I tried creating a global variable. However, I cannot import this variable in the main script and increment it.</p>
<p>For that I have weights_init() in my model script <strong>my_model.py</strong></p>
<pre><code class="lang-auto">def weights_init(m, act_type='relu'):
    global initialization_counter

    classname = m.__class__.__name__

    # 0: normal_
    # 1: xavier_uniform_
    
    if initialization_counter == 0:
        print("Initializing weights using normal distribution.")
        if classname.find('Conv') != -1:
            if act_type == 'selu':
                n = float(m.in_channels * m.kernel_size[0] * m.kernel_size[1])
                m.weight.data.normal_(0.0, 1.0 / math.sqrt(n))
            else:
                m.weight.data.normal_(0.0, 0.02)        
            if hasattr(m.bias, 'data'):
                m.bias.data.fill_(0)
        elif classname.find('BatchNorm2d') != -1:
            m.weight.data.normal_(1.0, 0.02)
            m.bias.data.fill_(0)
    
    if initialization_counter == 1:
        print("Initializing weights using xavier uniform distribution.")
        if classname.find('Conv') != -1:
            init.xavier_uniform_(m.weight, gain=nn.init.calculate_gain('relu'))
            if hasattr(m.bias, 'data'):
                m.bias.data.fill_(0)
        elif classname.find('BatchNorm2d') != -1:
            m.weight.data.normal_(1.0, 0.02)
            m.bias.data.fill_(0)

</code></pre>
<p>Executing this script by itself is working (I mean in the <strong>main</strong> method of this script).</p>
<p>However, in the <strong>learn.py</strong> I cannot import this global variable. Getting this error:</p>
<pre><code class="lang-auto">from models.my_model import net, weights_init, initialization_counter
ImportError: cannot import name 'initialization_counter' from 'models.my_model'
</code></pre>
<p>my file structure is:</p>
<pre><code class="lang-auto">my_folder
     - learning
          - learn.py
     - models
          - __init__.py
          - my_model.py
</code></pre>
<hr>
<p>On the other hand, when I had self.initialization_counter called as <code>print(model.initialization_counter)</code> I would get the no attribute error.</p>

ptrblck: <aside class="quote no-group" data-username="Nikola_Andro" data-post="5" data-topic="169703">
<div class="title">
<div class="quote-controls"></div>
<img loading="lazy" alt="" width="24" height="24" src="https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/nikola_andro/48/45273_2.png" class="avatar"> Nikola_Andro:</div>
<blockquote>
<p>On the other hand, when I had self.initialization_counter called as <code>print(model.initialization_counter)</code> I would get the no attribute error.</p>
</blockquote>
</aside>
<p>Based on your initial description this was the original issue while you are now trying to include global variables from other scripts if I understand your last description correctly.<br>
Why don’t you use the model attribute as it seems to work?</p>

Nikola_Andro: <aside class="quote no-group" data-username="ptrblck" data-post="6" data-topic="169703">
<div class="title">
<div class="quote-controls"></div>
<img loading="lazy" alt="" width="24" height="24" src="https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/ptrblck/48/1823_2.png" class="avatar"> ptrblck:</div>
<blockquote>
<p>hy don’t you use the model attribute as it seems to work?</p>
</blockquote>
</aside>
<p>Because I get the attribute error that I do not know why I get.</p>
<p>I create an instance of a model and then call model.initialization_counter. I do not know why it throws the no attribute error.</p>
<p>Then I tried introducing the global variable from the same script (my_model.py), and I get “cannot import name” error…</p>
<p>I am very confused…</p>

Nikola_Andro: <p><a class="mention" href="/u/ptrblck">@ptrblck</a> I did not update my <span class="hashtag">#PYTHONPATH</span> variable, when I made a copy of the project and it was still pointing to the old directory…</p>
<p>I am sorry about the confusion. It works now as expected.</p>