乐趣区

关于pytorch:协方差矩阵在torch和numpy中的比较以及自行实现torch协方差矩阵

我自己是此作者:https://yonggie.blog.csdn.net…

前言

数学中(教科书、大学课堂、数学相干的科普视频),一个矩阵的向量往往是竖着的,一列作为一个 vector,这一点 numpy 库也是这样默认的。
然而在机器学习以 torch 框架为例,一个有意义的向量或者说 embedding是横着的

比拟

因为 numpy 库默认是一列是一个向量而 torch 等机器学习框架默认一行是一个向量,所以
torch.cov(X)numpy.cov(X.T)是相等的。

自行实现

torch 在较高版本中才有 torch.cov 函数,低版本的须要自行实现。
因为大部分博客都是数学格调的,在减掉均值后,大部分写 $XX^T$ 算协方差矩阵,这是默认以列为一个 vector,肯定要留神。
因为 torch 的一个向量是一个横行,所以自行实现其实是 $X^TX$

def torch_cov(input_vec:torch.tensor):    
    x = input_vec- torch.mean(input_vec,axis=0)
    cov_matrix = torch.matmul(x.T, x) / (x.shape[0]-1)
    return cov_matrix

这样子能够和 numpy 的 cov 比拟一下:

vecs=torch.tensor([[1,2,3,4],[2,2,3,4]]).float()
vecs_np=vecs.numpy()
cov = np.cov(vecs_np.T)
# 显示
array([[0.5, 0. , 0. , 0.],
       [0. , 0. , 0. , 0.],
       [0. , 0. , 0. , 0.],
       [0. , 0. , 0. , 0.]])
torch_cov(vecs)
# 显示
tensor([[0.5000, 0.0000, 0.0000, 0.0000],
        [0.0000, 0.0000, 0.0000, 0.0000],
        [0.0000, 0.0000, 0.0000, 0.0000],
        [0.0000, 0.0000, 0.0000, 0.0000]])

二者是一样的。

直面矩阵的数学解释

对于矩阵 \(M\)来说, 1 行为一个高维变量 \(x_i\) 该当示意成

$$
\left[\begin{matrix}
x_1\\ x_2\\ x_3\\
\end{matrix} \right]
$$

计算均值 \(\mu\),该当是对 \(x_i\)求 \(\mu\),$$\mu=\frac1N\sum_Nx_i$$ 所以 \(\mu\)也是一个高维(与 x 同维度)的向量。
\(M-\mu\)变换该当示意成

$$
X=\left[\begin{matrix}
x_1-\mu\\ x_2-\mu\\ x_3-\mu\\
\end{matrix} \right]=\left[\begin{matrix}
x_1’\\ x_2’\\ x_3’\\
\end{matrix} \right]
$$

咱们把变换后的 \(M\)写做 \(X\),变换后的 \(x_i\)写作 \(x’_i\)。
协方差矩阵 \(\Sigma\)的意义是各个维度之间互相的方差,则该当是

$$
\frac13X^TX=\frac13\left[\begin{matrix}
x_1′, x_2′, x_3’\\
\end{matrix} \right]\left[\begin{matrix}
x_1’\\ x_2’\\ x_3’\\
\end{matrix} \right]=\Sigma
$$

直观解释是这个乘法 \(\Sigma\)最左上角的元素,恰好是 \(x’_i\)第 1 维对第 1 维的自我方差,此时能够确认是正确意义的协方差矩阵。
当然,算完之后还要乘变量个 \(\frac13\)或者 \(\frac1{3-1}\)。

退出移动版