最大坍塌度量学习MCML

文章介绍了基于PyTorch实现的MCML(MaximallyCollapsingMetricLearning)损失函数,作者参考了王微的论文并自编了一个简化版的代码,尽管代码可能较为基础,但在训练中仍取得不错效果。作者提到了可以在特征提取后应用MCML并更新,以可能提升性能。代码中使用了KL散度进行矩阵优化,并处理了对角线元素以避免log0的问题。
摘要由CSDN通过智能技术生成

关于相关理论知识,可以去看看下面这篇论文,

王微. 融合全局和局部信息的度量学习方法研究[D].合肥:中国科学技术大学,2014

关于Maximally Collapsing Metric Learning(简称MCML),我一开始没找的那种实现好的代码,然后我就自己看理论写了一个,当然了我这个实现是一个很low的版本了,希望后期有大佬可以重新写吧,我这个代码应该没啥大问题,如果有问题的话,欢迎大家提出解决办法,一起成长。
MCML转换代码
关于其中的M矩阵,我并没有具体实现,我写一个简单的公式,我想就可以明白了,y = F(x),
利用模型训练巧妙的避开了其中的M参数,但结果还是蛮好的。
我是在最后一层计算MCML的,其实可以考虑在特征提取过后就进行MCML,然后更新,可能效果会更好一点。
我的3060直接放弃了,有能力的小伙伴可以继续尝试。

#版本3,矩阵优化
class MCML_Loss(nn.Module):
    #第二种实现,F(x) 维度 (bs,512)
    def __init__(self):
        super(MCML_Loss, self).__init__()
        self.KL = nn.KLDivLoss(reduction="batchmean")  #KL散度
    def forward(self, x, labels):
#         one = time.time()
        label = labels.cpu()
        bs = x.shape[0]
        P  = torch.ones([bs, bs]).cuda()   #根据真实标签计算条件概率
        D = torch.cdist(x, x, p=2)
        Q_E = (-D).exp()
        Q_E = Q_E - torch.diag_embed(torch.diag(Q_E))  #设置i=j的元素都为0,不用担心log0的存在 KL散度y(logy-logy')  其中y=y'=0 
        fm_sum = torch.sum(Q_E,dim=1)  #构建条件概率分母   每一行运算出的结果 张量形状(bs)
        fm_sum = torch.reshape(fm_sum,(-1,1))
        Q = torch.div(Q_E, fm_sum)
        number = 0
        for i in label:
            indexs = np.argwhere(label==i)
            for j in indexs:
                P[number][j] = 0
            number +=1
        # input should be a distribution in the log space
        q = F.log_softmax(Q)
        # Sample a batch of distributions. Usually this would come from the dataset
        p = F.softmax(P)
        loss = self.KL(q, p)
        return loss
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值