想象这样一个夜晚:你第一次来到陌生城市的夜市,朋友发来消息说“我在夜市里等你”,可你只见过他一次——也许是在昏暗灯光下的一瞥。夜市里有几百个摊位、上千个人,你要在人群中找出只见过一面的朋友。你没办法“提前学会”朋友的全部长相,只能在脑海中留下一幕印象,然后观察每个路人:“像不像?像不像?”——这种只靠一个例子,就要从万千候选人里锁定目标的问题,就是小样本学习处理的核心困境。而“用尺子量一量,谁离我心中的印象最近”这类解法,就是本文的主角:度量学习方法。 度量学习方法的核心直觉是:与其死记硬背每一种物体的模样,不如掌握一把“好用的尺子”。只要尺子量得准,任何新出现的东西都能与旧印象比一比,距离最近的,就是答案。夜市里,你要做的不是记下朋友鞋子的颜色,而是修炼出判断“眉眼相似度”的眼力。在现代AI技术中,这把尺子被安放在一个由海量数据训练出来的“比对空间”里:同类物品被无形地推近,不同类被拉远。新面孔出现时,落在谁的附近,就属于谁。

岗位关联

掌握度量学习方法,等于学会了小样本场景下最实用的“相似度分类”工具箱。无论做人脸认证、少样本图像分类,还是冷启动推荐,这套思路都能帮你快速搭建可用的系统,是AI工程师与算法研究员的必备一课。

目录
  1. 可视化演示
  2. 度量学习总览
  3. 距离度量基础
  4. 孪生网络家族
  5. 原型网络
  6. 匹配网络
  7. 关系网络
  8. 优化与技巧
  9. 应用与挑战
  10. AI 应用场景
  11. Python 演示
  12. 常见误区
  13. 面试题

可视化演示

展示系统处理流水线、实时性能指标曲线及多方案对比分析,包含数据流转、吞吐延迟监控与方案评估。

本节配有交互动效(进入视口后自动加载,约 3KB)。

系统可视化 处理流程:输入→处理→模型→输出 性能监控:实时指标 P=L×T

度量学习总览

夜市里找人时,你不可能把朋友照片的每一个像素都背下来,但你可以学一套“比较的方法”:先记住朋友的大致轮廓,然后挨个问路人“你们俩像不像”。度量学习就是把这套“比较的方法”变成一门系统的学问。它不直接回答“这人是谁”,而是回答“这个人和已知的谁最像”。

在机器学习中,让计算机判断“像不像”,需要一个可计算的函数——距离或相似度。常见的做法是用神经网络把原始图片、文字映射到一个向量空间中,再在这个空间里计算欧氏距离或余弦相似度,作为“像不像”的依据。这个“映射+度量”的组合,就是度量学习的基本盘。

度量学习之所以在小样本学习中占据如此核心的位置,是因为它绕开了“学分类边界”的思路。小样本问题的标准设定是:支持集里每个类只有K个带标签样本(K通常为1或5),查询集则需要在依赖这些稀有样本的条件下完成分类。传统深度模型参数量大、需要大量标注样本,在这里会严重过拟合。度量学习改为“学习一个好的特征空间”,让同类靠近、异类远离。孪生网络、原型网络、匹配网络、关系网络,正是四个最具代表性的范式。

所以度量学习的本质,不是“记住朋友长什么样”,而是“学会如何科学地比对”。只要比对方式足够好,哪怕只有一张照片,也能在万千人流中锁定目标。

S={(xi,yi)}i=1N×K,Q={(xj,yj)}j=1N×M\mathcal{S} = \{(\mathbf{x}_i, y_i)\}_{i=1}^{N \times K},\quad \mathcal{Q} = \{(\mathbf{x}_j, y_j)\}_{j=1}^{N \times M}
支持集 S 包含 N 个类别、每类 K 个样本;查询集 Q 包含 N 类、每类 M 个待分类样本。度量学习的目标是借助 S 中的少量样例,正确预测 Q 中样本的类别。
  1. 支持集S 是“已有的印象集合”,共 N 类 × K 个样本,K 通常为 1 或 5,就像朋友给你的那张唯一照片。
    S={(xi,yi)}i=1N×K\mathcal{S} = \{(\mathbf{x}_i, y_i)\}_{i=1}^{N \times K}
  2. 查询集Q 是“待辨认的路人集合”,共 N 类 × M 个样本,每个样本都需要借助支持集来判断归属。
    Q={(xj,yj)}j=1N×M\mathcal{Q} = \{(\mathbf{x}_j, y_j)\}_{j=1}^{N \times M}
  3. 度量学习的任务利用 S 训练出的度量函数去预测 Q 中每个样本的类别 y_j——“用照片去比对每一个路人”。
    学习度量 d(⋅,⋅),使得 d(xj,同类样本)<d(xj,异类样本)\text{学习度量 } d(\cdot,\cdot) \text{,使得 } d(\mathbf{x}_j, \text{同类样本}) < d(\mathbf{x}_j, \text{异类样本})

