图像特征匹配场景下np.linalg.norm两种用法的区别是什么?
两行代码的计算逻辑与差异说明
1. dists1 = np.linalg.norm(features - query, axis=1) 计算逻辑
- 第一步先执行
features - query操作:features是形状为(31303, 4096)的特征库数组,每一行对应一张图库图像的4096维特征;query是形状为(4096,)的待查询图像特征,此处会触发numpy广播机制,query自动扩展为和features同形状的(31303, 4096)数组,和features逐元素相减,得到每个图库特征和查询特征的差值向量。 - 第二步调用
np.linalg.norm(..., axis=1):未指定ord参数时默认计算L2范数(也就是欧氏距离),axis=1表示对每一行的差值向量单独计算范数,最终得到的dists1是长度为31303的数组,每个值对应对应图库特征和查询特征的欧氏距离,数值越小说明两个特征相似度越高,是图像检索场景下正确的相似度计算方式。 - 你输出中打印的
dists就是这个计算结果,数值范围在0-1.3之间,和你提取的特征是L2归一化特征的特性匹配(你打印的query的L2范数接近1,两个归一化向量的欧氏距离最大值为2,和输出范围完全吻合)。
2. dists2 = (np.linalg.norm(features, axis=1)) - np.array(np.linalg.norm(query, 0)) 计算逻辑
- 首先计算
np.linalg.norm(features, axis=1):对features每一行计算默认的L2范数,得到长度为31303的数组,每个值是对应图库特征的L2模长,由于你的特征经过L2归一化,这个数组里所有值都接近1。 - 然后计算
np.linalg.norm(query, 0):这里指定了ord=0参数,L0范数的定义是向量中非零元素的个数,你的query是4096维特征,其中非零元素数量为1158,所以这个值是固定的常数1158。 - 最后用每个图库特征的L2模长(≈1)减去1158,得到的结果全部≈-1157.9999,取整后就是你输出中全为-1158的结果,这个计算逻辑和特征相似度完全无关,属于参数传递错误导致的无效计算。
两者核心差异
- 计算逻辑完全不同:dists1计算的是两个特征向量差值的L2范数(欧氏距离),直接衡量两个特征的相似程度;dists2计算的是图库特征的L2范数减去查询特征的L0范数,两个计算维度没有语义关联,完全不能衡量相似度。
- 结果价值不同:dists1的数值范围合理,排序后可以直接得到最相似的TopK检索结果;dists2所有结果都接近-1158,没有任何检索价值。
内容的提问来源于stack exchange,提问作者Timmi Kleinnibbelink Rysgaard
相关产品推荐
相关产品推荐

