1:SVD算法

1.1 算法原理

奇异值分解(SVD)是线性代数中一种重要的矩阵分解。假设M是一个m×n阶矩阵,其中的元素全部属于域K,也就是实数域或复数域。如此则存在一个分解使得M=UΣV∗M=UΣV^*M=UΣV∗
其中U是m×m阶酉矩阵;Σ是m×n阶非负实数对角矩阵;而V*,即V的共轭转置,是n×n阶酉矩阵。这样的分解就称作M的奇异值分解。Σ对角线上的元素Σi,i即为M的奇异值。常见的做法是将奇异值由大而小排列。如此Σ便能由M唯一确定了。(虽然U和V仍然不能确定。)
在矩阵M的奇异值分解中M=UΣV∗M=UΣV^*M=UΣV∗
V的列组成一套对M正交输入或分析的基向量,这些向量是MM的特征向量;
U的列组成一套对M的正交输出的基向量,这些向量是MM
的特征向量;
Σ对角线上的元素是奇异值,可视为是在输入和输出间进行的标量的‘膨胀控制’,这些是MM及MM的特征值的非负平方根,并与U和V的行向量相对应
奇异值和奇异向量,以及他们与奇异值分解的关系
一个非负实数σ是M的一个奇异值仅当存在Km的单位向量u和Kn的单位向量v如下:

其中向量u和v分别为σ的左奇异向量和右奇异向量。
对于任意的奇异值分解M=UΣV∗M=UΣV^*M=UΣV∗
矩阵Σ的对角线上的元素等于M的奇异值. U和V的列分别是奇异值中的左、右奇异向量。因此,上述定理表明:
一个m×n的矩阵至多有p = min(m,n)个不同的奇异值;
总能在Km中找到由M的左奇异向量组成的一组正交基U,;
总能在Kn找到由M的右奇异向量组成的一组正交基V,。
如果对于一个奇异值,可以找到两组线性无关的左(右)奇异向量,则该奇异值称为简并的(或退化的)。
非退化的奇异值在最多相差一个相位因子e(j∅)e^(j∅)e(j∅)(若讨论限定在实数域内,则最多相差一个正负号)的意义下具有唯一的左、右奇异向量。因此,如果M的所有奇异值都是非退化且非零,则除去一个可以同时乘在 U , V上的任意的相位因子外, M的奇异值分解唯一。
根据定义,退化的奇异值具有不唯一的奇异向量。因为,如果u1和u2为奇异值σ的两个左奇异向量,则它们的任意归一化线性组合也是奇异值σ一个左奇异向量,右奇异向量也具有类似的性质。因此,如果M具有退化的奇异值,则它的奇异值分解是不唯一的。

1.2 编程实现

先对cifar-10数据集进行奇异值分解,然后分别选择10,50,100维特征重构数据集(本实验中是一个1000*3072的矩阵)
重构出的矩阵reconstruct为
均方误差为
10维特征重建的均方误差为1742,50维特征重建的均方误差为777,100维特征重建的均方误差为458

2:字典学习算法

2.1 算法原理

算法求解思路为交替迭代的进行稀疏编码和字典更新两个步骤. K-SVD在构建字典步骤中,K-SVD不仅仅将原子依次更新,对于原子对应的稀疏矩阵中行向量也依次进行了修正. 不像MOP,K-SVD不需要对矩阵求逆,而是利用SVD数学分析方法得到了一个新的原子和修正的系数向量.
固定系数矩阵X和字典矩阵D,字典的第k个原子为dk,同时dk对应的稀疏矩阵为X中的第k个行向量xkT. 假设当前更新进行到原子dk,样本矩阵和字典逼近的误差为:
在得到当前误差矩阵EkE_kEk​后,需要调整dkd_kdk​和XkTX_{kT}XkT​,使其乘积与Ek的误差尽可能的小.如果直接对dkd_kdk​和XkTX_{kT}XkT​进行更新,可能导致XkTX_{kT}XkT​不稀疏. 所以可以先把原有向量XkTX_{kT}XkT​中零元素除,保留非零项,构成向量xkRx_k^RxkR​,然后从误差矩阵EkE_kEk​中取出相应的列向量,构成矩阵EkRE^R_kEkR​. 对EkRE^R_kEkR​进行SVD分解,有EkRE^R_kEkR​=UΔVTUΔV_TUΔVT​,由U的第一列更新dk,由V的第一列乘以Δ(1,1)所得结果更新xkRx_k^RxkR​

