专栏首页王的机器小孩都看得懂的 SVD 2

小孩都看得懂的 SVD 2

  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 的工具包。

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 代表黑色。

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 打印出来检查它们的值。

print(np.round(U,2))
print()
sigma = np.diag(S)
print(np.round(sigma,2))
print()
print(np.round(V,2))
[[-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]]

例二:小心形图片

换一张小一点的心形图。

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 个 σ 都为零,从第四幅重叠图起也已经完美的还原原图了。

例三:十字形图片

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 工具包。

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),在最后一维,即在色道维度上求均值。

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 压缩图片咯。

本文分享自微信公众号 - 王的机器(MeanMachine1031),作者:王圣元

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2021-04-13

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 小孩都看得懂的 SVD

    奇异值分解 (singular value decomposition, SVD) 就是一个“旋转-拉缩-旋转”的过程。

    用户5753894
  • 小孩都看得懂的 GMM

    聚类 (clustering) 是无监督学习中的一种任务类型,将没有标准的数据“聚”在一起,“赋予”它们标签,其过程如下面两图所示。

    用户5753894
  • 小孩都看得懂的 p-value

    本文是「小孩都看得懂」系列的第九篇,本系列的特点是极少公式,没有代码,只有图画,只有故事。内容不长,碎片时间完全可以看完,但我背后付出的心血却不少。喜欢就好!

    用户5753894
  • 小孩都看得懂的聚类

    本文是「小孩都看得懂」系列的第四篇,本系列的特点是没有公式,没有代码,只有图画,只有故事。内容不长,碎片时间完全可以看完,但我背后付出的心血却不少。喜欢就好!

    用户5753894
  • 小孩都看得懂的假设检验

    本文是「小孩都看得懂」系列的第十篇,本系列的特点是极少公式,没有代码,只有图画,只有故事。内容不长,碎片时间完全可以看完,但我背后付出的心血却不少。喜欢就好!

    用户5753894
  • 小孩都看得懂的推荐系统

    我还是推荐系统小白,因此对此课题理解相当浅显,但一定很好懂。这才是学一样新东西的正确开始方式。

    用户5753894
  • 小孩都看得懂的主成分分析

    本文是「小孩都看得懂」系列的第五篇,本系列的特点是极少公式,没有代码,只有图画,只有故事。内容不长,碎片时间完全可以看完,但我背后付出的心血却不少。喜欢就好!

    用户5753894
  • 小孩都看得懂的循环神经网络

    神经网络其实就是一堆参数,我们用矩阵来表示这些参数好不好?具体公式见下图,大家来用矩阵乘以向量来验证一下上面两组联系。

    用户5753894
  • 小孩都看得懂的熵、交叉熵和 KL 散度

    本文是「小孩都看得懂」系列的第八篇,本系列的特点是极少公式,没有代码,只有图画,只有故事。内容不长,碎片时间完全可以看完,但我背后付出的心血却不少。喜欢就好!

    用户5753894
  • 小孩都看得懂的多臂老虎机和汤姆森采样

    多臂老虎机 (multi-armed bandit, MAB) 是赌场里的一种游戏。首先展示单臂老虎机。

    用户5753894
  • 机器学习集成算法:XGBoost思想

    《实例》阐述算法,通俗易懂,助您对算法的理解达到一个新高度。包含但不限于:经典算法,机器学习,深度学习,LeetCode 题解,Kaggle 实战。期待您的到来...

    double
  • 新手小白都能看得懂的HTTPS加密算法!看完即懂!

    说出来你可能不信,密钥这两个字的规范读音竟然是【mì yuè】,听起来像蜜月,哈哈。不过,在密码学的语境下,读作【 mì yào】的应该更多吧。扯远了,这集我们...

    张晓衡
  • 机器学习集成算法:XGBoost思想

    《实例》阐述算法,通俗易懂,助您对算法的理解达到一个新高度。包含但不限于:经典算法,机器学习,深度学习,LeetCode 题解,Kaggle 实战。期待您的到来...

    企鹅号小编
  • 新手都能看得懂的 ES6 Iterators

    本文旨在分析理解 Iterators。 Iterators 是 JS中的新方法,可以用来循环任意集合。 在ES6中登场的Iterators。因其可被广泛使用,并...

    前端小智@大迁世界
  • 机器学习实战 - 读书笔记(14) - 利用SVD简化数据

    绿巨人
  • 108个程序员的笑话,你都看得懂吗?

    1、程序猿最烦两件事,第一件事是别人要他给自己的代码写文档,第二件呢?是别人的程序没有留下文档。 2、程序猿的读书历程:x语言入门—>x语言应用实践—>x语言高...

    智能算法
  • 插画版Kubernetes指南(小孩子也能看懂的kubernetes教程)

    编者按:Matt Butcher 是 Deis 的平台架构师,热爱哲学,咖啡和精雕细琢的代码。有一天女儿走进书房问他什么是 Kubernetes,于是就有了这本...

    kubernetes中文社区
  • 常见面试算法:PCA、简化数据

    主成分分析(Principal Component Analysis, PCA):通俗理解:就是找出一个最主要的特征,然后进行分析。

    机器学习AI算法工程
  • 「漫画版」 小朋友都能看懂得 DevOops!不允许你有问号!

    DevOps消除了障碍,并减轻了开发人员和运营人员之间的紧张关系。革命性的DevOops!

    小小科

扫码关注云+社区

领取腾讯云代金券