奇异值分解——学习笔记

原本在看这篇论文,Information-theoretical label embeddings for large-scale image classification。

发邮件想问问可以不可分享代码,这是作者回信提到的

I don't have any of that code anymore. But the code for computing PMI-SVD embeddings is basically just a few lines of numpy. The code for training an image model is just regular Keras. There is nothing complicated or magic.

If occ is a vector counting label occurences, coocc is a matrix counting cooccurences, and cardinal is the total number of occurences, then the embedding code is:

pmi = cardinal * coocc / (np.dot(occ, occ.T) + 10e-5)
pmi[coocc > 0.] = np.log(pmi[coocc > 0.])
pmi[coocc == 0.] = 0.
u, s, _ = np.linalg.svd(pmi)
sigma = np.eye(len(s)) * np.sqrt(s)  
embeddings = np.dot(u, sigma[:dim].T)

其中PMI(pointwise mutual information ) 中用到了奇异值分解。


这是论文里的相关描述

奇异值分解——学习笔记_第1张图片
论文截图

于是想找找关于奇异值分解的文章,在知乎找到了这个答案

答案里说到了秩为1的矩阵,于是又去找了几篇文章重温一下秩是什么。
http://blog.csdn.net/u011240016/article/details/52811606
http://blog.csdn.net/u011240016/article/details/52926635
http://blog.csdn.net/u011240016/article/details/52805663
http://blog.csdn.net/u011240016/article/details/53386184
http://blog.csdn.net/u011240016/article/details/52869027

总的来说,组成矩阵的线性无关的向量个数
比如说下面的矩阵,


第二行和第三行都能用第一行乘某个数字得到,即线性无关(独立)的向量个数是1,即秩是1。
而对于一个秩为1的矩阵,常常给定的是一个列向量与自己的转置之积。
而这种秩是1的矩阵有一个特性,就是能分解成两个矩阵之积。
奇异值分解——学习笔记_第2张图片


好了,重温完了关于矩阵和秩的内容,回到知乎看完了关于奇异值分解的答案,明白了sigma其实就是奇异值,而且是按照从大到小排列的。

不过看完了还是不知道原论文中


论文截图

分解后的三个矩阵为什么这么写。因为最后一个应该是Vt才对,和Ut没什么关系。

这篇文章有一些图很棒,画出了分解后的三个矩阵,方便理解。

奇异值分解——学习笔记_第3张图片
文章截图

下面是用numpy里的而np.linalg.svd试了一下。下面的写法表示维度。2*3表示2维*3维。

A=2*3
U = 2*2
sigma = 2*2
VT = 2*3

可是发现维度是对不上的,sigma本来应该跟A矩阵的大小2*3一样,但linalg.svd()只返回了一个行向量的sigma,并且只有2个奇异值(本来应该有3个),这是因为第三个奇异值为0,舍弃掉了。之所以这样做,是因为当A是非常大的矩阵时,只返回奇异值可以节省很大的存储空间。

奇异值分解——学习笔记_第4张图片

接下来试着用这三个矩阵再重组得到A。
sigma是奇异值,先变成奇异值矩阵。变为矩阵后,再加[0, 0]列。这样维度就都符合了

奇异值分解——学习笔记_第5张图片

然后就是 U*dia_sigma*VT。不过必须用np.dot()才是矩阵乘法。复原得到了A。

你可能感兴趣的:(奇异值分解——学习笔记)