【机器学习算法】奇异值分解(SVD)

news2024/12/24 20:15:09

文章目录

  • 奇异值分解(SVD)
    • 1.理论部分
      • 1.1特征分解(ED)
      • 1.2 奇异值分解(SVD)
        • 求解U和V
        • 求解Σ
    • 2.应用部分
      • 2.1图像压缩
      • 2.2图像数据集成分分析
      • 2.3 数据降维(PCA的一种解法)
    • Reference

奇异值分解(SVD)

在这里插入图片描述

奇异值分解(Singular Value Decomposition) 是矩阵低秩分解的一种方法,在机器学习领域具有广泛的应用。它不光可以用于图像压缩,降维算法中的特征分解,还可以用于推荐系统,以及自然语言处理等领域。是许多机器学习算法的基石。
本篇博客中所有的可视化及数据预处理代码已上传至github:
Machine-Learning/SVD_PCA at main · Scienthusiasts/Machine-Learning (github.com)

1.理论部分

鉴于逻辑的连贯性,在搞清楚什么是奇异值分解之前,我们先来聊聊矩阵的特征分解

1.1特征分解(ED)

我们知道,任何矩阵都有特征值和特征向量,它们的定义如下:
A ξ = λ ξ A \xi=\lambda \xi Aξ=λξ
其中λ是A的特征值,ξ是A的特征向量。

现在我们假设A为n阶方阵,并且有n个特征值,对应n个线性无关的特征向量,我们求出A的n个特征值和特征向量,并将这n个特征值按从大到小的顺序排列,构成对角阵Λ,相应的,将n个特征向量构成一个可逆矩阵P,即:
Λ = [ λ 1 ⋯ 0 ⋮ ⋱ ⋮ 0 ⋯ λ n ] , P = [ ξ 1 ⋯ ξ n ] \Lambda=\left[\begin{array}{ccc} \lambda_1 & \cdots & 0 \\ \vdots & \ddots & \vdots \\ 0 & \cdots & \lambda_n \end{array}\right], \mathrm{P}=\left[\xi_1 \cdots \xi_{\mathrm{n}}\right] Λ= λ100λn ,P=[ξ1ξn]
则有:
A P = P Λ ⇒ A = P Λ P − 1 \mathrm{AP}=\mathrm{P} \Lambda \Rightarrow \mathrm{A}=\mathrm{P} \Lambda \mathrm{P}^{-1} AP=PΛA=PΛP1
进一步地,我们将A的n个特征向量标准正交化,即P是一个正交矩阵,则有:
A = P Λ P T \mathrm{A}=\mathrm{P} \Lambda \mathrm{P}^{T} A=PΛPT
这样一来,我们便将一个方阵A分解成为了一个对角阵和一个正交阵,相信大家对此都非常的熟悉,因为这就是方阵的相似对角化,只不过研究的领域不同,叫法也有所差异。

值得一提的是,上面这种形式还可以写成:
A = ∑ i = 1 n λ i ξ i T ξ i \mathrm{A}=\sum_{\mathrm{i}=1}^{\mathrm{n}} \lambda_{\mathrm{i}} \xi_{\mathrm{i}}^{\mathrm{T}} \xi_{\mathrm{i}} A=i=1nλiξiTξi
注意到ξᵀξ是一个秩为1的和A同样大小的矩阵,这就相当于:我们可以通过n个秩为1的方阵,通过加权(λᵢ)求和的方式,还原出原始矩阵A

我们可以顺便从图像的角度来理解,假设图像的尺寸为nxn大小。图像的秩为为n,那么,我们就可以通过特征分解将图像分解为n个秩为1的子图像,通过对这n个子图像加权求和,不断升高图像的秩,我们就可以逐渐还原出原始图像。

(因为ξᵢ线性无关,所以每加一次,图像矩阵的秩+1)

到这里,虽然还没引出奇异值分解,我想各位也已经对奇异值分解有一个模糊的认知了,因为特征分解就是奇异值分解当A为方阵的特殊情况。换句话说,奇异值分解更进一步适用于非方阵矩阵的情况。

1.2 奇异值分解(SVD)

考虑到矩阵的特征分解有以下几个局限性:

