Haochen-Wang409 / U2PL

[CVPR'22] Semi-Supervised Semantic Segmentation Using Unreliable Pseudo-Labels
Apache License 2.0
426 stars 59 forks source link

对比学习的损失 #93

Closed NJNUCS closed 1 year ago

NJNUCS commented 1 year ago

您好,我又来打搅您啦,我想问您一个问题,就是我看您的代码 loss_helper.py下的第220行,求损失函数的时候,为什么使用F.cross_entropy(seg_logits / temp, torch.zeros(num_queries).long().cuda()) 与一个num_queries维度的都是0的张量求交叉熵呀,谢谢,期望您的回答。

Haochen-Wang409 commented 1 year ago

因为正样本的 logits 都摆在了第 0 位,这一点与 MoCo 的实现一致:

image
NJNUCS commented 1 year ago

谢谢您的及时回答,我想想哈

NJNUCS commented 1 year ago

您好,我在我的任务上使用了您的对比损失,发现损失一直都不下降,保持在一个值不变,我思来想去也不知道是怎么回事,您能指点指点嘛 `batch_size, num_channels, h, w = features.size() segmentation = segmentation.long() features = features.detach()

    features = features.permute(0, 2, 3, 1).contiguous() # 变为B * H * W * C
    features = features.view(batch_size * h * w, num_channels) # 变成 K * C
    #self.logger_handle.info('后分割图:%s'%(segmentation))
    clsids = segmentation.unique() #获得该图中的类别

    #self.logger_handle.info("%s"%(clsids))
    contra_loss = torch.tensor(0.0).cuda()
    for clsid in clsids:
        if clsid==ignore_index:continue
        seg_cls = segmentation.view(-1)
        feats_cls = features[seg_cls == clsid]
        feature_negative = features[seg_cls!=clsid] # 负样本的特征 
        features_negative_index = torch.randint(feature_negative.size()[0], size=(self.cfg['negative_pixels']*self.cfg['anchor_pixels'],))
        negative_features = feature_negative[features_negative_index].cuda()  #选择的负样本的特征
        negative_feature = negative_features.reshape(self.cfg['anchor_pixels'],self.cfg['negative_pixels'],num_channels)
        seg_anchor_pixel_index  = torch.randint(feats_cls.size()[0], size=(self.cfg['anchor_pixels'],))
        anchor_pixel = feats_cls[seg_anchor_pixel_index].clone().cuda()  # 存储每个类的锚框像素
        postive_center = memory_module[clsid].mean(0).cuda()
        postive_feature = postive_center.unsqueeze(0).unsqueeze(0).repeat(self.cfg['anchor_pixels'], 1, 1).cuda()  # 尺寸是anchor_pixels * 1 * num_feat

        all_feat = torch.cat((postive_feature, negative_feature), dim=1)
        seg_logits = torch.cosine_similarity(anchor_pixel.unsqueeze(1), all_feat, dim=2)
        contra_loss = contra_loss + F.cross_entropy(seg_logits/self.cfg['temp'],torch.zeros(self.cfg['anchor_pixels']).long().cuda())

    return contra_loss/len(clsids)`
Haochen-Wang409 commented 1 year ago

这与 issue https://github.com/Haochen-Wang409/U2PL/issues/67 类似。 我对此的解释为,contrastive loss 可能更像一个 regularizer,而非真正的 objective。它起的作用是防止着对错误伪标签的过拟合。

NJNUCS commented 1 year ago

我是在全监督领域内使用的对比损失,目的是使BackBone产生的同类特征近,异类特征远,我觉得跟你的是差不多的,我在复现您的论文的时候,对比损失整体趋势在下降,但是使用到我的任务上的时候,它就一直保持在一个数上下波动,有点奇怪,

Haochen-Wang409 commented 1 year ago

可以适当调整一下对比损失的权重?例如 loss = loss_sup + 0.1 * loss_contra

NJNUCS commented 1 year ago

您好,我调到了0.01了,它也是保持不怎么下降,也不上升呢

Haochen-Wang409 commented 1 year ago

这与 issue #67 类似。 我对此的解释为,contrastive loss 可能更像一个 regularizer,而非真正的 objective。它起的作用是防止着对错误伪标签的过拟合。

正如我说的,它更像是一个正则项,而非最小化的目标函数。加入对比学习损失后模型精度是否有提升?