前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >小孩都看得懂的 SVD 2

小孩都看得懂的 SVD 2

作者头像
用户5753894
发布2021-04-21 15:50:11
4800
发布2021-04-21 15:50:11
举报
文章被收录于专栏:王的机器王的机器
  1. 小孩都看得懂的神经网络
  2. 小孩都看得懂的推荐系统
  3. 小孩都看得懂的逐步提升
  4. 小孩都看得懂的聚类
  5. 小孩都看得懂的主成分分析
  6. 小孩都看得懂的循环神经网络
  7. 小孩都看得懂的 Embedding
  8. 小孩都看得懂的熵、交叉熵和 KL 散度
  9. 小孩都看得懂的 p-value
  10. 小孩都看得懂的假设检验
  11. 小孩都看得懂的基尼不纯度
  12. 小孩都看得懂的 ROC
  13. 小孩都看得懂的 SVD
  14. 小孩都看得懂的 SVD 2

0

回顾

奇异值分解 (singular value decomposition, SVD) 就是一个“旋转-拉缩-旋转”的过程。用下图来进一步说明:

用矩阵 A 一步做线性转换

等价于

用三个矩阵先旋转 (VT),再拉缩 (),最后旋转 (U),那么

A = U∑VT

本贴主要讲 SVD 在图片压缩上的应用。

1

公式可视化

将上面数学公式做可视化,旋转矩阵 U 用列向量表示,拉缩矩阵 ∑ 是只有对角线上有值,旋转矩阵 VT 用行向量表示,如下图所示:

两点需要留意:

  1. A 不一定是方阵(以上图举例, A 是 4×6,U 是 4×4, 是 4×6,VT 是 6×6,U∑VT 是 4×6)
  2. 中对角线上的值是从大到小排列的 σ1 ≥ σ2 ≥ σ3 ≥ σ4

进一步将 U∑VT 矩阵相乘分解成

  • 的对角线上第 i 个元素
  • U 的第 i 列
  • VT 的第 i 行

相乘来累加,可以得到矩阵 A。如下图展示:

上述分解可不仅仅在于将公式以另一种方式等价写出来,其意义是,如果某个“拉缩” σ 很小,比如 σ4,那么舍弃 σ4u4v4,也能近似还原 A

在实际图片压缩问题中,图片可用像素矩阵 A 表示,做完 SVD 后发现如果很多“拉缩” σ 很小,全部舍弃不久减少很多数据存储了吗?还能近似还原 A 不就对图片成功做了压缩处理的么?

下面来几个 SVD 实操,先来看最简单的例子,仅仅为了便于明晰 SVD 的原理;了解完全原理后,再用一张真实照片来做图片压缩。

首先引入必要的 Python 的工具包。

代码语言:javascript
复制
import numpy as np
from numpy.linalg import svd
import matplotlib as mpl
import matplotlib.pyplot as plt

2

简单例子

下面用于可视化 SVD 的代码在本帖会重复使用,对 Python 有兴趣的小朋友可以看看。代码主要做的事情就三件:

  1. 在图片像素矩阵上做 SVD
  2. 可视化出所有 σiuivi 的图
  3. 可视化出所有 σiuivi 的重叠图(比如第一张是 σ1u1v1,第二张是 σ1u1v1 + σ2u2v2 ...)

例一:心形图片

用 NumPy 数组表示图片,0 代表白色,1 代表黑色。

代码语言:javascript
复制
D = np.array([[0,1,1,0,1,1,0],
              [1,1,1,1,1,1,1],
              [1,1,1,1,1,1,1],
              [0,1,1,1,1,1,0],
              [0,0,1,1,1,0,0],
              [0,0,0,1,0,0,0],
             ])
U,S,V = plot_svd(D)

图片像素矩阵 D 做完 SVD 后得到的 对角线有 6 个值,最后两个是 0。

不难发现,从第四幅重叠图起就已经完美的还原原图了。

此外也可将 U, S, V 打印出来检查它们的值。

