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

Hey there, below is part of my code

class ContentLoss(nn.Module):
    def __init__(self,target,weight):
        super(ContentLoss,self).__init__()
        #detach the original computing graph->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->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:
       -------------------------------->>> style_score+=sl.backward()
    for cl in content_losses:
       -------------------------------->>> 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)
<ipython-input-67-2426f976e393> in <module>
      1 for sl in style_losses:
----> 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(
--> 591             type(self).__name__, name))
    592 
    593     def __setattr__(self, name, value):

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

I have defined the loss in the class self.loss why the torch can’t find it?

If you want to implement a custom backward method, you should use autograd.Function and refer to this example.
What’s the reason you want to override the backward? Autograd should be able to create the computation graph so that you could return the loss in the forward method and call backward on it.

PS: You can post code snippets by wrapping them into three backticks ```. I’ve edited your post, for easier debugging.

if I delete the backward it will involves many variables.
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.
How can i do

I Change them to

#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->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->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()

USE Callback method instead

the error is ‘StyleLoss’ object has no attribute ‘loss’
it will as same as contentLoss class