度量学习(Metric learning、损失函数、triplet、三元组损失、fastreid)

article/2025/11/10 21:34:06
定义
    Metric learning 是学习一个度量相似度的距离函数:相似的目标离得近,不相似的离得远. 
    一般来说,DML包含三个部分, 如下图.。
    1)特征提取网络:map embedding
    2)采样策略:将一个mini-batch里的样本组合成很多个sub-set
    3)loss function:在每个sub-set上计算loss.
    

 

应用场景
通常是在个体级别的细粒度识别上使用,传统的分类是花鸟狗的大类别的识别,但是有些需求是要精确到个体级别,比如精确到哪个人的人脸识别,还有一种场景是训练和部署的类别不同,比如训练只有100个人,部署需要分辨200人,所以triplet loss的最主要应用也就是:人脸识别、人脸验证、图像检索、签名验证、行人重识别等。
为什么不用分类:
1)这类场景用分类往往最后会造成softmax的维数远大于feature的维数,想想resnet50 global ap出来- -个2048的feature对应到一 -个几万,几十万的分类softmax就可怕。
2)triplet loss通常能比classification得到更好的feature(这个需要实验,因为网上有人的场景比分类高10个点,拍照购陈越测试分类更好)
3)triplet loss可以卡阈值, triplet losi训练的时候要设置- 个margin, 这个margin可以控制正负样本的距离,当feature 进行normalization之后,可以更加方便的卡个阈值来判断是不是同一个ID。(这个同样存疑,因为加了margin的分类,也可以卡阈值)。
度量学习缺点:依赖采样的策略,如果采样策略过简单,只会学习到简单的样本,无法继续训练;如果采样过难,会导致收敛慢、不收敛,甚至过拟合。(2015年度量学习的思路已经具备,主要还是看采样即困难样本的挖掘)
一、特征提取网络
    参考各类分类等的主干网络
二、损失函数
    主要讲两个大类:对比损失(contrastive loss)和三元组损失(triplet loss),其中项目中用的多的还是三元组损失,所以重点理解和掌握三元组其余建议了解即可。
    注意:
1)这两种loss函数如果单独使用则会遭遇收敛速度慢的问题(三元组的选取导致数据的分布并不一定均匀,所以在模型训练过程表现很不稳定,而且收敛慢,需要根据结果不断调节参数,而且Triplet loss比分类损失更容易过拟合。)。
2)样本空间的量级( 𝑂 ( 𝑁 2 ) O(N^2) O ( N 2 ) 或者 𝑂 ( 𝑁 3 )O(N^3) O( N3 ))非常大,在学习过程的后期,大多数样本都能满足损失函数的约束条件,这些样本对应进一步学习的贡献很小。因此,这两种损失函数都需要配合hard sample mining的学习策略一起使用。
3)大多数情况下,我们会把这种方法放在模型的预训练过程中,或者和softmax函数(分类损失)结合在一起使用。
对比损失
    1、思想为:
    正样本对尽可能的近,负样本对尽可能的远,这样可以增大类间差异,减小类内差异。具体为 ,取一样本对,如果:
    1) 是正样本对,则其产生的loss就应该等于其特征之间的距离 (例如L2 loss);因为我们的期望是他们之间的距离为0,所以凡是大于零的loss都需要被保留。
     2) 如果是负样本对,他们之间的距离应该尽可能的大,至于应该大到多少则由我们人为的设定,假设设定的阈值为 m ,如果距离大于 m,其loss为0,不需要对模型进行更新了,如果小于 m,则认为模型还不够好,需要继续训练。
 
    2、缺点:
    需要指定一个固定的margin,即公式中的 m ,因为 m  是固定的,所以这里就隐含了一个很强的假设,即每个类目的样本分布都是相同的,不过一般情况下这个强假设未必成立。
    例如,有一个数据集有三种动物,分别是狗、狼 、猫,直观上狗和狼比较像,狗和猫的差异比较大,所以狗狼之间的margin应该小于狗猫之间的margin,但是Contrastive loss使用的是固定的margin,如果margin设定的比较大,模型可能无法很好的区分狗和狼,而margin设定的比较小的话,可能又无法很好的区分狗和猫。
三元组损失
    1、思想为:
    让负样本对之间的距离大于正样本对之间的距离。
