Torch:AttributeError: 'StyleLoss' object has no attribute 'loss'

username: 111336
cooked: <p>Hey there, below is part of my code</p>
<pre><code class="lang-auto">class ContentLoss(nn.Module):
    def __init__(self,target,weight):
        super(ContentLoss,self).__init__()
        #detach the original computing graph-&gt;weight graph
        self.target=target.detach()*weight
        self.weight=weight
        self.criterion=nn.MSELoss()
    def forward(self,input):
        self.loss=self.criterion(input*self.weight,self.target)#MSE LOSS
        self.output=input
        return self.output
    def backward(self,retain_graph=True):
        self.loss.backward(retain_graph=retain_graph)
        return self.loss
======
class StyleLoss(nn.Module):
    def __init__(self,target,weight):
        super(StyleLoss,self).__init__()
        self.target=target.detach()*weight
        self.weight=weight
        #self.gram=GramMatrix()
        self.criterion=nn.MSELoss()
    def forward(self,input):
        self.output=input.clone()
        input=input.cuda()
        self_G=Gram(input)
        self_G.mul_(self.weight)
        self.loss=self.criterion(self_G,self.target)
        return self.output
    def backward(self,retain_graph=True):
        self.loss.backward(retain_graph=retain_graph)
        return self.loss
def Gram(input):
    a,b,c,d=input.size()#a=batch_size,b=number of features (c,d)=N=c*d-&gt;dimension of visualization
    features=input.view(a*b,c*d)
    G=torch.mm(features,features.t())
    return G.div(a*b*c*d)
=====
content_losses=[]
style_losses=[]
model=nn.Sequential()
model=model.cuda()
i=1
for layer in list(cnn):
    if isinstance(layer,nn.Conv2d):
        name="conv_"+str(i)
        model.add_module(name,layer)
    if name in content_layers:
        target=model(content_img).clone()
        content_loss=ContentLoss(target,content_weight)#content_weight=1000
        content_loss=content_loss.cuda()
        model.add_module("content_loss"+str(i),content_loss)
        content_losses.append(content_loss)
    if name in style_layers:
        target_feature=model(style_img).clone()
        target_feature=target_feature.cuda()
        #print(target_feature)
        target_feature_gram=Gram(target_feature)
        style_loss=StyleLoss(target_feature_gram,style_weight)#style_weight=1
        style_losses.append(style_loss)
    if isinstance(layer,nn.ReLU):
        name="ReLU"+str(i)
        model.add_module(name,layer)
        print(i)
        i+=1
    if isinstance(layer,nn.MaxPool2d):
        name="MaxPool"+str(i)
        model.add_module(name,layer)
==========
input_param=nn.Parameter(input_img.data)
optimizer=optim.LBFGS([input_param])
num_steps=300
for i in range(num_steps):
    input_param.data.clamp_(0,1)
    optimizer.zero_grad()
    model(input_param)
    style_score=0
    content_score=0
    for sl in style_losses:
       --------------------------------&gt;&gt;&gt; style_score+=sl.backward()
    for cl in content_losses:
       --------------------------------&gt;&gt;&gt; content_score+=cl.backward()
    if i%50==0:
        print("num{}epochs".format(i))
        print("StyleLoss{:4f},Content_loss{:4f}".format(style_score.data[0],content_score.data[0]))
    def closure():
        return style_score+content_score
output=input_param.data.clamp_(0,1)
plt.figure()
inshow(output,title="output Image")
plt.ioff()
plt.show()

And the Error:
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
&lt;ipython-input-67-2426f976e393&gt; in &lt;module&gt;
      1 for sl in style_losses:
----&gt; 2         style_score+=sl.backward()

c:\python36\lib\site-packages\torch\nn\modules\module.py in __getattr__(self, name)
    589                 return modules[name]
    590         raise AttributeError("'{}' object has no attribute '{}'".format(
--&gt; 591             type(self).__name__, name))
    592 
    593     def __setattr__(self, name, value):

AttributeError: 'StyleLoss' object has no attribute 'loss'
==============
</code></pre>
<p>I have defined the loss in the class self.loss why the torch can’t find it?</p>

username: ptrblck
cooked: <p>If you want to implement a custom <code>backward</code> method, you should use <code>autograd.Function</code> and refer to <a href="https://pytorch.org/tutorials/beginner/examples_autograd/two_layer_net_custom_function.html">this example</a>.<br>
What’s the reason you want to override the <code>backward</code>? Autograd should be able to create the computation graph so that you could return the <code>loss</code> in the <code>forward</code> method and call <code>backward</code> on it.</p>
<p>PS: You can post code snippets by wrapping them into three backticks ```. I’ve edited your post, for easier debugging.</p>

username: 111336
cooked: <p>if I delete the backward it will involves many variables.<br>
my purpose is that the graph retain two output, one is produced image ,the other is real ,they come from same graph i have to use retain_graph=True to make sure grad value will not be cleared by system.<br>
How can i do</p>

username: 111336
cooked: <p>I Change them to</p>
<pre><code class="lang-auto">#con_loss=Variable(torch.FloatTensor([]),requires_grad=True)
class ContentLoss(nn.Module):
   def __init__(self,target,weight):
       super(ContentLoss,self).__init__()
       #detach the original computing graph-&gt;weight graph
       self.target=target.detach()*weight
       self.weight=weight
       self.criterion=nn.MSELoss()
   def forward(self,input):
       self.loss=self.criterion(input*self.weight,self.target)#MSE LOSS
       self.output=input
       
       return self.output
   def callback(self):
       return self.loss.backward(retain_graph=True)
       ====
class StyleLoss(nn.Module):
   def __init__(self,target,weight):
       super(StyleLoss,self).__init__()
       self.target=target.detach()*weight
       self.weight=weight
       #self.gram=GramMatrix()
       self.criterion=nn.MSELoss()
   def forward(self,input):
       self.output=input.clone()
       input=input.cuda()
       self_G=Gram(input)
       self_G.mul_(self.weight)
       self.loss=self.criterion(self_G,self.target)
       return self.output
   def callback(self):
       return self.loss.backward(retain_graph=True)
def Gram(input):
   a,b,c,d=input.size()#a=batch_size,b=number of features (c,d)=N=c*d-&gt;dimension of visualization
   features=input.view(a*b,c*d)
   G=torch.mm(features,features.t())
   return G.div(a*b*c*d)

and Run 

input_param=nn.Parameter(input_img.data)
optimizer=optim.LBFGS([input_param])
num_steps=300
for i in range(num_steps):
   input_param.data.clamp_(0,1)
   optimizer.zero_grad()
   model(input_param)
   style_score=0
   content_score=0
   for sl in style_losses:
       style_score+=sl.callback()
   for cl in content_losses:
       content_score+=cl.callback()
   if i%50==0:
       print("num{}epochs".format(i))
       print("StyleLoss{:4f},Content_loss{:4f}".format(style_score.data[0],content_score.data[0]))
   def closure():
       return style_score+content_score
output=input_param.data.clamp_(0,1)
plt.figure()
inshow(output,title="output Image")
plt.ioff()
plt.show()
</code></pre>
<p>USE Callback method instead</p>
<p>the error is ‘StyleLoss’ object has no attribute ‘loss’<br>
it will as same as contentLoss class</p>