PyTorch:距离度量

Posted -柚子皮-

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PyTorch:距离度量相关的知识,希望对你有一定的参考价值。

两个张量之间的欧氏距离

即m*e和n*e张量之间的欧式距离

理论分析

算法实现

import torch


def euclidean_dist(x, y):
    """
    Args:
      x: pytorch Variable, with shape [m, d]
      y: pytorch Variable, with shape [n, d]
    Returns:
      dist: pytorch Variable, with shape [m, n]
    """
    m = x.size(0)
    n = y.size(0)
    e = x.size(1)

    # 方式1
    a1 = torch.sum((x ** 2), 1, keepdim=True).expand(m, n)
    b2 = (y ** 2).sum(1).expand(m, n)
    dist = (a1 + b2 - 2 * (x @ y.T)).float().sqrt()
    print(dist)

    # 方式2
    x1 = x.unsqueeze(1).expand(m, n, e)
    y1 = y.expand(m, n, e)
    dist = (x1 - y1).pow(2).sum(2).float().sqrt()
    print(dist)

    # 方式3
    dist = torch.zeros((m, n))
    for i, xi in enumerate(x):
        for j, yi in enumerate(y):
            # 方式2.1
            # dist[i][j] = ((xi - yi) ** 2).sum().float().sqrt()
            # 方式2.2
            dist[i][j] = torch.pairwise_distance(torch.unsqueeze(xi, 0), torch.unsqueeze(yi, 0), p=2)
    print(dist)

    # 方式4
    dist = torch.zeros((m, n))
    for i, xi in enumerate(x):
        dist[i] = torch.pairwise_distance(xi, y, p=2)
    print(dist)
    return dist


a = torch.tensor([[1, 2], [3, 4], [5, 6]])
b = torch.tensor([[2, 3], [4, 5], [5, 6], [8, 9]])
dist = euclidean_dist(a, b)

tensor([[1.4142, 4.2426, 5.6569, 9.8995],
        [1.4142, 1.4142, 2.8284, 7.0711],
        [4.2426, 1.4142, 0.0000, 4.2426]])

[矩阵之间欧式距离的快捷计算方法(无循环)]

m*e和m*e张量之间的欧式距离pairwise_distance

import torch.nn.functional as F
distance = F.pairwise_distance(rep_a, rep_b, p=2)

其中rep_a和rep_b为[batch_size,hidden_dim],两个维度必须相同,或者第一个维度为[hidden_dim]会自动进行广播操作(且最多只能有两个维度?)

[torch.nn.PairwiseDistance(p=2.0, eps=1e-06, keepdim=False)]

使用numpy完成相同操作

import numpy as np
def euclidean_dist(a, b):
    '''
    计算a中向量和b中向量 两两间的欧式距离
    '''
    import numpy as np
    a = np.asarray(a)
    b = np.asarray(b)
    dist = np.sqrt(np.sum(a ** 2, 1, keepdims=True).repeat(b.shape[0], axis=1) +
                   np.sum(b ** 2, 1, keepdims=True).repeat(a.shape[0], axis=1).transpose() - a.dot(b.transpose()) * 2)
    return dist


a = np.array([[1, 2], [3, 4], [5, 6]])
b = np.array([[2, 3], [4, 5], [5, 6], [8, 9]])
dist = euclidean_dist(a, b)
print(dist)

[[1.41421356 4.24264069 5.65685425 9.89949494]
 [1.41421356 1.41421356 2.82842712 7.07106781]
 [4.24264069 1.41421356 0.         4.24264069]]

-柚子皮-

单个张量内部向量两两之间的欧氏距离

def self_euclidean_dist(embeddings):
    # 方式1(类似euclidean_dist(x, y)方式2)
    m, m, e = len(embeddings), len(embeddings), embeddings.shape[1]
    t1 = embeddings.unsqueeze(1).expand(m, m, e)
    t2 = embeddings.unsqueeze(0).expand(m, m, e)
    dist = (t1 - t2).pow(2).sum(2).float().sqrt()
    print(dist)
    return dist


a = torch.tensor([[1, 2], [3, 4], [5, 6]])
self_euclidean_dist(a)
from: -柚子皮-

ref:

以上是关于PyTorch:距离度量的主要内容,如果未能解决你的问题,请参考以下文章

PyTorch:距离度量

Collaborative Translational Metric Learning论文小结(附核心pytorch代码)

Collaborative Translational Metric Learning论文小结(附核心pytorch代码)

Collaborative Translational Metric Learning论文小结(附核心pytorch代码)

Collaborative Translational Metric Learning论文小结(附核心pytorch代码)

Collaborative Translational Metric Learning论文小结(附核心pytorch代码)