距离度量基础

夜市找人的“尺子”不止一种。你可以量直线距离,把夜市想成一张平面图;也可以量绕过人群的实际路径;还可以只看“朋友正朝哪个方向走”。三种量法各有各的适用场景,这就是距离度量的基础。

在度量学习中,最基础的三把尺子是欧氏距离、马氏距离和余弦相似度。欧氏距离衡量多维空间中的直线距离,最直观;马氏距离通过协方差矩阵的逆对特征做白化,能消除量纲和特征相关性的影响;余弦相似度只关注向量的方向是否一致,不关心绝对长度。

欧氏距离的公式虽然简单,却有一个明显局限:它没有考虑各特征维度之间的相关性。身高和体重两个维度,单位不同、方差不同,直接求直线距离会让方差大的维度主导结果。马氏距离正是为了解决这一问题而设计,但它在深度学习中并不常用——因为特征由网络学得、维度高,协方差矩阵难以稳定估计。实际项目里,大家更爱用欧氏距离配合端到端训练,让网络自己去适应这把尺子。余弦相似度则在文本和图像检索场景中大量使用。

欧氏距离像一个简单好用的直线量尺,但夜市里有时你得绕开摊位走——这就是马氏距离的用武之地;而余弦相似度则像判断“朋友朝向哪个方向”,方向一致说明是同伴。选对尺子,决定了你会不会把某个路人错认成朋友。

de(xi,xj)=∑k=1n(xik−xjk)2d_e(\mathbf{x}_i, \mathbf{x}_j) = \sqrt{\sum_{k=1}^{n}(x_{ik} - x_{jk})^2}
欧氏距离就是“直线量尺”:把两个样本当作高维空间中的两个点,计算它们之间的直线长度。
  1. 各维度之差x_ik − x_jk,表示两个样本在第 k 个特征上的数值差距,比如夜市里两人身高的差。
    xik−xjkx_{ik} - x_{jk}
  2. 平方把负差转正,同时让大的差距对距离产生更大影响——“身高差 10cm 比差 1cm 更值得注意”。
    (xik−xjk)2(x_{ik} - x_{jk})^2
  3. 求和将 n 个维度上的差距全部累加,得到总差距,相当于把每个特征的“小差别”汇总成“总差别”。
    ∑k=1n(xik−xjk)2\sum_{k=1}^{n}(x_{ik} - x_{jk})^2
  4. 开方对累加结果开根号,把平方造成的“放大”还原为线性量纲,让距离的单位和原始特征一致。
    ∑k=1n(xik−xjk)2\sqrt{\sum_{k=1}^{n}(x_{ik} - x_{jk})^2}

孪生网络家族

夜市里最直觉的比对方式是“两两对照”:拿起照片,跟眼前的路人仔细比五官。孪生网络做的事情正是如此——它一次处理“一对”样本,输出一个“像不像”的分数,是最经典的度量学习范式之一。

孪生网络(Siamese Network)由两个共享权重的分支网络组成。两个输入分别经过同一个特征提取器,得到两个嵌入向量,再通过距离函数计算相似度。因为权重完全共享,模型天然保证了“同一个人”无论从哪个分支进入,都会被映射到相近的位置。

训练孪生网络常用对比损失(Contrastive Loss):同一类的样本对,拉近它们嵌入之间的距离;不同类的样本对,推远它们。更进阶的是三元组损失(Triplet Loss),每次取三个样本:锚点 a、正样本 p(与 a 同类)、负样本 n(与 a 不同类),目标是把 a 和 p 之间的距离压到比 a 和 n 之间的距离小一个间隔 α。正是这套“拉近正类、推开负类”的逻辑,让人脸识别系统具备了只靠少量照片就能认证身份的能力。

