Does `register_buffer` make a obj member or cls member?

evilroach: <p>I’m coding a multi-task classification model, with my customized loss func.</p>
<p>While the number of classes of each task are same, each label variables have <strong>different</strong> class weights buffers. So I instanciated loss_func objs for every label var respectively, and let them to hold their own weights buffer, by means of <code>register_buffer()</code>.</p>
<p>Now I need to confirm whether or not <code>register_buffer()</code> would create multiple instances with a same name, and we can simply access the correct ones just like accessing a normal member var of every func obj.</p>
<p>In my example as shown later, although I called <code>register_buffer</code> with a same arg value(name=‘cls_wts’) for all instances of <code>SoftLabelLoss</code>, in fact each obj has its own member var named ‘cls_wts’ with different weight values(No global values, No overwrites)?</p>
<p>If so, I do <strong>NOT</strong> need to find the correct buffer by iterating <code>model.buffers()</code> when it computing loss?</p>
<p><strong>Thanks!!!</strong>*</p>
<pre><code class="lang-auto">class SoftLabelLoss( nn.Module ):
    def __init__( self, class_cnt:int, weights:np.ndarray=None ):
        super().__init__()
        cls_idx = torch.arange( class_cnt, dtype=torch.float32, requires_grad=False )
        cls_idx = cls_idx.unsqueeze( 0 )
        self.register_buffer( name='cls_idx', tensor=cls_idx )

        if( weights ):
            cls_wts = torch.tensor( weights, dtype=torch.float32, requires_grad=False )
            self.register_buffer( name='cls_wts', tensor=cls_wts )
        else:
            self.cls_wts = None

    def forward( self, logits, target ):
        with torch.no_grad():
            ftgts = target.unsqueeze( 1 ).float() # batch_size * 1
            dists = torch.abs( ftgts - self.cls_idx )  # ( batch_size, class_cnt )
            unnorm = torch.exp( -dists )
            soft_labs = unnorm / unnorm.sum( dim=1, keepdim=True )
        log_probs = F.log_softmax( logits, dim=1 )  # ( batch_size, class_cnt )
        loss = - ( soft_labs * log_probs ).sum( dim=1 ) # ( batch_size, )
        if( self.cls_wts ):
            loss *= self.cls_wts[target]
        return loss.mean()
</code></pre>

ptrblck: <aside class="quote no-group" data-username="evilroach" data-post="1" data-topic="220155">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/evilroach/48/53515_2.png" class="avatar"> evilroach:</div>
<blockquote>
<p>Now I need to confirm whether or not <code>register_buffer()</code> would create multiple instances with a same name, and we can simply access the correct ones just like accessing a normal member var of every func obj.</p>
</blockquote>
</aside>
<p>I’m not sure if I understand the question correctly, but <code>register_buffer</code> will register the buffer to the object itself in the same way trainable parameters are registered. E.g. while every <code>nn.Linear</code> module defines trainable parameter via <code>self.weight</code> they will not share these weights as the individual weight is registered to the instantiated object.</p>

evilroach: <p>Sorry for my poor English.<br>
Thanks for your help!</p>