归一化 CNN 网络输出以获得 0 和 1 之间的距离输出
Normalizing CNN network output to get a distance output between 0 and 1
我正在使用基于 PyTorch 的 CNN 对人类图像进行特征提取,以便使用它重新识别给定不同图片的同一个人。在整个过程之后,我剩下一个一维向量,大约 2048x1
然后我使用 L2 距离作为度量来比较它。我目前正在尝试标准化 L2 距离输出,以便我可以将模型的预测表示为来自 0-1
.
的置信度
我注意到 PyTorch 建议使用加载到 [0, 1]
的 运行ge 中的图像加载位置,然后使用 mean = [0.485, 0.456, 0.406]
和 std = [0.229, 0.224, 0.225]
进行规范化。当它这样做时,它似乎改变了 L2 距离输出的 运行ge,这改变了 L2 距离值的 运行ge,使其不再 0-1
。我想知道是否有一种方法可以将输出向量归一化为 0-1
运行ge 甚至 L2 距离本身,这样我就可以从 0-1
中表示它
编辑:
以下是我用来计算 L2 距离的代码
distmat = torch.pow(qf, 2).sum(dim=1, keepdim=True).expand(m, n) + \
torch.pow(gf, 2).sum(dim=1, keepdim=True).expand(n, m).t()
distmat.addmm_(qf, gf.t(), beta=1, alpha=-2, )
distmat = distmat.cpu().numpy()
正如一位评论者所建议的,我正在尝试更改 L2 距离计算以改为使用余弦距离。这是我当前的代码:
distmat = torch.mm(qf, gf.t())
然而,当我 运行 这样做时,我得到的输出如下所示:
tensor([[ 0.3244, 0.2478, 0.1808, -0.0249, 0.2137, 0.2113]])
想知道这是否是计算余弦距离的正确方法?
编辑 2:
对我来说余弦相似度的最终实现是这样的:
qf_norm = qf / qf.norm(dim=1)[:, None]
gf_norm = gf / gf.norm(dim=1)[:, None]
distmat = torch.mm(qf_norm, gf_norm.transpose(0, 1)).cpu().numpy()
使用规范化与不使用规范化
您使用的是预训练网络吗?
如果是,并且预训练模型是使用标准化输入(mean/std 转换)训练的,那么您应该使用这些操作。如果您在没有这些操作的情况下使用,嵌入将没有用或用处不大。简单地说,你应该输入标准化图像,因为模型是在标准化输入上训练的。
归一化距离
L2 距离是无限的。即使您计算典型输入样本的范围,也不能保证新的输入图像会落在该范围内。出于这个原因,人们使用类似于归一化点积的余弦相似度,因此总是在 0 和 1 -1 和 1.
之间
我正在使用基于 PyTorch 的 CNN 对人类图像进行特征提取,以便使用它重新识别给定不同图片的同一个人。在整个过程之后,我剩下一个一维向量,大约 2048x1
然后我使用 L2 距离作为度量来比较它。我目前正在尝试标准化 L2 距离输出,以便我可以将模型的预测表示为来自 0-1
.
我注意到 PyTorch 建议使用加载到 [0, 1]
的 运行ge 中的图像加载位置,然后使用 mean = [0.485, 0.456, 0.406]
和 std = [0.229, 0.224, 0.225]
进行规范化。当它这样做时,它似乎改变了 L2 距离输出的 运行ge,这改变了 L2 距离值的 运行ge,使其不再 0-1
。我想知道是否有一种方法可以将输出向量归一化为 0-1
运行ge 甚至 L2 距离本身,这样我就可以从 0-1
编辑:
以下是我用来计算 L2 距离的代码
distmat = torch.pow(qf, 2).sum(dim=1, keepdim=True).expand(m, n) + \
torch.pow(gf, 2).sum(dim=1, keepdim=True).expand(n, m).t()
distmat.addmm_(qf, gf.t(), beta=1, alpha=-2, )
distmat = distmat.cpu().numpy()
正如一位评论者所建议的,我正在尝试更改 L2 距离计算以改为使用余弦距离。这是我当前的代码:
distmat = torch.mm(qf, gf.t())
然而,当我 运行 这样做时,我得到的输出如下所示:
tensor([[ 0.3244, 0.2478, 0.1808, -0.0249, 0.2137, 0.2113]])
想知道这是否是计算余弦距离的正确方法?
编辑 2:
对我来说余弦相似度的最终实现是这样的:
qf_norm = qf / qf.norm(dim=1)[:, None]
gf_norm = gf / gf.norm(dim=1)[:, None]
distmat = torch.mm(qf_norm, gf_norm.transpose(0, 1)).cpu().numpy()
使用规范化与不使用规范化
您使用的是预训练网络吗?
如果是,并且预训练模型是使用标准化输入(mean/std 转换)训练的,那么您应该使用这些操作。如果您在没有这些操作的情况下使用,嵌入将没有用或用处不大。简单地说,你应该输入标准化图像,因为模型是在标准化输入上训练的。
归一化距离
L2 距离是无限的。即使您计算典型输入样本的范围,也不能保证新的输入图像会落在该范围内。出于这个原因,人们使用类似于归一化点积的余弦相似度,因此总是在 0 和 1 -1 和 1.