三元组损失就像练“火眼金睛”:每次拿朋友照片、亲戚照片、路人照片,学会把朋友和亲戚归到一起,把路人远远甩开。练得越多,你在夜市里一眼锁定朋友的速度就越快。

Ltriplet=max⁡(0, d(a,p)−d(a,n)+α)\mathcal{L}_{triplet} = \max\left(0,\ d(a,p) - d(a,n) + \alpha\right)
三元组损失要求“朋友”比“陌生人”至少近 α;如果已经满足,损失为 0,否则按差距更新模型。
  1. 正样本距离d(a,p),锚点与同类样本在嵌入空间中的距离——“朋友和亲戚像不像”。
    d(a,p)d(a,p)
  2. 负样本距离d(a,n),锚点与异类样本的距离——“朋友和路人像不像”。
    d(a,n)d(a,n)
  3. 间隔+α,强制正样本比负样本近至少 α 这么多;如果差距不足,就形成损失。
    α\alpha
  4. 上限截断max(0,·),当 d(a,p) + α < d(a,n) 时说明条件已满足,损失置零,不浪费梯度。
    max⁡(0, ⋅)\max(0,\ \cdot)

原型网络

如果朋友不是一个人,而是一群穿着“同款蓝卫衣”的人呢?与其记住每个人的脸,不如记住“蓝卫衣”这个集体特征。原型网络(Prototypical Network)的思路正是如此:为每个类别计算一个“代表点”,然后看查询样本离哪个代表点最近。

在特征空间中,原型网络把支持集中同一类别的所有样本嵌入向量取平均,得到该类别的“原型”(prototype)。分类时,查询样本计算到所有原型的距离,选择距离最近的类别作为预测结果。整个过程不需要训练额外的分类器,简单而高效,是小样本分类任务中最常见的强基线。

正式地,设嵌入函数为 f<sub>φ</sub>,第 k 类的原型就是该类支持样本嵌入的均值。给定查询嵌入 f<sub>φ</sub>(x),类别概率用 softmax 作用于负距离得到。训练时,网络不断随机采样多个 episode(每个 episode 都是一个独立的 few-shot 任务),用交叉熵损失端到端优化嵌入函数,使它学会“同类聚拢、异类分散”。

夜市里你发现朋友的社团都穿蓝卫衣,于是“蓝卫衣”成为你脑中那个原型的颜色。新路人离蓝卫衣原型越近,越可能是社团的人——原型网络就用“平均印象”代替了每一张具体面孔。

ck=1∣Sk∣∑(xi,yi)∈Skfϕ(xi)\mathbf{c}_k = \frac{1}{|S_k|}\sum_{(\mathbf{x}_i, y_i) \in S_k} f_\phi(\mathbf{x}_i)
原型是类别的“平均印象”:把支持集中所有蓝卫衣成员的特征向量加起来求平均,得到社团的代表形象。
  1. 支持子集S_k 表示第 k 类的全部支持样本,是“蓝卫衣社团”的所有已知成员。
    Sk={(xi,yi)∣yi=k}S_k = \{(\mathbf{x}_i, y_i) \mid y_i = k\}
  2. 嵌入映射f_φ(x_i) 把原始样本映射到特征空间中的一个坐标,等于每个社员的“身高、体型、神态”坐标。
    fϕ(xi)f_\phi(\mathbf{x}_i)
  3. 求平均同类所有坐标逐维求和后除以样本数,得到类别的中心点——原型,也就是社团的“平均画像”。
    1∣Sk∣∑(xi,yi)∈Skfϕ(xi)\frac{1}{|S_k|}\sum_{(\mathbf{x}_i, y_i) \in S_k} f_\phi(\mathbf{x}_i)

匹配网络

夜市里的线索并不总是可靠的:朋友的发型很独特,但蓝卫衣满大街都是。匹配网络(Matching Network)的做法是:不再把支持样本压成一个原型,而是让每个支持样本“各自发言”,用注意力权重决定“听谁的话更多”。

匹配网络保留所有支持样本的嵌入。查询样本到来时,先计算它与每个支持样本的注意力分数,再用这些分数对标签做加权求和,得到预测。注意力分数通常由余弦相似度计算,再经过 softmax 归一化。这样一来,长得越像的支持样本,对最终预测的发言权就越大。