Triplet-Loss的效果比Contrastive Loss的效果要好,因为他考虑了正负样本与锚点的距离关系。
    当负样本对之间的距离比正样本对之间的距离大m的时候,loss为0 ,认为当前模型已经学的不错了,所以不对模型进行更新。
    公式如下:
    

    2、margin选择
    对于阈值margin的设置需要注意选择合适大小的值,理论上来说,较大的margin能够增强模型对不同类样本的区分度,但是如果在训练初期就将margin设置得比较大,则可能会增加模型训练的难度,进而出现网络不收敛的情况。在模型训练初期先使用一个较小的值对网络进行初始化训练,之后再根据测试的结果对margin的值进行适当的增大或缩小,这样可以在保证网络收敛的同时让模型也能拥有一个较好的性能。
    3、困难样本挖掘
    

    如上图, 理论上讲,使用hard triplets训练模型最好,因为这样模型能够有很好的学习能力,但由于margin的存在,这类样本可能模型没法很好的拟合,训练比较困难;其次是使用semi-hard triplet,这类样本是实际使用中最优选择,因为这类样本损失不为0,而且损失不大,模型既可以学习到样本之间的差异,又较容易收敛;至于easy triplet,损失为0,不用拿来训练。
   针对不同的业务,其实构造的原则也不一样,比如人脸识别场景,选择semi-hard triplets样本,这样一来,损失函数的公式不容易满足,也就意味着损失值不够低,模型必须认真训练和更新自己的参数,从而努力让d(a,n)的值尽可能变大,同时让 d(a,p) 的值尽可能变小。
    1)离线挖掘
    训练集所有数据经过计算得到对应的embedding,根据embedding计算得到(a,p)和(a,n)之间的距离,根据这个距离判断三元组属于semi-hard triplets,hard triplets还是easy triplets中的哪一类。Offline triplet mining 仅仅用于选择hard或者semi-hard的三元组类型,因为easy triplet太容易了,没有必要训练。总得来说,这个方法效率不高。
  

    1)离线挖掘

    训练集所有数据经过计算得到对应的embedding,根据embedding计算得到(a,p)和(a,n)之间的距离,根据这个距离判断三元组属于semi-hard triplets,hard triplets还是easy triplets中的哪一类。Offline triplet mining 仅仅用于选择hard或者semi-hard的三元组类型,因为easy triplet太容易了,没有必要训练。总得来说,这个方法效率不高。

    2)在线挖掘(不要慌,使用pytorch实现均仅仅需要几行代码便可实现)

    为每一batch动态挖掘有用的三元组,即只计算batch中的triplets。假设一个batch的数据有P个人,每人K张图片,则共包含P*K张人脸。针对valid triplet的挑选(即构成A-P-N对),有如下两种策略:

    Batch all:计算所有的valid triplet,对hard 和 semi-hard triplets上的loss进行平均(easy triplets不参与计算,平均会导致loss很小),可以得到PK(K-1)(PK-K)个三元组。

    Batch hard: 对于每一个锚点,选择距离最大的正样本(a,p)和距离最小的负样本(a,n),可以得到PK个三元组。

    加权:对于每一个锚点,通过样本到anchor的最大距离加权计算所有样本到anchor的距离的加权和(正负样本同理),可以得到PK个三元组(逻辑上其实并不再是真实存在的三元组,为加权均值,包含easy,semi-hard 和hard)。

    再详细理解可以参考:https://zhuanlan.zhihu.com/p/266916361

    Fastreid(截止20210730)实现了batch hard 和加权的功能,,可以参考对应的实现:https://github.com/JDAI-CV/fast-reid/blob/master/fastreid/modeling/losses/triplet_loss.py

Triplet center loss
        triplet样本的选取至关重要,如果选取的triplet对没啥难度,模型不更新;而如果使用hard mining的方法对难例进行挖掘,又会导致模型对噪声极为敏感。
        Triplet Center loss的思想非常简单,原来的Triplet是计算anchor到正负样本之间的距离,现在Triplet Center是计算anchor到正负样本所在类别的中心的距离。类别中心就是该类别所有样本embedding向量的中心。
N-pair loss
       

    triplet loss同时拉近一对正样本和一对负样本,这就导致在选取样本对的时候,当前样本对只能够关注一对负样本对,而缺失了对其他类别样本的区分能力。

    为了改善这种情况,N-pair loss就选取了多个负样本对,即一对正样本对,选取其他所有不同类别的样本作为负样本与其组合得到负样本对。如果数据集中有 N个类别,则每个正样本对 yii都对应了N-1个负样本对。

 

Quadruplet loss
        Quadruplet loss由两部分组成:
        1)正常的triplet loss,这部分loss能够让模型区分出正样本对和负样本对之间的相对距离。
2)正样本对和其他任意负样本对之前的相对距离。这一部分约束可以理解成最小的类间距离都要大于类内距离,不管这些样本对是否有同样的anchor。即不仅要要求 A1A2<A1B1 ,还需要A1A2<B1C1       

