我最近一直在从事有监督的对比学习。在使用triplet loss进行图像分类的几次实验之后,我决定实现一个新功能,以增加此三重态损失的额外损失。此函数使用变异系数(stddev / mean),我的想法是基于本文的:
Learning 3D Keypoint Descriptors for Non-Rigid Shape Matching
他们的GitHub存储库是here,但我认为它的文档记录不是很好。
去年我一直在研究Pytorch,但仍然很难完全理解如何正确创建损失函数。这是我写的损失函数:
class CoefficientVariationLoss(nn.Module):
def __init__(self, class_to_idx, weighted=False):
super(CoefficientVariationLoss, self).__init__()
self.class_to_idx = class_to_idx
self.weighted = weighted
def forward(self, x, labels):
total_coeff_variation = 0
l2_norm_positive = F.pairwise_distance(x[0], x[1],2)
for c in self.class_to_idx.values():
count_label_pos = torch.sum(labels[0]==c).float()
if count_label_pos <= 1:
class_cv = 0
else:
class_pos = l2_norm_positive[labels[0]==c]
if self.weighted:
weight = count_label_pos/labels[0].shape[0]
class_cv = (torch.std(class_pos)/torch.mean(class_pos))*weight
else:
class_cv = (torch.std(class_pos)/torch.mean(class_pos))
# if torch.isnan(class_cv):
# class_cv = 0
total_coeff_variation += class_cv
return total_coeff_variation
此功能的两个输入是:
我的自定义数据加载器正在将数据作为字典提供:
sample = {'images': [...], 'labels': [...]}
和我的模型(三重态网络)的输出是张量的列表,其顺序相同:锚,正和负。
最终损失最终计算为
loss = loss_triplet + FACTOR * loss_coeffVariation
我是否正确地造成了这种损失?由于差异性问题,我不知道是否可以在损失函数中使用索引...
谢谢!