高级版本的匹配网络还会使用全上下文嵌入(FCE):让每个支持样本的嵌入受到整个支持集信息的调制——就像你看到朋友站在奶茶店旁,会把“奶茶店”也当成一条环境线索。相比原型网络用“平均”压缩信息,匹配网络保留了每个样本的细节,因此当支持样本之间差异较大时,它往往更加灵活。

匹配网络像你带着朋友的一叠生活照:每张照片各有各的价值,你不把它们平局成“一张脸”,而是拿着路人跟每张照片比对,像的照片权重高、不像的权重低,最后所有人投票决定“这是不是朋友”。

y^=∑i=1Nexp⁡(c(f(x),g(xi)))∑j=1Nexp⁡(c(f(x),g(xj)))yi\hat{y} = \sum_{i=1}^{N} \frac{\exp\left(c(f(\mathbf{x}), g(\mathbf{x}_i))\right)}{\sum_{j=1}^{N}\exp\left(c(f(\mathbf{x}), g(\mathbf{x}_j))\right)} y_i
预测标签 = 每个支持样本标签的加权平均,权重就是查询样本与它的余弦相似度占比。
  1. 注意力权重分子是查询与某个支持样本的相似度取指数,分母是所有相似度之和,结果是一个 0 到 1 之间的“投票权”。
    exp⁡(c(f(x),g(xi)))∑j=1Nexp⁡(c(f(x),g(xj)))\frac{\exp(c(f(\mathbf{x}), g(\mathbf{x}_i)))}{\sum_{j=1}^{N}\exp(c(f(\mathbf{x}), g(\mathbf{x}_j)))}
  2. 加权求和把每个支持样本的标签 y_i 乘上它与查询的相似度权重再累加——“谁越像,谁对最终判断的贡献越大”。
    ∑i=1Nai⋅yi\sum_{i=1}^{N} a_i \cdot y_i
  3. 相似度核函数c(·,·) 通常取余弦相似度,衡量两个嵌入方向是否一致——“两人面向同一个方向站,算一种相似”。
    c(f(x),g(xi))=cos⁡(f(x),g(xi))c(f(\mathbf{x}), g(\mathbf{x}_i)) = \cos(f(\mathbf{x}), g(\mathbf{x}_i))

关系网络

前面几种方法要么用固定尺子(欧氏距离),要么用简单核函数(余弦)。关系网络(Relation Network)干脆换个思路:让一位经验丰富的“鉴定师”来看两张照片究竟像不像。鉴定师能看出“这两人虽然肤色不同,但眉形和笑容一模一样”——这是固定公式难以捕捉的复杂判断。

关系网络把“度量”本身也交给神经网络学习。它先用特征提取器得到查询样本和支持样本的嵌入,然后把两者的嵌入向量拼接在一起,交给一个“关系模块”(一个小型神经网络)打分。关系模块输出一个 0 到 1 之间的分数,表示两个样本属于同一类别的置信度。

具体做法是:将查询与同一类别所有支持样本的关系分数取平均,作为该类别的关系得分,取最大者作为预测结果。训练时用均方误差(MSE)作为损失,监督信号是“同类为 1、异类为 0”。相比原型网络假设各类样本呈近似球状分布,关系网络的深度距离能够适应更复杂的特征流形,在细粒度分类任务中往往表现更优。

这就好比夜市里的“目击者鉴定”:你不自己动手量,而是把两个路人的所有细节拼在一起,请老练的侦探拍板说“像”或“不像”。有了这位侦探,再复杂微妙的特征差异也能被他看穿。

ri=gϕ([fϕ(x), fϕ(xi)])r_i = g_\phi\left(\left[f_\phi(\mathbf{x}),\ f_\phi(\mathbf{x}_i)\right]\right)
关系分数 = 将两个嵌入拼接后,由一个小型神经网络打分,判断它们是否属于同一类。
  1. 嵌入拼接把查询嵌入和支持样本嵌入首尾相连,组成一个长度为两倍的向量——“把两个人的全身照拼在一张纸上”。
    [fϕ(x), fϕ(xi)]\left[f_\phi(\mathbf{x}),\ f_\phi(\mathbf{x}_i)\right]
  2. 关系模块g_φ 是一个小型神经网络(如两层全连接),接收拼接向量,输出标量关系分数。
    gϕ(⋅)g_\phi(\cdot)
  3. 关系分数r_i 表示查询与第 i 个支持样本“是自己人”的置信度,数值越接近 1,说明越像。
    ri∈[0,1]r_i \in [0, 1]