Lifted Structure Loss
        思想是对于一对正样本对而言,不去区分这个样本对中谁是anchor,谁是positive,而是让这个正样本对中的每个样本与其他所有负样本的距离都大于给定的阈值。此方法能够充分的利用mini-batch中的所有样本,挖掘出所有的样本对。

三、采样策略
        最自然的就是按loss里面的项每一对样本都算距离,那么就是N*N对。
        其他的策略详见上面对应的损失函数。
参考链接:
1、 https://zhuanlan.zhihu.com/p/68200241
2、 https://zhuanlan.zhihu.com/p/72516633
3、 https://www.cnblogs.com/luckforefforts/p/13642695.html
4、 https://blog.csdn.net/zenglaoshi/article/details/106928204
5、 https://bindog.github.io/blog/2019/10/23/why-triplet-loss-works/
6、 https://flashgene.com/archives/151266.html
7、 https://blog.csdn.net/zenglaoshi/article/details/106928204
8、 https://zhuanlan.zhihu.com/p/266916361

http://chatgpt.dhexx.cn/article/BiitrmMw.shtml

相关文章

度量学习Metric Learning

度量学习 (Metric Learning) 距离度量学习 (Distance Metric Learning&#xff0c;DML) 相似度学习 度量学习 是指 距离度量学习&#xff0c;Distance Metric Learning&#xff0c;简称为 DML&#xff0c;是人脸识别中常用传统机器学习方法&#xff0c;由Eric Xing在NIPS 2…

度量学习(Metric Learning)基础概念

一、什么是度量学习&#xff1f; 度量学习 (Metric Learning) 距离度量学习 (Distance Metric Learning&#xff0c;DML) 相似度学习。 在数学中&#xff0c;一个度量&#xff08;或距离函数&#xff09;是一个定义集合中元素之间距离的函数。一个具有度量的集合被称为度量空…

度量学习——总结

传统方法 User guide: contents — metric-learn 0.6.2 documentation 深度学习 基于深度学习的度量学习方法大都由两个部分组成&#xff1a;特征提取模块和距离度量模块。距离度量模块的任务是使同一类样本间的距离更靠近&#xff0c;而不同类样本间的距离更远离。这一模块…

ffmpeg命令分析-r

本系列 以 ffmpeg4.2 源码为准&#xff0c;下载地址&#xff1a;链接&#xff1a;百度网盘 提取码&#xff1a;g3k8 之前的文章分析 FFMpeg 工程的 do_video_out() 函数的时候&#xff0c;建议不关注 delta0&#xff0c;delta&#xff0c;nb0_frames&#xff0c;nb_frames 等变…

使用FFmpeg命令处理音视频

文章目录 前言一、ffprobe相关命令1.使用ffprobe查看音频文件的信息2.使用ffprobe查看视频文件的信息 二、ffplay相关命令1.基本的ffplay命令2.音视频同步命令 三、ffmpeg相关命令1.ffmpeg通用参数2.ffmpeg视频参数3.ffmpeg音频参数4.ffmpeg示例 总结 前言 FFmpeg是一套可以用…

ffmpeg-命令行详解

前言 ffmpeg是一个多媒体开发库&#xff0c;提供了关于音频和视频的工具。这个项目的官网是这里。 下载地址 ffmpeg提供了方便地控制台命令&#xff0c;可以在下载页面下载。三个平台&#xff08;windows&#xff0c;linux&#xff0c;macos&#xff09;都有打包好的可执行文…

ffmpeg命令分析-b:v

本系列 以 ffmpeg4.2 源码为准&#xff0c;下载地址&#xff1a;链接&#xff1a;百度网盘 提取码&#xff1a;g3k8 本系列主要分析各种 ffmpeg 命令参数 在代码里是如何实现的。a.mp4下载链接&#xff1a;百度网盘&#xff0c;提取码&#xff1a;nl0s 。 命令如下&#xff1a;…

FFmpeg命令详解

命令格式 功能 FFmpeg命令是在ffmpeg.exe可执行文件环境下执行&#xff0c;ffmpeg.exe用于音视频的转码&#xff0c;加水印&#xff0c;去水印&#xff0c;视频剪切&#xff0c;提取音频&#xff0c;提取视频&#xff0c;码率控制等等功能。 最简单的命令 ffmpeg -i input.a…

FFmpeg命令行转码

本文主要了解FFmpeg进行音视频编码转换。主要学习如下几个知识点&#xff1a; FFmpeg使用libx264进行H,264(AVC)软编码&#xff0c;使用libx265进行H.265(HEVC)软编码使用FFmpeg在MacOS环境下硬编码了解音频编码&#xff0c;MP3&#xff0c;AAC的参数设置编码 FFmpeg软编码H.…

ffmpeg命令行使用

查看视频信息 ffmpeg -i 视频名字视频名字这里输入前几个字符按 tab 键可以自动补全 返回结果&#xff1a; 红框之内的内容没什么用 编码器 &#xff1a;encoder : Lavf57.25.100 持续时间&#xff1a;Duration: 00:14:20.58, start: 0.000000, bitrate: 381 kb/s Duratio…

ffmpeg录屏命令

1.gdigrab抓屏 ffmpeg -f gdigrab -i desktop -q:v 0.01 -vcodec mpeg4 -f mp4 out.mp4-i 输入设备 -vcodec 视频编码格式 -f 视频封装格式 缺点只能录制视频&#xff0c;不能录制音频 2.dshow 下载安装screen capture recorder https://sourceforge.net/projects/screencap…

FFMPEG常用命令行

目录 命令格式&#xff1a; 1.获取视频信息 2.转视频/音频格式 视频格式转换 音频格式转换 3.音视频分离 4.图像处理 5.视频旋转 6.视频倒放&视频加速&视频减速 7.视频合并&#xff08;两个10秒的视频合并为20秒&#xff09;&#xff1a; 8.视频拼接&…

FFmpeg命令介绍

FFmpeg 简介轶闻常用命令视频相关音频相关录制命令 简介 FFmpeg是一套可以用来记录、转换数字音频、视频&#xff0c;并能将其转化为流的开源计算机程序。使用C语言进行开发&#xff0c;采用LGPL或GPL许可证&#xff0c;可前往Github下载其源码。它提供了录制、转换以及流化音…

ffmpeg命令大全

ffmpeg命令大全 FFMPEG 目录及作用FFMPEG基本概念FFMPEG 命令基本信息查询命令主要参数视频参数音频参数录制录屏 分解与复用滤镜简单滤镜复杂滤镜 直播相关 前言 FFMPEG是特别强大的专门用于处理音视频的开源库。你既可以使用它的API对音视频进行处理&#xff0c;也可以使用它…

音视频ffmpeg——ffmpeg 命令大全

ffmpeg 命令参数 ffmpeg信息查询命令 ffmpeg 控制命令 主要参数&#xff1a; ◼ -i 设定输入流 ◼ -f 设定输出格式(format) ◼ -ss 开始时间 ◼ -t 时间长度 音频参数&#xff1a; ◼ -aframes 设置要输出的音频帧数 ◼ -b:a 音频码率 ◼ -ar 设定采样率 ◼ -ac 设定…

常见FFmpeg命令行全面分析

FFmpeg多媒体库支持的命令行调用分为三个模块&#xff1a;ffmpeg、ffprobe、ffplay。其中ffmpeg命令行常用于音视频剪切、转码、滤镜、拼接、混音、截图等&#xff1b;ffprobe用于检测多媒体流格式&#xff1b;ffplay用于播放视频。详情可查阅FFmpeg官方文档&#xff1a;ffmpeg…

ffmpeg 常用命令汇总

​​​​​​经常用到ffmpeg做一些视频数据的处理转换等&#xff0c;用来做测试&#xff0c;今天总结了一下&#xff0c;参考了网上部分朋友的经验&#xff0c;一起在这里汇总了一下。 1、ffmpeg使用语法 命令格式&#xff1a; ffmpeg -i [输入文件名] [参数选项] -f [格…

FFmpeg常用基本命令行

本文收集记录了笔者使用过的FFmpeg命令&#xff0c;亲测可用&#xff0c;并不是简单的copy别人的FFmpeg大全&#xff0c;下面的命令大部分都是本人测试成功过的&#xff0c;大家可以放心使用。 音视频技术是程序员日常生活中经常用到的&#xff0c;比如转码需求&#xff0c;同事…

Eclipse启动Tomcat逐渐变慢

现象 1、Eclipse用着用着发现启动Tomcat特别慢 原因 断点打多了&#xff0c;之前调试的断点没有取消&#xff0c;导致启动时加载断点&#xff0c;拖慢启动 解决方案 1、点击debug按钮 2、选择breakpoint选项 清空所有断点 3、重新启动

eclipse 解决启动慢、运行慢的方法总结(最全)

由于 CSDN 的目录只在固定地方显示&#xff0c;并不是很方便阅读&#xff0c;又占空间&#xff0c;所以本文章已同步更新到个人博客上&#xff0c;在个人博客上的文章&#xff0c;有滑动侧边目录栏&#xff0c;阅读体验更加&#xff0c;而且文章的样式也更为丰富&#xff0c;推…