I am trying to code a loss function for instance segmentation problem given in this paper - Associative Embedding 2 . While iterating over the training examples, the loss function works fine and calling .backward() on the works fine for the first example. But for second example, it gives an error
"RuntimeError: there are no graph nodes that require computing gradients"
I debugged the code a bit more and it turns out, for the first iteration on data, loss that I return is a pytorch Variable but for second iteration, it is a float. I do not understand why this is happening. What am I missing?
Here’s the loss function:
class AssociativeEmbeddingLoss(torch.nn.Module):
    def __init__(self, sigma=0.1, num_points=20):
        super(AssociativeEmbeddingLoss, self).__init__()
        self.sigma = sigma
        self.numPoints = num_points

    def forward(self, prediction, ground_truth_map, ground_truth_class):
        probability_map = prediction[0, 0, :, :]
        sigmoid_map = torch.nn.functional.sigmoid(probability_map)
        filtered_tags = sigmoid_map * prediction[0, 1, :, :]
        prediction_loss = self.pred_loss(filtered_tags, ground_truth_map, ground_truth_class)

        tag_loss = self.tag_loss(filtered_tags, ground_truth_map, ground_truth_class)

        return prediction_loss + tag_loss

    def pred_loss(self, filtered_tags, ground_truth_map, ground_truth_class):
        loss = 0.0
        for each_instance, instance_class in enumerate(ground_truth_class):
            if instance_class == 15: #index of person
                point_list = torch.nonzero(ground_truth_map == each_instance)
                random.shuffle(point_list)
                point_list = point_list[:self.numPoints]
                for point1 in point_list:
                    for point2 in point_list:
                        w1, h1 = point1
                        w2, h2 = point2
                        loss += ((filtered_tags[w1, h1] - filtered_tags[w2, h2]) ** 2)
        return loss / self.numPoints



    def tag_loss(self, filtered_tags, ground_truth_map, ground_truth_class):
        loss = 0.0
        for each_instance1, instance_class1 in enumerate(ground_truth_class):
            for each_instance2, instance_class2 in enumerate(ground_truth_class):
                if instance_class1 == instance_class1 == 15 and each_instance1 != each_instance2:
                    point_list = torch.nonzero((ground_truth_map == each_instance1))
                    random.shuffle(point_list)
                    point_list1 = point_list2 = point_list[:self.numPoints]
                    for point1 in point_list1:
                        for point2 in point_list2:
                            w1, h1 = point1
                            w2, h2 = point2
                            loss += torch.exp(-0.5 * (1/(self.sigma)**2) * ((filtered_tags[w1, h1] - filtered_tags[w2, h2]) ** 2))
        return loss / (self.numPoints ** 2)