优化与技巧

想让鉴定师越来越准,就得让他多看“难认的”案例。夜市里有 100 个穿蓝卫衣的人,其中 90 个和朋友的体态差很远,只有 10 个乍一看几乎一样。如果训练时只挑容易的看,鉴定师永远学不会辨认真正难区分的路人。

在度量学习中,损失函数大多依赖样本对或三元组的组合。如果随机采样,绝大多数样本对属于“容易样本”——同类距离已经很小,异类距离已经很大,损失为 0,对训练毫无帮助。困难样本挖掘专门寻找那些让模型犯错的三元组,让梯度更新真正有信息量,从而大幅提升训练效率。

以三元组损失为例,“困难负样本”是指比正样本距离还近的负样本。批量困难挖掘(Batch Hard)在每一个 batch 内,对每个锚点挑选距离最远的正样本和距离最近的负样本组成三元组;其余策略还包括半困难挖掘、距离加权采样等。另一个重要的旋钮是温度参数 τ:在 softmax 中把距离除以 τ,可以控制输出分布的“锐利程度”。τ 越小,分布越接近 one-hot,模型越发自信;τ 越大,分布越平滑,模型越保守。

温度参数就像你的辨认“严格程度”:温度低,你只看最像的那个人,稍有一丝差异就排除;温度高,你觉得谁都差不多。夜市中温度太低容易漏看,温度太高容易认错——调好温度,是鉴定师进阶的必修课。

y^=exp⁡(−d(fϕ(x),ck)/τ)∑jexp⁡(−d(fϕ(x),cj)/τ)\hat{y} = \frac{\exp\left(-d(f_\phi(\mathbf{x}), \mathbf{c}_k) / \tau\right)}{\sum_{j}\exp\left(-d(f_\phi(\mathbf{x}), \mathbf{c}_j) / \tau\right)}
温度参数 τ 决定“判断的严格程度”:τ 小,只认最像的类别;τ 大,所有类别都“有点可能”。
  1. 距离除以温度−d/τ,τ 越小,不同类别之间距离的差异被放大,模型的判断更“激进”。
    −d(fϕ(x),ck)/τ-d(f_\phi(\mathbf{x}), \mathbf{c}_k) / \tau
  2. 指数化exp(·) 保证结果为正值,同时保持“距离越近、得分越高”的顺序。
    exp⁡(⋅)\exp(\cdot)
  3. 归一化分母对所有类别的指数得分求和,把输出压缩到 0~1 之间,形成概率分布。
    ∑jexp⁡(−d(fϕ(x),cj)/τ)\sum_{j}\exp\left(-d(f_\phi(\mathbf{x}), \mathbf{c}_j) / \tau\right)

应用与挑战

度量学习的“找人”本领早已走出夜市:手机刷脸解锁、监控视频检索、商品拍照识图、冷启动推荐……这些场景的背后,都站着一把经过训练的“相似度尺子”。

在真实企业中,度量学习最经典的应用是人脸认证。银行 App 活体认证、门禁系统、相册自动聚类,都依赖“先提取嵌入、再比较距离”的流程。它的核心优势在于可以不断加入新用户,而无需重新训练分类器:只需要把新用户的人脸嵌入存入特征库,之后用距离检索即可完成识别。图像检索、基于内容的推荐、异常检测(距离中心太远的样本即为异常),也都属于度量学习的应用战地。

不过度量学习并非万能。它强依赖嵌入函数的表征质量:如果特征提取器学到的特征本身不具备判别性,再好的距离函数也无济于事。原型网络假设各类样本在特征空间呈近似各向同性的球状分布,而真实数据往往不满足这一假设。此外,episode 训练与真实测试之间可能存在分布漂移。近年的趋势是把 Transformer 和大规模预训练模型作为嵌入提取器,用自监督对比学习预热特征空间,再利用度量方法快速适配新类别。

对比损失就像夜市里的“社群规则”:熟人互相靠近(d→0),陌生社团保持距离(d>m)。从孪生网络到原型、匹配、关系网络,本质都是这条规则的不同变奏。掌握度量学习,就掌握了在样本稀少的现实世界里为万物“量身定尺”的能力。