代码语言:javascript
复制
print(np.round(U,2))
print()
sigma = np.diag(S)
print(np.round(sigma,2))
print()
print(np.round(V,2))
代码语言:javascript
复制
[[-0.36 -0.   -0.73 -0.05  0.56  0.13]
 [-0.54  0.35  0.27 -0.08 -0.16  0.69]
 [-0.54  0.35  0.27 -0.08  0.16 -0.69]
 [-0.45 -0.35 -0.27  0.52 -0.56 -0.13]
 [-0.28 -0.71  0.18 -0.62 -0.   -0.  ]
 [-0.08 -0.35  0.46  0.57  0.56  0.13]]

[[4.74 0.   0.   0.   0.   0.  ]
 [0.   1.41 0.   0.   0.   0.  ]
 [0.   0.   1.41 0.   0.   0.  ]
 [0.   0.   0.   0.73 0.   0.  ]
 [0.   0.   0.   0.   0.   0.  ]
 [0.   0.   0.   0.   0.   0.  ]]

[[-0.23 -0.4  -0.46 -0.4  -0.46 -0.4  -0.23]
 [ 0.5   0.25 -0.25 -0.5  -0.25  0.25  0.5 ]
 [ 0.39 -0.32 -0.19  0.65 -0.19 -0.32  0.39]
 [-0.22  0.42 -0.44  0.42 -0.44  0.42 -0.22]
 [ 0.56 -0.43  0.03  0.   -0.03  0.43 -0.56]
 [-0.42 -0.55 -0.16  0.    0.16  0.55  0.42]
 [-0.12 -0.11  0.69 -0.   -0.69  0.11  0.12]]

例二:小心形图片

换一张小一点的心形图。

代码语言:javascript
复制
D = np.array([[0,0,0,0,0,0,0,0,0],
              [0,0,1,1,0,1,1,0,0],
              [0,1,1,1,1,1,1,1,0],
              [0,1,1,1,1,1,1,1,0],
              [0,0,1,1,1,1,1,0,0],
              [0,0,0,1,1,1,0,0,0],
              [0,0,0,0,1,0,0,0,0],
              [0,0,0,0,0,0,0,0,0]
             ])
U,S,V = plot_svd(D)

最后 4 个 σ 都为零,从第四幅重叠图起也已经完美的还原原图了。

例三:十字形图片

代码语言:javascript
复制
D = np.array([[0,0,1,1,0,0],
              [0,1,1,1,1,0],
              [1,1,1,1,1,1],
              [1,1,1,1,1,1],
              [0,1,1,1,1,0],
              [0,0,1,1,0,0],
             ])
U,S,V = plot_svd(D)

最后 3 个 σ 都为零,从第三幅重叠图起也已经完美的还原原图了。

弄清楚以上 SVD 分解原理后,最后看一个实际例子。先引入必要的 Python 工具包。

代码语言:javascript
复制
import os
from matplotlib.image import imread
mpl.rcParams['font.sans-serif'] = ['Microsoft YaHei']
mpl.rcParams['axes.unicode_minus'] = False

3

真实例子

设置正确路径,从文件夹中用 imread() 函数读取图片并转成像素,该图片是彩照,有 RGB 三个色道。为了仅说明压缩过程,用黑白图片即可,因此将彩照转成黑白照, np.mean(A, -1),在最后一维,即在色道维度上求均值。

代码语言:javascript
复制
file = os.getcwd() + '\\niannian.jpg'
A = imread(file)
X = np.mean(A, -1); # Convert RGB to grayscale

plt.rcParams['figure.figsize'] = [16, 8]
img = plt.imshow(X)
img.set_cmap('gray')
plt.axis('off')
plt.show()

该图片矩阵尺寸很大,我们就看保留前 100,200 和 500 个 σiuivi 的图片长什么样,代码如下:

将结果整理成一排好比较,我们发现用前 500 个特征值已经能基本还原原图了,用 100 个特征值效果也不差,而且仅仅只用了原图 5.79% 的存储量,大大压缩了图片。

打印出特征个数和累计能量值发现,前 100 个特征已经还原 70% 原图,前 500 个特征已经还原 90% 原图,后面 2500 个特征只能贡献 10% 的还原度。这样根据个人的“还原原图”的需求,选取一个合适特征数量,舍弃后面的特征即可。

小朋友们,现在你们可以在自己电脑里找照片,将下图高亮处改成“照片名称和格式”就可以自己玩玩用 SVD 压缩图片咯。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-04-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 王的机器 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
文件存储
文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档