1.矩阵必须是方阵

2.矩阵属于同一特征值的两个特征向量线性无关。

除此之外,考虑到实际中非方阵才是更普遍的情况,因此SVD相比ED是更为通用的矩阵分解方法,但其推导过程中依然会用到特征分解。

我们首先给出SVD分解的结论,再来进一步进行推导,这样会更容易理解。

SVD分解的定义是,任意给定nxm大小的矩阵X,都可以将其分解为X=UΣVᵀ的形式,其中U是nxn大小的矩阵,Vᵀ是mxm大小矩阵,U和V均为正交矩阵(酉矩阵),既满足UUᵀ = VVᵀ = E(单位阵)。而Σ是一个对角矩阵,Σ对角元素为X的奇异值(非负数),其中的非零元素个数为X的秩的大小
A = U Σ V T A=U \Sigma V^T A=UΣVT

求解U和V

下面给出求解U和V的方法:

首先求解V,我们需要构造AᵀA,此时AᵀA是一个实对称矩阵,必然可以进行特征分解,AᵀA的单位特征向量就是V矩阵,因此问题转化为对AᵀA做特征分解:
A T A = V Σ U T U Σ V T = V Σ 2 V T A^T A=V \Sigma U^T U \Sigma V^T=V \Sigma^2 V^T ATA=VΣUTUΣVT=VΣ2VT
同理U:XXᵀ的单位特征向量就是U矩阵
A A T = U Σ V T V Σ U T = U Σ 2 U T A A^T=U \Sigma V^T V \Sigma U^T=U \Sigma^2 U^T AAT=UΣVTVΣUT=UΣ2UT
值得注意的是,r(AᵀA)=r(AAᵀ), 因此r(U)=r(V),尽管他们的尺寸不同。

对于Σ,需要注意的是,为了满足UΣVᵀ能够相乘,Σ的尺寸应为nxm,但是由于Σ大多情况下并不满秩,因此我们只考虑Σ的尺寸为其对角线上非零元素的个数,这个个数就是X的秩的大小。

求解Σ

Σ的求法有两种,一种是通过求解AᵀA或AAᵀ的非零特征值的算数平方根(因为奇异值非负),它们的结果应该是一样的(不用应该)。

另一种求法如下,待求解出V和U之后,AV与U每一列的比例系数都是一个奇异值
A = U Σ V T ⇒ A V = U Σ V T V ⇒ A V = U Σ ⇒ A v i = σ i u i ⇒ σ i = A v i / u i A=U \Sigma V^T \Rightarrow A V=U \Sigma V^T V \Rightarrow A V=U \Sigma \Rightarrow A v_i=\sigma_i u_i \Rightarrow \sigma_i=A v_i / u_i A=UΣVTAV=UΣVTVAV=UΣAvi=σiuiσi=Avi/ui
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-P7g9XPa1-1689527236057)(.\2.png)]

2.应用部分

SVD分解的U矩阵的每一列称作左奇异向量,Vᵀ矩阵的每一行被称作右奇异向量,Σ的每一个对角元素是一个奇异值。
U = [ u 1 , u 2 , ⋯   , u n ] , V T = [ v 1 T v 2 T ⋮ v m T ] , Σ = [ σ 1 ⋯ 0 ⋮ ⋱ ⋮ 0 ⋯ σ m ] U=\left[u_1, u_2, \cdots, u_n\right], \quad V^T=\left[\begin{array}{c} v_1^T \\ v_2^T \\ \vdots \\ v_m^T \end{array}\right], \Sigma=\left[\begin{array}{ccc} \sigma_1 & \cdots & 0 \\ \vdots & \ddots & \vdots \\ 0 & \cdots & \sigma_m \end{array}\right] U=[u1,u2,,un],VT= v1Tv2TvmT ,Σ= σ100σm
同特征分解类似,SVD分解的形式还可以表示如下:
A = U Σ V T = ∑ i = 1 m σ i u i v i T A=U\Sigma V^T=\sum_{\mathrm{i}=1}^{\mathrm{m}} \sigma_{\mathrm{i}} u_{\mathrm{i}} v_{\mathrm{i}}^{\mathrm{T}} A=UΣVT=i=1mσiuiviT
可以注意到,uiviᵀ是一个列向量乘以一个行向量,结果是一个尺寸同A的秩为1的成分矩阵,而σ可以理解为该成分构成A的重要程度。依据这个,我们就可以通过抛弃不显著的σ来进行矩阵的低秩近似。比如说,我们可以通过只取前k大的奇异值和左右奇异向量来对原始矩阵A进行近似

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZYjueLaU-1689527236058)(.\3.png)]