2.2 编程实现

在编程过程中,使用K-SVD算法实现字典学习,由于实验数据集太大,测试实在太费时间,故首先选择一张图片来验证代码的正确性。具体做法是将算法应用于图片上,学习得到字典D和稀疏矩阵X,而后利用D和X矩阵重建图片,与原始图片比较。
选择一张苏州水乡的图片,当选择原子数n_components为10时,重建出来的图片失去了原来的样貌,如下图所示:

考虑增加原子数,将其增加到30时,发现重建效果较之前好得多,如下

这也与我们的预期符合,用于拟合的原子数越多,失真当然越小,
以上基本验证了代码的正确性
分析:为什么需要30个原子才能较好的重构呢?

这里我在代码中设置了最大迭代次数max_iter为50,为了保证程序不会运行太长时间,这是一种折中的办法,因为考虑时间效率,另外在自己的电脑上跑,如果设置得很大,运行一次实在费劲。然而,节省时间就会导致重构准确性受到影响,50次迭代或许并未达到最优更新,但是不得不停止,倘若适当增大迭代上限,重构效果更好
再将编写好的代码用于实验数据集
做法相同,只是由于实验数据为10003072,含有1000张图片,这里直接对这个10003072矩阵进行字典学习和稀疏编码,而后重构比较计算均方误差
1) 当取原子数为50时,均方误差为907即平均每个元素偏离30左右
2) 当取原子数为100时,均方误差为562
比较SVD和字典学习方法的图像重建均方误差如下表

3:附录(代码)

