Pytorch中的自定义损失,其中对象没有向后属性()

时间:2018-07-25 14:24:59

标签: pytorch

我是pytorch的新手,我尝试创建自己的自定义损失。这确实具有挑战性。以下是我所遭受的损失。

class CustomLoss(nn.Module):

    def __init__(self,  size_average=True, reduce=True):
        """

        Args:
            size_average (bool, optional): By default, the losses are averaged
               over observations for each minibatch. However, if the field
               size_average is set to ``False``, the losses are instead summed for
               each minibatch. Only applies when reduce is ``True``. Default: ``True``
            reduce (bool, optional): By default, the losses are averaged
               over observations for each minibatch, or summed, depending on
               size_average. When reduce is ``False``, returns a loss per input/target
               element instead and ignores size_average. Default: ``True``
        """
        super(CustomLoss, self).__init__()      


    def forward(self, S, N, M, type='softmax',):

        return self.loss_cal(S, N, M, type)



    ### new loss cal
    def loss_cal(self, S, N, M, type="softmax",):
        """ calculate loss with similarity matrix(S) eq.(6) (7)
        :type: "softmax" or "contrast"
        :return: loss
        """

        self.A = torch.cat([S[i * M:(i + 1) * M, i:(i + 1)]
                               for i in range(N)], dim=0)        
        self.A = torch.autograd.Variable(self.A)        


        if type == "softmax":
            self.B = torch.log(torch.sum(torch.exp(S.float()), dim=1, keepdim=True) + 1e-8)
            self.B = torch.autograd.Variable(self.B)       
            total = torch.abs(torch.sum(self.A - self.B))        
        else:
            raise AssertionError("loss type should be softmax or contrast !")
        return total

当我运行以下命令时:

loss = CustomLoss()          
(loss.loss_cal(S=S,N=N,M=M))
loss.backward()

我收到以下错误:

C:\Program Files\Anaconda3\lib\site-packages\IPython\core\interactiveshell.py in run_cell_magic(self, magic_name, line, cell)
   2113             magic_arg_s = self.var_expand(line, stack_depth)
   2114             with self.builtin_trap:
-> 2115                 result = fn(magic_arg_s, cell)
   2116             return result
   2117 

<decorator-gen-60> in time(self, line, cell, local_ns)

C:\Program Files\Anaconda3\lib\site-packages\IPython\core\magic.py in <lambda>(f, *a, **k)
    186     # but it's overkill for just that one bit of state.
    187     def magic_deco(arg):
--> 188         call = lambda f, *a, **k: f(*a, **k)
    189 
    190         if callable(arg):

C:\Program Files\Anaconda3\lib\site-packages\IPython\core\magics\execution.py in time(self, line, cell, local_ns)
   1178         else:
   1179             st = clock2()
-> 1180             exec(code, glob, local_ns)
   1181             end = clock2()
   1182             out = None

<timed exec> in <module>()

C:\Program Files\Anaconda3\lib\site-packages\torch\nn\modules\module.py in __getattr__(self, name)
    530                 return modules[name]
    531         raise AttributeError("'{}' object has no attribute '{}'".format(
--> 532             type(self).__name__, name))
    533 
    534     def __setattr__(self, name, value):

AttributeError: 'CustomLoss' object has no attribute 'backward'

为什么会出现此错误?我没有面对TF的这个错误。我的理解是,这与autograd有关系吗?如果有人可以解释为什么我会遇到此错误,那么我可以找出其余的原因。

1 个答案:

答案 0 :(得分:1)

嗨!

问题是您尝试在模块上调用向后函数,而不是在变量上调用(可能您想)。由于您尚未在模块上实现向后功能,因此解释器无法找到一个。因此,您要做的是:

loss_func = CustomLoss()          
loss = loss_func.loss_cal(S=S,N=N,M=M)
loss.backward()

作为一般说明: 您正在使用nn.Module而不实际具有参数。虽然可行,但这不是nn.Module的用途-因此应避免使用。相反,只需创建一个纯函数-毕竟,您拥有的函数始终是静态的。如果您确实想参加该课程,请考虑要创建的课程类型-loss。但是,损失可能具有特殊的pytorch属性。因此,您应该阅读here的讨论。