2.1图像压缩

低秩近似的一个经典应用就是图像压缩,给定一张图像,图像中可能包含噪声,通过SVD分解将图像的秩压缩到K来近似拟合原始图像。

(1) 以MNIST数据集为例,选取一张手写数字5的图像,对其进行奇异值分解得到的可视化结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-prRRq3Cp-1689527236058)(.\4.png)]

对原始图像进行低秩近似。随着图像的秩不断升高,低秩矩阵会越来越逼近原始图像(从秩=1到秩=25):

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pharxOro-1689527236058)(.\5.png)]

(2) 以celeba_hq数据集为例,选取一张人脸图像,对其进行奇异值分解得到的可视化结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nhhyF4mr-1689527236058)(.\6.png)]

对原始图像进行低秩近似(从秩=1到秩=64):

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Jai8wUii-1689527236058)(.\7.png)]

值得注意的是,当图像尺寸为nxm时,用秩=k去近似原图像,k需满足以下关系,才能真正实现压缩:
n m > n k + m k + k ⇒ n m > ( n + m + 1 ) k ⇒ k < n m n + m + 1 \begin{aligned} \mathrm{nm} & >\mathrm{nk}+\mathrm{mk}+\mathrm{k} \\ \Rightarrow\mathrm{nm} & >(\mathrm{n}+\mathrm{m}+1) \mathrm{k} \\ \Rightarrow\mathrm{k} & <\frac{\mathrm{nm}}{\mathrm{n}+\mathrm{m}+1} \end{aligned} nmnmk>nk+mk+k>(n+m+1)k<n+m+1nm
再举一个RGB图像压缩的例子:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-c3tXDeBn-1689527236058)(.\8.png)]

2.2图像数据集成分分析

在2.1的例子中,我们只对单张图像进行了分析,在本节中,我们试着批量导入celeba_hq人脸数据集,将每张图像压缩为一维向量,以行向量存储的方式存储在数据矩阵A中。通过可视化右奇异向量,我们可以获得图像数据集的各个成分的信息

(值得注意的是,SVD归根结底仍然是线性分析方法,对于提取数据中的非线性特征不敏感,因此采集的数据集必须避免光照,尺度,空间变化等非线性变换。celeba_hq数据集包含30000张图像,其中的人脸大多为正脸且分布在图像正中央,特别适合采用SVD方法进行成分分析)

数据集链接:[CelebA Dataset (cuhk.edu.hk)](https://github.com/switchablenorms/CelebAMask-HQ)

resize为64x64大小的celeba_hq人脸数据集(部分):

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ToXpPcM4-1689527236059)(.\9.png)]

数据集前64个主成分分析(每一张成分图像都是VT中的一行行向量),其中越靠前的成分越能代表一张人脸的普遍特征:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9cay966w-1689527236059)(.\10.png)]

同样的,利用SVD分解得到的三个矩阵,任意一张数据集中的人脸图像都可以通过成分之间的加权组合来生成,如下图所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cjKZRHEt-1689527236059)(.\11.png)]

上图也可以用一个更为直观的公式来描述:
F = ∑ i = 1 n α i F i F=\sum_{i=1}^n \alpha_i F_i F=i=1nαiFi
其中:F是一张新生成的脸部图像

Fi是一个EigenFace(特征脸,即每一个成分)

αi是表示每一个成分的系数,可正可负

可视化单张图像的成分分析(随着成分的不断叠加,结果越来越逼近目标图像):

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4qH94BHR-1689527236059)(.\12.png)]

2.3 数据降维(PCA的一种解法)

详细请看另一篇博客:【机器学习算法】主成分分析(PCA)

