长度、方向和点积:怎样比较两串特征
先从二维箭头说明为什么要归一化,再扩展到 128 维。相似度、最大类别和显示用分数分别解释。
1 · 同一方向,长度可以不同
向量 (1,0) 和 (10,0) 指向同一个方向,但长度相差十倍。直接点积会受到长度影响,如果希望按方向比较,就先把向量除以自己的长度,使它变成单位长度。
得到长度 5,单位向量 [0.6,0.8]
v = np.array([3.0, 4.0])
length = np.sqrt((v*v).sum())
unit = v / length
print(length, unit)这叫 L2 归一化。零向量没有可定义的方向,不能直接除零;包含 NaN 或无穷的输入也应拒绝。配套示例在归一化之前检查这些情况。
2 · 归一化以后,点积表示什么
两个单位向量点积为 0.8
query = np.array([0.8, 0.6])
prototype = np.array([1.0, 0.0])
similarity = (query * prototype).sum()
print(similarity)对应坐标相乘再相加叫点积。对单位向量,它等于两者夹角的余弦:同向接近 1,垂直接近 0,反向接近 -1。因此项目可以把各类相似度比较后取最大者。128 维仍是同样的乘加与求和。
3 · 先归一化样本,还是先求中心
当前特征提取输出已经归一化,会话对这些特征求均值,再把均值归一化成新原型。对于长度不同的原始向量,这与直接先求均值再归一化不一定相同;训练与更新约定必须一致。
proto_model.c 在设置和预测时还做了防御性归一化,读实际实现可见,不能只沿用头文件中“完全依赖调用者”的旧说明。即便内部再归一化,有限数值、非零方向和正确模型仍是前提。
4 · 为什么最高相似度不等于可信概率
取最大者只说明“在这几类里最接近谁”。若新动作根本不属于已知类别,也仍可能有一个最大值。相似度可以辅助拒绝策略,但阈值需要用真实未知动作与独立场次评估。
项目还通过指数和归一化生成总和为一的分数,放大系数会改变尖锐程度。总和为一并不能保证它是校准过的正确概率;更新前后比较要保留原始分数及实际错误。
5 · 用短程序核对高维计算
构造几个 128 维单位向量,比较 Python 与 C 的点积、类别编号,允许明确的浮点误差。零向量和非有限值作为单独输入检查,不能期待 argmax 自动代表有效判断。
把 [3,4] 乘以 10,分别比较未归一化点积和归一化后相似度。再构造一个与所有原型都不相近的样本,说明为什么仍会得到最大类别。