学习总结
文章目录
- 学习总结
- 一、三角分解(LU分解)
- 1.1 高斯消元
- 1.2 LU分解原理
- 1.3 LU分解python代码
- 1.4 LU分解算法
- 二、QR分解
- 2.1 Schmid 正交化
- 2.2 使用 Schmid 施密特正交化过程求 QR 分解
- 2.3 QR分解的栗子
- 三、SVD分解
- 3.1 SVD定义
- 3.2 SVD基本理论
- (1)线性变换
- (2)SVD推导(略)
- (3)SVD栗子
- 四、SVD图像压缩
- 五、SVD手写体识别
- Reference
一、三角分解(LU分解)
1.1 高斯消元
1.2 LU分解原理
1.3 LU分解python代码
1.4 LU分解算法
二、QR分解
2.1 Schmid 正交化
2.2 使用 Schmid 施密特正交化过程求 QR 分解
2.3 QR分解的栗子
三、SVD分解
3.1 SVD定义
Singular Value Decomposition。
SVD是一种基于矩阵分解的,提取信息的强大工具,能够发现数据中的潜在模式。应用领域比如:
- 隐性语义分析 (Latent Semantic Analysis, LSA) 或隐性语义索引 (Latent Semantic Indexing, LSI);
- 推荐系统 (Recommender system),可以说是最有价值的应用点(不过现在推荐系统很多都是基于深度学习模型);
- 矩阵形式数据(主要是图像数据)的压缩。
3.2 SVD基本理论
(1)线性变换
以2×2的线性变换矩阵为例,现在有一个对角矩阵
M
=
[
3
0
0
1
]
M=\left[\begin{array}{ll}3 & 0 \\ 0 & 1\end{array}\right]
M=[3001]
对角矩阵M是将二维平面上的点(x,y)经过线性变换到另一个点的变换矩阵(变换效果:平面沿着x水平方向进行3倍拉伸,垂直方向没变化): [ 3 0 0 1 ] [ x y ] = [ 3 x y ] \left[\begin{array}{ll} 3 & 0 \\ 0 & 1 \end{array}\right]\left[\begin{array}{l} x \\ y \end{array}\right]=\left[\begin{array}{c} 3 x \\ y \end{array}\right] [3001][xy]=[3xy]
(2)SVD推导(略)
从几何角度理解二维SVD:借助SVD可将一个相互垂直的网络(orthogonal grid)变换到另一个互相垂直的网络。
实际应用中,我们仅需保留着三个比较小的矩阵,就能表示A,不仅节省存储量,在计算的时候更是减少了计算量。SVD在信息检索(隐性语义索引)、图像压缩、推荐系统、金融等领域都有应用。
(3)SVD栗子
其中正交矩阵的特征值和特征向量的求解可以复习线性代数。
四、SVD图像压缩
(1)下载cv2
:pip install opencv-python
。
(2)其中np.linalg.svd(a, full_matrices=1, compute_uv=1)
函数:
-
input参数:
a
是一个形如(M,N)矩阵full_matrices
的取值是为0或者1,默认值为1,这时u的大小为(M,M),v的大小为(N,N) 。否则u的大小为(M,K),v的大小为(K,N) ,K=min(M,N)。compute_uv
的取值是为0或者1,默认值为1,表示计算u,s,v。为0的时候只计算s。
-
output参数(三个):
- u大小为(M,M),s大小为(M,N),v大小为(N,N)。
- A = usv
- 其中s是对矩阵a的奇异值分解。s除了对角元素不为0,其他元素都为0,并且对角元素从大到小排列。s中有n个奇异值,一般排在后面的比较接近0,所以仅保留比较大的r个奇异值。
(3)numpy.stack
函数:将多个数组进行堆叠,按照指定的维度,可参考博客。
# -*- coding: utf-8 -*-
"""
Created on Sat Dec 11 23:14:35 2021
@author: 86493
"""
import cv2
import matplotlib as mpl
import numpy as np
import matplotlib.pyplot as plt
#转为u8类型
def restore1(u, sigma, v, k):
m = len(u)
n = len(v)
a = np.zeros((m, n))
a = np.dot(u[:, :k], np.diag(sigma[:k])).dot(v[:k, :])
# s1 = np.size(u[:, :k])
# s1+= np.size(np.diag(sigma[:k]))
# s1+= np.size(np.diag(v[:k, :]))
# s2 = np.size(a)
# print("压缩率:",s1/s2)
a[a < 0] = 0
a[a > 255] = 255
return np.rint(a).astype('uint8')
def SVD(frame,K=10):
a = np.array(frame)
#由于是彩色图像,所以3通道。a的最内层数组为三个数,分别表示RGB,用来表示一个像素
u_r, sigma_r, v_r = np.linalg.svd(a[:, :, 0])
u_g, sigma_g, v_g = np.linalg.svd(a[:, :, 1])
u_b, sigma_b, v_b = np.linalg.svd(a[:, :, 2])
R = restore1(u_r, sigma_r, v_r, K)
G = restore1(u_g, sigma_g, v_g, K)
B = restore1(u_b, sigma_b, v_b, K)
I = np.stack((R, G, B), axis = 2)
return I
if __name__ == "__main__":
mpl.rcParams['font.sans-serif'] = [u'simHei']
mpl.rcParams['axes.unicode_minus'] = False
# frame = cv2.imread("./liuyifei.bmp",-1)
frame = cv2.imread("pig.jpg",-1)
I = SVD(frame,40)
plt.imshow(I)
cv2.imwrite("out.bmp",I)
原图为:
图像压缩后的图为:
五、SVD手写体识别
Reference
(1)SVD-矩阵奇异值分解 —— 原理与几何意义
(2)SVD应用于图像压缩 Python代码测试
(3)https://www.zhihu.com/question/277311874
(4)矩阵的SVD分解(应用之一:手写数字识别)
(5)浅谈SVD原理以及python实现小demo
(6)SVD(奇异值分解)Python实现(原理清晰)