L=y⋅d2+(1−y)⋅max⁡(0, m−d)2\mathcal{L} = y\cdot d^2 + (1-y)\cdot \max\left(0,\ m-d\right)^2
对比损失是度量学习的“通用配方”:同类对的距离要压到 0,异类对的距离要推到边界 m 以外。
  1. 同类对损失y·d²,当两个样本同属一类(y=1)时,距离 d 越大,损失越大。
    y⋅d2y\cdot d^2
  2. 异类对损失(1−y)·max(0, m−d)²,当属于不同类(y=0)且距离小于 m 时产生损失;距离已超过 m,损失为 0。
    (1−y)⋅max⁡(0, m−d)2(1-y)\cdot \max(0,\ m-d)^2
  3. 边界参数m 控制“异类至少要隔开多远”,相当于夜市中不同社团之间需要保持的安全距离。
    mm

AI 应用场景

银行刷脸认证系统的少样本度量学习

阶段:特征抽取与相似度匹配(推理阶段)

解决的问题:传统人脸认证需要为每个用户采集大量照片来训练分类器,但银行新增用户往往只有 1~3 张人脸照片,无法训练大规模分类模型。度量学习通过“预训练嵌入网络 + 距离检索”的路线,新用户注册时只需录入一张照片,提取特征存入特征库,即可完成身份认证。

具体案例:某银行 App 注册时要求用户拍摄人脸,系统用度量学习模型提取 512 维特征向量存入向量数据库。登录时再次提取特征,与库中向量计算欧氏距离,距离小于阈值即认证通过。用户换手机或光线变化导致认证失败时,系统会使用最近一次成功认证的特征做增量更新。

电商拍照识图与以图搜图

阶段:嵌入训练与向量检索

解决的问题:电商平台商品图片数以亿计,新品上线时往往没有大量标注数据。度量学习把商品图片映射到同一语义空间,拍照搜图时返回与查询图片嵌入距离最近的商品,无需为新品类单独训练分类器。

具体案例:某电商平台的“拍立淘”功能,后端使用基于度量学习的 embedding 模型将商品图和用户实拍图映射到同一嵌入空间,用近似最近邻(ANN)检索召回 Top50 候选,再由精排模型排序。新品只需计算与已有商品的嵌入距离,即可进入检索库参与召回。

冷启动场景下的用户兴趣度量

阶段:用户嵌入与相似度推荐

解决的问题:新用户几乎没有行为数据,传统推荐系统无法建模其兴趣偏好。度量学习将商品和用户交互映射到共同的嵌入空间,用距离度量用户与商品的相似度,实现“用小样本初始化兴趣模型”。

具体案例:某资讯 App 冷启动时,让新用户选择感兴趣的三五个标签(每类仅一两个样本),系统以这些标签为支持集,计算各候选文章嵌入与支持集的加权距离,按距离排序输出初始推荐列表。随着用户点击行为增多,支持集动态扩大,推荐逐渐精细化。

Python 演示