Reference

Face Reconstruction using EigenFaces

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/761210.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

太猛了!Web安全漏洞批量扫描框架

关注【Hack分享吧】公众号&#xff0c;回复关键字【230528】获取下载链接 工具介绍 一个应用于web安全领域的漏洞批量扫描框架&#xff0c;可被应用于但不限于如下场景&#xff1a; 0Day/1Day全网概念验证(在没有测试环境(各种商业、闭源软件)或懒得搭建测试环境的情况下&…

D. Binary String Sorting

Problem - 1809D - Codeforces 思路&#xff1a;最后得到的结果就是前面是一串0后面是一串1&#xff0c;那么我们可以枚举分界点&#xff0c;如果枚举到i&#xff0c;那么就将1~i变为0&#xff0c;将i1变为1,我们发现如果一个1在1~i中&#xff0c;如果他是第i-1个&#xff0c;那…

Redis进阶底层原理-Cluster集群底层

Redis实现高可用的方案有很多中&#xff0c;先了解下高可用和分区的概念&#xff1a; 高可用是指系统在面对硬件故障、网络故障、软件错误等意外问题时&#xff0c;仍能给客户端提供正常的服务&#xff0c;尽量的减少服务的阻塞、终端现象。在高可用的方案中一般会采用冗余备份…

《洛谷深浅》第五章---数组与数据批量存储

文章目录 前言一、小鱼比可爱二、小鱼的数字游戏三、冰雹猜想四、校门外的树五、旗鼓相当的对手六、旗鼓相当的对手总结 前言 本节主要学习一维数组 和 多维数组 后边的知识我觉得 可以试着了解并不要求你掌握这么难的题目 因为ACM更多都是思维题目 所以这里把重要的题目掌握就…

【多线程系列-03】深入理解java中线程的生命周期,任务调度

多线程系列整体栏目 内容链接地址【一】深入理解进程、线程和CPU之间的关系https://blog.csdn.net/zhenghuishengq/article/details/131714191【二】java创建线程的方式到底有几种&#xff1f;(详解)https://blog.csdn.net/zhenghuishengq/article/details/127968166【三】深入…

基于树莓派实现的IO-Link 项目

IO-Link 协议 &#xff08;IEC 61131-9&#xff09; 是从传感器或执行器到 IO-Link 主站的串行半双工点对点连接。目前IO-Link 的硬应已经越来越普及。国外产品以巴鲁夫为代表。如何开发IO-link 产品&#xff1f;可以参考国外的一些开源项目。 国外有人开发了开发一个IO-Link主…

soundfile torchaudio 读取音频文件

soundfile 和 torchaudio 读取音频文件后的数据格式不同&#xff0c;前者是numpy&#xff0c;后者是tensor。前者读取后可以直接用于一些python的基础函数输入&#xff0c;后者用于pytorch的一些函数的应用。两者互换用途时候需要进行格式转换。 import soundfile as sf impor…

智能指针使用及详细解析

文章目录 智能指针概念为什么使用智能指针智能指针使用智能指针的常用函数get() 获取智能指针托管的指针地址.reset() 重置智能指针托管的内存地址&#xff0c;如果地址不一致&#xff0c;原来的会被析构掉 auto_ptrunique_ptrshared_ptr**shared_ptr的原理**引用计数的使用构造…

Gradle 构建工具 #5 又冲突了!如何理解依赖冲突与版本决议?

⭐️ 本文已收录到 AndroidFamily&#xff0c;技术和职场问题&#xff0c;请关注公众号 [彭旭锐] 和 [BaguTree Pro] 知识星球提问。 Gradle 作为官方主推的构建系统&#xff0c;目前已经深度应用于 Android 的多个技术体系中&#xff0c;例如组件化开发、产物构建、单元测试等…

STM32(HAL库)驱动SHT30温湿度传感器通过串口进行打印

目录 1、简介 2、CubeMX初始化配置 2.1 基础配置 2.1.1 SYS配置 2.1.2 RCC配置 2.2 软件IIC引脚配置 2.3 串口外设配置 2.4 项目生成 3、KEIL端程序整合 3.1 串口重映射 3.2 SHT30驱动添加 3.3 主函数代 3.4 效果展示 1、简介 本文通过STM32F103C8T6单片机通过HAL库…