# -*- coding: utf-8 -*-
"""
Created on Fri Nov 23 22:29:17 2018@author: wbw
"""
import numpy as np
import matplotlib.pyplot as plt
from numpy import *
import scipy.io as sio
import random
from sklearn import linear_model
import scipy.misc
from PIL import Image
class KSVD(object):def __init__(self, n_components, max_iter=100, tol=1e-6,n_nonzero_coefs=None):"""稀疏模型Y = DX,Y为样本矩阵,使用KSVD动态更新字典矩阵D和稀疏矩阵X:param n_components: 字典所含原子个数(字典的列数):param max_iter: 最大迭代次数:param tol: 稀疏表示结果的容差:param n_nonzero_coefs: 稀疏度"""self.dictionary = Noneself.sparsecode = None self.max_iter = max_iter self.tol = tol self.n_components = n_components self.n_nonzero_coefs = n_nonzero_coefsdef _initialize(self, y):"""初始化字典矩阵"""u, s, v = np.linalg.svd(y)self.dictionary = u[:, :self.n_components]def _update_dict(self, y, d, x):"""使用KSVD更新字典的过程"""for i in range(self.n_components):index = np.nonzero(x[i, :])[0]#选出Xk中非零的元素下标if len(index) == 0:continued[:, i] = 0r = (y - np.dot(d, x))[:, index] u, s, v = np.linalg.svd(r, full_matrices=False) d[:, i] = u[:, 0].T x[i, index] = s[0] * v[0, :]return d, xdef fit(self, y):"""KSVD迭代过程"""self._initialize(y)for i in range(self.max_iter):x = linear_model.orthogonal_mp(self.dictionary, y, n_nonzero_coefs=self.n_nonzero_coefs)e = np.linalg.norm(y - np.dot(self.dictionary, x)) if e < self.tol:breakself._update_dict(y, self.dictionary, x)self.sparsecode = linear_model.orthogonal_mp(self.dictionary, y, n_nonzero_coefs=self.n_nonzero_coefs) return self.dictionary, self.sparsecode
def loadData(file):#file='G:/lecture of grade one/pattern recognition/data/train_data.mat'trainImg=sio.loadmat(file)#print trainImg["Data"][1,:]return trainImgdef esErrSvd(Img,reconstruct):m,n=Img['Data'].shapeesErr=[0,0,0]for k in range(3):esErr[k]=0for i in range(m):for j in range(n):esErr[k]+=(Img['Data'][i][j]-reconstruct[k][i][j])**2esErr[k]/=(m*n)return esErr  def esErrDic(data,recons):m,n=data.shapeesErr=0for i in range(m):for j in range(n):esErr+=(data[i][j]-recons[i][j])**2return esErr/(m*n)
def svdReconstruct(u,sigma,vt):num_of_singular = [10,50,100]reconstruct=[]plt.figure()plt.title('A=U*S*Vh') for index,i in enumerate(num_of_singular) : reconstruct.append(np.dot(u[:,:i]*sigma[:i],vt[:i,:])) # 注意这个重构的矩阵运算 plt.subplot(1,len(num_of_singular),index+1) plt.xticks([]) plt.yticks([]) plt.title("Num of Singular :{}".format(i)) plt.imshow(reconstruct[index],cmap=plt.cm.gray)return reconstructif __name__ == '__main__':file='G:/lecture of grade one/pattern recognition/trial_two/train_data2_807802844.mat'
Img=loadData(file)
#SVDu,sigma,vt=linalg.svd(Img['Data'])reconstruct=svdReconstruct(u,sigma,vt)err=esErrSvd(Img,reconstruct)
'''
#字典学习ksvd = KSVD(100)dictionary, sparsecode = ksvd.fit(Img['Data'])recons=dictionary.dot(sparsecode)err=esErrDic(Img['Data'],recons)'''
'''
#验证字典学习代码KSVD的正确性image =Image.open('/home/swh/Downloads/scene.jpeg')image = np.array(image)image=image[:,:,0]im_ascent = image.astype('float32')#im_ascent = scipy.misc.ascent().astype(np.float)ksvd = KSVD(30) dictionary, sparsecode = ksvd.fit(im_ascent) plt.figure() plt.subplot(1, 2, 1) plt.imshow(im_ascent) plt.subplot(1, 2, 2) recon=dictionary.dot(sparsecode)plt.imshow(recon) plt.show()'''