python48 行
"""简易原型网络:小样本分类演示"""import numpy as np def euclidean_distance(x1, x2):    """欧氏距离矩阵: x1 [N, D], x2 [M, D] -> [N, M]"""    n = x1.shape[0]    m = x2.shape[0]    x1_sq = np.sum(x1 ** 2, axis=1).reshape(n, 1)    x2_sq = np.sum(x2 ** 2, axis=1).reshape(1, m)    cross = -2.0 * np.dot(x1, x2.T)    return np.sqrt(np.maximum(x1_sq + x2_sq + cross, 0)) def compute_prototypes(support_emb, support_label, n_classes):    """每个类别支持样本嵌入的均值作为类原型"""    prototypes = []    for c in range(n_classes):        mask = support_label == c        proto = support_emb[mask].mean(axis=0)        prototypes.append(proto)    return np.stack(prototypes) def predict_query(query_emb, prototypes):    """选择距离最近的原型作为预测类别"""    dists = euclidean_distance(query_emb.reshape(1, -1), prototypes)[0]    return int(np.argmin(dists)), dists def simulate_data(n_classes, support_per_class, embed_dim, seed=42):    """生成模拟的嵌入数据:支持集 + 一个查询样本"""    rng = np.random.RandomState(seed)    support_emb = rng.randn(n_classes * support_per_class, embed_dim)    support_label = np.repeat(np.arange(n_classes), support_per_class)    query_emb = rng.randn(embed_dim)    return support_emb, support_label, query_emb def main():    n_classes = 5    support_per_class = 3    embed_dim = 8    support_emb, support_label, query_emb = simulate_data(        n_classes, support_per_class, embed_dim    )    prototypes = compute_prototypes(support_emb, support_label, n_classes)    pred, dists = predict_query(query_emb, prototypes)    print("查询样本与各类原型距离:", np.round(dists, 4))    print("预测类别:", pred) if __name__ == "__main__":    main()
目的:用 NumPy 从零实现一个最简原型网络,演示“支持集求原型 → 查询样本距离比较 → 最近者获胜”的完整流程。
  1. support_emb[mask].mean(axis=0)对第 c 类所有支持样本的嵌入逐维求均值,得到该类别的原型。
  2. euclidean_distance(query_emb.reshape(1, -1), prototypes)[0]计算查询嵌入到每个原型的欧氏距离,返回距离向量。
  3. np.argmin(dists)找出距离最小的原型索引,作为预测类别,对应“距离最近者获胜”。
  4. np.repeat(np.arange(n_classes), support_per_class)构造支持集标签,每个类别连续出现 support_per_class 次。
  5. np.stack(prototypes)把各原型按行堆叠成矩阵,便于后续一次计算所有距离。

常见误区

误区只要把数据标准化,然后选欧氏距离或者余弦相似度,就算做完度量学习了。

正解度量学习的核心不是“选什么距离”,而是“联合学习一个特征映射 + 度量”。距离函数往往简单固定,真正决定效果的是前面的特征提取器 f_φ。同样用欧氏距离,前面接一个精心训练的嵌入网络,效果天差地别——夜市里,用再准的尺子,也敌不过你认错照片。

为何常见:早期工作确实是在固定特征上选度量,让人容易忽略映射学习的决定性作用。

误区原型网络分类时就是对支持样本取平均,这是不是意味着它根本没有训练过程?

正解均值计算只是推理端的最后一步。真正可学习的是嵌入函数 f_φ。原型网络通过大量 episode 训练,用交叉熵损失端到端优化 f_φ,使“类内样本的均值能代表这个类”这一假设在特征空间中成立。没有训练,均值毫无意义。

为何常见:原型公式看起来过于简洁,容易让人忽略它背后的深度网络训练。

误区每类只有 1 个样本,怎么学得到好的度量?度量学习一定不适合极端的少样本场景。

正解度量学习恰恰是为少样本设计的。它不依赖单个任务内的数据量,而是在大量 episode 上学习通用的嵌入规律。训练阶段每个 episode 本身就是 few-shot 的,因此测试时即使每类只有 1 个样本,嵌入照样能给出有效的距离判断。

为何常见:直觉上“一个样本什么都做不了”,容易忽视 episode 训练这种“用小样本任务堆出大模型”的设计范式。

误区只要在模型里加入 Triplet Loss,嵌入就一定能分得开,效果必然优于 Contrastive Loss。

正解三元组损失对采样极其敏感。随机采样的三元组大多是“容易样本”,损失为 0,模型学不到东西;必须配合困难样本挖掘、合适的 batch size 和边距 α,效果才会显现。否则训练不稳定,甚至比不上简单的对比损失。

为何常见:Triplet Loss 在人脸识别中名声大噪,容易让人忽略其实现中的大量工程细节。

面试题

Q1. 度量学习的核心目标是什么?

单选题 · easy

  • A.学习一个分类边界
  • B.学习相似度度量空间← 正确答案
  • C.增加模型的参数量
  • D.减少样本标注数量

答案:B。度量学习的目标不是学分类边界,而是学一个特征空间,让同类距离近、异类距离远。A 是传统分类器思路,C 是无关方向,D 是数据增广范畴。夜市找朋友靠的是“谁离朋友印象最近”,而不是“夜市被划分成几个区域”。

Q2. 欧氏距离的显著局限是什么?

单选题 · easy

  • A.无法计算多维向量数据
  • B.未考虑维度的相关性← 正确答案
  • C.结果总是大于数值一
  • D.速度比余弦相似度慢