Spring Batch之读数据库——JdbcCursorItemReader之自定义RowMapper(三十七)

一、自定义RowMapper 详情参考我的另一篇博客&#xff1a; Spring Batch之读数据库——JdbcCursorItemReader&#xff08;三十五&#xff09;_人……杰的博客-CSDN博客 二、项目实例 1.项目框架 2.代码实现 BatchMain.java: package com.xj.demo28;import org.springfram…

代码随想录第27天 | 455.分发饼干 ● 376. 摆动序列 ● 53. 最大子序和

455.分发饼干 /*** param {number[]} g* param {number[]} s* return {number}*/ var findContentChildren function(g, s) {let a0let b0let count0g.sort((a,b)>a-b)s.sort((a,b)>a-b)while(a<g.length&&b<s.length){if(s[b]>g[a]){countba}else{b}…

STM32(HAL库)软件IIC驱动OLED

目录 1、简介 2、CubeMX初始化配置 2.1 基础配置 2.1.1 SYS配置 2.1.2 RCC配置 2.2 软件IIC引脚配置 2.3 项目生成 3、KEIL端程序整合 3.1 OLED驱动添加 3.3 主函数代 3.4 效果展示 1、简介 本文通过STM32F103C8T6单片机&#xff08;HAL库&#xff09;通过软件IIC方式…

java linux服务器环境搭建

安装 jdk 下载jdk: wget --no-cookies --no-check-certificate --header "Cookie: gpw_e24http%3A%2F%2Fwww.oracle.com%2F; oraclelicenseaccept-securebackup-cookie" "http://download.oracle.com/otn-pub/java/jdk/8u141-b15/336fa29ff2bb4ef291e347e091f7f…

Kubespray v2.22.1 在线部署 kubernetes v1.26.5 集群

文章目录 1. 介绍2. 预备条件3. 配置 hostname4. yum5. 下载介质5.1 git 下载5.2 下载 kubespray v2.22.1 6. 编写 inventory.ini7. 配置互信8. 安装 ansible9. 关闭防火墙10. 安装 docker11. 配置内核参数12. 启动容器 kubespray13. 部署14. 配置连接集群 1. 介绍 kubespray​…

Ubuntu18.04 安装vscode 配置C#编译器

环境&#xff1a; ubuntu 18.04 依赖库&#xff1a; SDK .net-7 安装对象&#xff1a; vscode 在终端&#xff1a; ./dotnet-install.sh --channel 7.0 遇见如下提示&#xff1a; dotnet&#xff1a;未找到命令 如下操作&#xff1a; 下载–解压–安装 wget https://pa…

Python 自学 day04 函数为参数传递, 匿名函数, 文件操作

1. 函数作为参数传递 &#xff08;类似C 函数指针&#xff09; def func(x):mm x(1,2);#print(f"mm的值是{mm}")return mmdef add(x,y): #加法return xy def reduce(x,y): # 减法return x-ydef ride(x,y): # 乘法return x*ydef divide(x,y): #带有小数点除法…

详解DDPG算法:解决对大量的超参数、随机重启、任务环境敏感问题,完成月球着陆器,双足机器人demo、以及超参数调优教学

0.demo展示 当我复现强化学习算法 DDPG 时,我发现论文中缺少必要的实现细节,例如:Gamma、噪声方差、最大训练步数等参数的取值。此外,在我调整参数,成功完成某次训练后,当我对随机种子进行修改,发现训练时长有很大变化,甚至有时候无法完成训练。更别提把在某个任务上 w…

1、linux中安装tomcat

1、创建目录 cd /opt ls mkdir tomcat 2、将文件拖入tomcat目录中 3、解压安装包 cd /opt/tomcat ls tar -zxvf apache-tomcat-8.5.59.tar.gz 4、启动tomcat cd /opt/tomcat/apache-tomcat-8.5.59/bin ./startup.sh 5、在linux中访问 http://localhost:8080/ 6、开放端口 …

为什么选择孟德尔随机化来写文章

为什么选择孟德尔随机化来写文章