用SVD和字典学习方法重建图像(cifar-10图片集)相关推荐

  1. 【图像重建】基于matlab字典学习KSVD图像低秩重建【含Matlab源码 1762期】

    ⛄一.低秩稀疏图像重建简介 1 矩阵的低秩稀疏分解理论 从数学上讲, 矩阵的秩反应了矩阵的固有属性, 矩阵的低秩性是指矩阵的秩相对于矩阵的行数和列数而言很小.低秩矩阵稀疏分解模型是将已知矩阵M (M∈ ...

  2. 图像分类的字典学习方法概述

    图像分类的字典学习方法概述 1 字典学习(dictionary learning) 旨在从原始数据中找到一组特殊的稀疏信号,在机器视觉中称为视觉单词(visual words),这一组稀疏元素能够足够 ...

  3. 自动编码器重建图像及Python实现

    自动编码器简介 自动编码器(一下简称AE)属于生成模型的一种,目前主流的生成模型有AE及其变种和生成对抗网络(GANs)及其变种.随着深度学习的出现,AE可以通过网络层堆叠形成深度自动编码器来实现数据 ...

  4. 第5章 Python 数字图像处理(DIP) - 图像复原与重建17 - 由投影重建图像、雷登变换、投影、反投影、反投影重建

    标题 由投影重建图像 投影和雷登变换 Johann Radon 反投影 滤波反投影重建 由投影重建图像 本由投影重建图像,主要是雷登变换与雷登把变换的应用,所以也没有太多的研究,只为了保持完整性,而添 ...

  5. 【转】由投影重建图像:滤波反投影、FDK、TFDK三维重建算法理论基础

    转自:由投影重建图像:滤波反投影.FDK.TFDK三维重建算法理论基础_m0_37357063的博客-CSDN博客_fdk算法 1. 基础理论从: [1] RafaelC.Gonzalez, Rich ...

  6. 【youcans 的 OpenCV 例程 200 篇】112. 滤波反投影重建图像

    欢迎关注 『youcans 的 OpenCV 例程 200 篇』 系列,持续更新中 欢迎关注 『youcans 的 OpenCV学习课』 系列,持续更新中 [youcans 的 OpenCV 例程 2 ...

  7. 【youcans 的 OpenCV 例程 200 篇】111. 雷登变换反投影重建图像

    欢迎关注 『youcans 的 OpenCV 例程 200 篇』 系列,持续更新中 欢迎关注 『youcans 的 OpenCV学习课』 系列,持续更新中 [youcans 的 OpenCV 例程 2 ...

  8. idft重建图像 matlab_不可见成为可见!超材料和 AI 融合,洛桑联邦理工破译了声音图像...

    无标记成像技术应用的新道路." 作者 | 付静 声音在空气中作了一幅我们看不见的画,人们需要用一些手段将其显现出来. 听上去有点玄幻,能做到吗? 能! 近日,瑞士洛桑联邦理工学院波工程实验室 ...

  9. 【OpenCV 例程 300 篇】112. 滤波反投影重建图像

    专栏地址:『youcans 的 OpenCV 例程 300篇 - 总目录』 [第 7 章:图像复原与重建] 110. 投影和雷登变换 111. 雷登变换反投影重建图像 112. 滤波反投影重建图像 [ ...

最新文章

  1. 开源 java CMS - FreeCMS2.8 模板管理
  2. ECSHOP发送邮件提示need rcpt command的解决方法
  3. [Drupal] How to get the real path of a node, no matter it is a path or a url alias
  4. Python实现定时任务,定时采集数据,定时执行脚本程序都可以
  5. this关键字在构建错误实例时使用说明
  6. 探讨【IGE】的源代码【五】。
  7. 适合win7的python版本_Python 3.9 发布,不再支持 Win7!
  8. 矩阵计算器——大一c++大作业回顾
  9. Laravel5.6 模块化公众号与小程序系统项目实战
  10. 【嵌入式基础常识】单片机
  11. 自定义SeekBar 带文字
  12. 微信支付提示微信登录失败:redirect_uri域名与后台配置不一致,错误码:10003
  13. c语言编程基础 王森,《C语言编程基础第2版》王森版 习题答案
  14. 教你10分钟电脑配置挑选装机速成攻略
  15. 微信支付可能改变的六大行业
  16. Redis数据结构之——跳表skiplist
  17. 正版软件,盗版软件和免费软件
  18. 3d打印在影视领域应用
  19. gorm增删查改json_go基于echo、gorm实现增删改查,从请求到落库
  20. 丝芙兰(Sephora)和悦诗风吟(Innisfree)如何用“购物篮”改善顾客购物体验

热门文章

  1. winrar 去广告_解压缩工具之WinRAR下载安装教程
  2. 2017.5 期中考试 完挂
  3. java请求响应中转_J2EE中的请求中转、重定向和包含关系
  4. 【英语学习】【Level 08】U05 Better option L3 Everything's a click away
  5. c#时分秒毫秒微妙_C# 关于DateTime类型 精确到毫秒
  6. php .net mvc,总是觉得asp.net MVC 写着很别扭,对比PHP的mvc,asp.net 麻烦很多?
  7. iPhone 6S GPU到底多强
  8. 每天一个设计模式之享元模式
  9. 7.JasperReports学习笔记7-applet打印
  10. 零门槛!ZBLibrary仿微信朋友圈自定义View,就是这么简单!