小工具知识网

当前位置: 首页 > 行业知识 > 【center-loss 中心损失函数】 原理及程序解释(更新中)

行业知识

【center-loss 中心损失函数】 原理及程序解释(更新中)

2026-10-29 05:01:43 来源:互联网转载

文章目录

  • 前言
  • 问题引出
    • open-set问题
    • 抛出
    • 解决方法
      • softmax函数、softmax-loss函数
      • 解决
      • 代码(center_loss.py)
        • 原理
        • 程序解释
        • 代码运用
        • 如何梯度更新
          • 首先了解一下基本的梯度下降算法
          • 然后
          • 补充:外围知识
            • ���型

              前言

              学习一下: 中心损失函数,用于用于深度人脸识别的特征判别方法

              论文:https://ydwen.github.io/papers/WenECCV16.pdf

              github代码:https://github.com/KaiyangZhou/pytorch-center-loss

              参考:史上最全MNIST系列(三)——Centerloss在MNIST上的Pytorch实现(可视化)


              问题引出

              open-set问题

              open-set 问题是一种模式识别中的问题,它指的是当训练集和测试集的类别不完全相同的情况。例如,如果训练集只包含 0 到 9 的数字,而测试集包含了 A 到 Z 的字母,那么就是一个 open-set 问题。这种情况下,分类器不仅要正确识别已知的类别,还要能够拒绝未知的类别,即将它们标记为 unknown 或 outlier。(后来我想这就是一个聚类问题)

              open-set 问题与 closed-set 问题相对应,closed-set 问题是指训练集和测试集的类别完全相同的情况。例如,如果训练集和测试集都只包含 0 到 9 的数字,那么就是一个 closed-set 问题。这种情况下,分类器只需要正确识别已知的类别即可。

              抛出

              当我们要预测的人脸不在训练集中出现过时,我们需要让它不识别出,而不要因为与训练过的人脸相像而误判。

              对于常见的图像分类问题,我们常常用softmax loss来求损失。以MNIST数据集为例,如果你的损失采用softmax loss,那么最后各个类别学出来的特征分布大概如下图:(在倒数第二层全连接层输出了一个2维的特征向量)

              左图为训练集,右图为测试集,发现结果分类还算不错,但是每一类的界限太过模糊,若从中再加一列,则有可能出现误判。

              解决方法

              softmax函数、softmax-loss函数

              已知softmax的函数为:

              在深度学习的分类问题上,意为对应类的概率(符合每个类的概率相加和为1且0 [[0],[4],[2]] labels = labels.unsqueeze(1).expand(batch_size, self.num_classes)# .unsqueeze(1)表示在第1维增加一个维度 .expand()表示扩展维度 mask = labels.eq(classes.expand(batch_size, self.num_classes)) #eq是比较两个tensor是否相等,相等返回1,不相等返回0 # *表示对应元素相乘 dist = distmat * mask.float() # mask.float()将mask转换为float类型 loss = dist.clamp(min=1e-12, max=1e+12).sum() / batch_size # clamp表示将dist中的元素限制在1e-12和1e+12之间 return loss

              代码运用

              import torchimport torch.nn as nnfrom center_loss import CenterLosscriterion_cent =CenterLoss(10, 2,False) #10个类别,2维torch.manual_seed(0) #设置随机种子x = torch.randn(10, 2) # (32, 2) #32个样本,每个样本2维labels = torch.randint(0, 10, (10,)) # (32,) #32个样本,每个样本一个标签print(x)print(labels)print(criterion_cent(x, labels))

              结果:

              tensor([[-1.1258, -1.1524],        [-0.2506, -0.4339],        [ 0.5988, -1.5551],        [-0.3414,  1.8530],        [ 0.4681, -0.1577],        [ 1.4437,  0.2660],        [ 1.3894,  1.5863],        [ 0.9463, -0.8437],        [ 0.9318,  1.2590],        [ 2.0050,  0.0537]])tensor([2, 9, 1, 8, 8, 3, 6, 9, 1, 7])tensor(2.9281, grad_fn=)

              如何梯度更新

              首先了解一下基本的梯度下降算法

              【点云、图像】学习中 常见的数学知识及其中的关系与python实战

              里的小标题:基于迭代的梯度下降算法,了解到超参数(人为设定的参数):

              学习率,w,b等。此算法为拟合出一条线。

              伪代码:

              1、未达到设定迭代次数

              2、迭代次数epoch+1

              3、计算损失值

              4、计算梯度

              5、更新w、b

              6、达到迭代次数,结束

              然后

              看下这里的更新方法

              其中,卷积层中初始化的参数 θc,超参数 :λ、α 和学习率 μ ,迭代次数 t 。(λ、α、 μ均可调)

              伪代码:

              1、当未收敛时:

              2、迭代次数t+1

              3、计算损失函数 L=Ls+Lc

              4、计算反向传播误差(即梯度)

              5、更新w

              6、更新cj

              7、更新θc

              8、结束

              其中

              其中,如果满足条件,则 δ(条件) = 1,如果不满足,则 δ(条件) = 0。

              首先:第一个公式不用多说,为中心损失函数对特征xi求偏导,即求梯度。

              其次:第二个公式:加入了判断,当条件满足时(即yi=j,即就是在同一类时)Δcj=cj-xi 的小批量的所有和/m+1。相当于累加了误差求平均,以此来作为梯度。

              当条件不满足时,即Δcj =0,此时这个分母的+1的作用就体现出来了,分母不能为0嘛。

              补充:

              第5步后面一个等号成立是因为Lc中没有W项,所以Lc对W的求导为0

              第7步也是一样,求梯度,只是写成了求导的链式法则。

              补充:外围知识

              模型

上一篇:方维直播安装全攻略,轻松上手,即刻开播!

下一篇:闪送外卖下载指南,轻松掌握外卖下单技巧,快速享受美食!