🧠 第六章 自然语言处理
📄 一句话概括

6 张 48×48 合成图,12 维颜色块加 8 维梯度方向共 20 维特征,两组各自归一化后拼接。 查询一张带噪的红竖条,第一名是红竖条 0.9994,可第二、 三名是绿竖条 0.7891 和蓝竖条 0.7722,同色的红横条只有 0.6153。

📝 本节和前面几节的关系

上一节把图整理成统一形状,这一节把它变成向量。 这也是「Embedding」这个词在图像上的用法:不是词变向量,是图变向量。

一、图像 Embedding 和词 Embedding 是一回事

都是把东西映射成一个定长向量,要求相似的东西向量也相近。 区别只在原料:词靠共现统计,图靠像素统计。 所以评价方法也一样:取一个查询,算它和库里每个向量的余弦,看排在最前的是不是同类。 Demo 走的就是这条路:6 张图进库,1 张图查询,看 top-3。

二、特征怎么定:颜色一组、走向一组

颜色组 12 维:把图切成四块,每块算 RGB 均值,4 乘 3 得 12。这组抓「什么颜色」。 梯度组 8 维:算每个像素的梯度方向,归到 8 个方向桶里,把每个桶的梯度强度加起来。 这组抓「什么走向」。 两组量纲完全不同——颜色均值在 0 到 1,梯度强度可能上百。直接拼起来,梯度会压倒颜色。 所以每组先各自归一化成单位向量,再拼接,最后整体再归一化一次。这样两组权重相等。

三、排序暴露了一件事

查询是带噪的红竖条,第一名红竖条 0.9994,对。 但第二、三名是绿竖条 0.7891 和蓝竖条 0.7722——换了颜色没换走向; 同色的红横条只有 0.6153,排在第四。 也就是说「走向相同」给的相似度接近满分,「颜色不同」只把分数压到七成多。 在余弦里两组等权,可两组内部差异的尺度不一样。 想让颜色优先,得给颜色组乘个权重。权重怎么定?只能拿真实图片试。 这就是「调特征权重」这件事最朴素的样子。

四、这套方法能用到哪、不能用到哪

能用:颜色和纹理是主要区分依据的场景——找同款纯色商品、筛掉重复拍摄的物料图、按色调给图库分类。 不能用:换成人脸、场景、文字,这套特征立刻失效。因为颜色和走向描述不了「这张脸是谁」。 真实系统用的是神经网络提的特征(ResNet、CLIP 之类),维度几百到几千,而且是在上亿张图上训出来的。 但流程一样:定特征、归一化、算余弦、排序。换成深度特征,后面三步一个字都不用改。

五、动手 Demo:图像检索:颜色块加梯度方向,做 top-3

造 6 张 48×48 的合成图(红、蓝、绿三色乘竖条、横条), 每张算 12 维颜色块均值加 8 维梯度方向直方图;两组各自归一化后拼接,整体再归一化; 用一张带噪的红竖条做查询,算与库里 6 张的余弦,排 top-3。

c = np.array(col); c = c / np.linalg.norm(c)      # 颜色组归一
g = hist / np.linalg.norm(hist)                  # 梯度组归一
v = np.concatenate([c, g])
v = v / np.linalg.norm(v)

sims = [(float(fq @ F[i]), names[i]) for i in range(len(names))]

实跑输出:

--------------------------------------------------------------------
图像 Embedding:颜色块直方图 + 梯度方向,做 top-3 检索
--------------------------------------------------------------------
  图库张数                 6
  特征维度                 20(12 维颜色块 + 8 维梯度方向)
  归一化                   每个向量除以自己的模,模长变 1

  查询图:红竖条(另加了 σ=6 的噪声,种子也不同)
  图库条目   余弦相似度
  --------------------
  红竖条         0.9994
  绿竖条         0.7891
  蓝竖条         0.7722
  红横条         0.6153
  绿横条         0.4127
  蓝横条         0.3898
  检索正确                 是(第 1 名就是同类)

  排序读出来的东西比「检索正确」更有意思:第 2、第 3 名是另外两种颜色的竖条,第 4 名才是同色的横条。
  也就是说「走向相同」给的是满分,而「颜色不同」只把相似度压到七成多——在余弦里两组特征权重相等,可两组各自内部的差异尺度不一样。
  想让颜色优先,得给颜色那一组乘个权重;权重怎么定,只能拿真实图片试,拍脑袋定不了。另外这套特征是手工定的,换一批图(比如人脸)直接失效。

第一名 0.9994,几乎满分。查询图只加了 σ=6 的噪声,形状没变,所以特征几乎一样。 第二、三名 0.7891 和 0.7722 是另外两色的竖条。它们走向完全一样,梯度组贡献了满分的相似度。 红横条 0.6153 排第四。它颜色完全一样但走向不同,梯度组几乎不投分,只剩颜色组在撑。 这四行说明一件事:两组特征等权的时候,「走向」这个维度比「颜色」更硬。想改排序,只能改权重。

30 秒实验

  1. 把颜色组乘 2、梯度组乘 0.5,再看排序会不会变成「先同色后同走向」。
  2. 把 4 块颜色改成 9 块(3×3),看特征维度变成多少、排序有没有变。
  3. 想一想:为什么换成深度特征之后,后面的流程一步都不用改?

常见误区

  1. 「特征维度越高越准」——无关维度只会带来噪声。
  2. 「两组特征直接拼就行」——量纲差太远,会被一组压倒。
  3. 「这套特征能识别人脸」——颜色和走向描述不了「是谁」。
自测三问(点开对答案) 1. 两组特征为什么要各自归一化再拼接? —— 量纲差太远,不分别归一化的话梯度强度会压倒颜色均值。 2. 为什么同色的红横条排在异色的绿竖条后面? —— 两组等权时「走向相同」贡献近满分,「颜色不同」只压到七成多。 3. 换成深度特征之后,哪些步骤不用改? —— 归一化、算余弦、排序这三步都不用改,只换特征提取那一段。

图变成向量了。最后一步:把提示词也变成向量,两边才好在同一个空间里比。

相关笔记