答案:B。欧氏距离直接对各维度差值平方求和,假设各维度独立且等权重。若两个特征高度相关(如身高和体重),会导致信息冗余且方差大的维度主导距离。就像夜市里只量直线距离,不考虑“某些路上摊位多绕行更难走”。

Q3. Triplet Loss 的三元组组成是?

单选题 · mid

  • A.查询正样本与原型
  • B.锚点正样本和负样本← 正确答案
  • C.支持样本查询和原型
  • D.输入输出以及目标标签

答案:B。三元组由锚点 a、正样本 p(与 a 同类)和负样本 n(与 a 异类)构成,目标是让 d(a,p) 比 d(a,n) 小至少 α。夜市比喻中,a 是朋友照片,p 是亲戚,n 是陌生人——学会“朋友更像亲戚而非陌生人”。

Q4. 原型网络如何生成类原型?

单选题 · mid

  • A.对支持样本嵌入求均值← 正确答案
  • B.对支持样本嵌入求中位
  • C.随机选取一个代表样本
  • D.用线性分类器求解权重

答案:A。原型网络将同一类所有支持样本的嵌入向量取平均,得到该类别的原型。均值作为“平均印象”,比单一样本更稳健。夜市里,朋友所在的蓝卫衣社团的“平均形象”,比任何单个社员都更能代表这个社团。

Q5. 关系网络与原型网络的区别是?

单选题 · mid

  • A.关系网络使用更多支持样本
  • B.关系模块由神经网络构成← 正确答案
  • C.原型网络不需要特征嵌入
  • D.二者的本质完全相同

答案:B。关系网络用神经网络作为关系模块学习深度距离,而原型网络使用固定的欧氏距离。固定尺子量的是直线距离,鉴定师却能看出“眉形和笑容一致”这种复杂相似。原型网络当然也需要特征嵌入,C 错误。

Q6. 匹配网络的注意力权重来源是?

单选题 · hard

  • A.距离最近的样本权重为一
  • B.对余弦相似度做softmax← 正确答案
  • C.所有支持样本权重相等
  • D.用随机权重初始化网络

答案:B。匹配网络先计算查询与每个支持样本的余弦相似度,再对相似度向量做 softmax,得到和为 1 的注意力权重。这相当于夜市里“越像的照片投票权重越高”——而不是简单地把票平均分给所有人。

Q7. 困难样本挖掘的核心思想是?

单选题 · mid

  • A.只挑选容易分类的样本
  • B.优先挑选损失高的组合← 正确答案
  • C.增大训练数据集的数量
  • D.用生成数据代替真数据

答案:B。困难样本挖掘专门挑选那些让模型“犯错”或损失较高的三元组参与梯度更新,让训练信号更有信息量。容易样本的损失已经是 0,练再多也不会进步——夜市里只有那些让你认错的人,才是真正教会你辨认朋友的老师。

Q8. 以下哪些属于度量学习方法?

多选题 · mid

  • A.孪生网络对比学习← 正确答案
  • B.原型网络匹配网络← 正确答案
  • C.生成对抗网络
  • D.关系网络三元损失← 正确答案

答案:ABD。孪生网络、原型网络、匹配网络、关系网络以及三元组损失都是度量学习的主流方法。生成对抗网络(GAN)属于生成模型,任务是生成数据而非度量相似度,不属于度量学习范畴。

Q9. 关于小样本度量学习正确的有?

多选题 · hard

  • A.有效缓解过拟合问题← 正确答案
  • B.用episode训练通用嵌入← 正确答案
  • C.只能处理图像数据
  • D.依赖相似度度量函数← 正确答案

答案:ABD。度量学习通过 episode 训练学习通用嵌入,减少小样本过拟合,并依赖距离或相似度函数做核心决策。C 错误:度量学习广泛应用于文本、语音、推荐系统,并非只能处理图像。

Q10. 影响度量学习性能的因素有哪些?

多选题 · extreme

  • A.特征嵌入表达能力← 正确答案
  • B.距离函数与温度设置← 正确答案
  • C.训练时的采样策略← 正确答案
  • D.支持集样本的质量← 正确答案

答案:ABCD。嵌入函数决定特征质量,距离函数和温度参数调节相似度计算方式,采样策略(如困难样本挖掘)影响训练信号,支持集本身的质量直接关系到原型或注意力权重的可靠性。四者共同决定度量学习的最终效果,缺一不可。