本博客为表达学习课程期末实验,使用K-SVD算法实现缺失人脸图像的恢复。图像数据取自Yale B 数据集中的38张192*168的人脸正面图像…
一、实验目的(问题描述)
本实验拟使用K-SVD算法实现缺失人脸图像的恢复。图像数据取自Yale B 数据集中的38张192*168的人脸正面图像。将图像数据划分为训练集和测试集,在训练集上使用K-SVD算法得到字典,对测试集中的图像进行50%、70%的随机像素值缺失处理。使用训练集训练得到的字典填补缺失图像并计算重建人脸图像与原始图像的平均误差。
二、算法描述和分析
1、OMP(Orthogonal Matching Pursuit 正交匹配追赶法)算法
1)原理
在匹配算法(MP)基础上,每次迭代中通过在已选的集合中的全部元素上重新调整表达系数,使得每次都能最大化的减小残差。
2)性质
A、
\[rk\perp span\{a_{\lambda 1},a_{\lambda 2},a_{\lambda 3},\dots,a_{\lambda k} \}\]#####
B、 对于m维向量,该算法最多在m步内即可收敛
3)算法步骤
2、K-SVD算法
1)字典学习
2)K-SVD原理
K-SVD是一种字典学习算法(其他算法有MOD方向法等),该算法通过两个主要步骤训练字典:
1、稀疏编码:固定字典D,求解稀疏表达矩阵X;
2、字典更新(主要创新点):在当前表达X下,逐一更新字典D中原子(列)(固定其他列不变),同时也更新表达矩阵X的对应行。
其中,第一步可以通过常见的稀疏编码算法实现(OMP,BP),本实验使用OMP算法;
第二步通过优化目标函数来更新原子(列):
由于把第k个原子剥离后,表达中产生了空洞,我们的目标就是找到一个新的dk^,更好的填补这个空洞;或者说,寻找Ek的秩为1的最优逼近,但直接求解不易,而这又可以通过核范数(University of Washington 的教授M. Fazel提出基于核范数对矩阵的秩进行封装)来进行有效估计,故可以将Ek进行SVD分解即可满足需求。
同时为了保证新生成的X的第k行gk_T还是稀疏的,我们需要对Ek和gk_T进行“压缩”,只取gkT非0元素对应下标的原子(列)和元素。
3)算法步骤
三、算法实现
1、OMP算法
1)OMP算法实现
1 |
|
2)OMP算法效果展示
1 |
|
##### 拟合效果
结论
从图中可以看出,OMP算法重构的数据对原始数据进行了较好的拟合(稀疏度为7);
3)OMP算法进一步分析
1 |
|
结论
使用不同的稀疏度对原始数据进行稀疏表达后再拟合,从图中可以看出,稀疏度越大,误差越小(稀疏度从1到20)。但是,稀疏度太大的话,需要的迭代次数也更多,因此实际使用时,要从效率和效果两方面综合考虑来选择合适的稀疏度。
2、K-SVD算法
1 |
|
四、实验数据及数据预处理
1、试验数据预处理后保存为.npy格式
1 |
|
2、读取训练集和测试集并对测试集进行不同程度模糊(0,0.5,0.7)处理
1 |
|
3、对预处理后的数据集进行逆向处理为原图片格式并显示
1 |
|
效果
1、原始数据集
2、原始测试集
3、50%残差处理后的测试集
4、70%残差处理后的测试集
五、实验结果及实验分析
1、训练字典(迭代5次,稀疏度10)
#-- 对矩阵进行列归一化操作
#-- 使得列向量为单位向量
def normalization(A):
for j in range(A.shape[1]):
res_sum = np.sqrt(np.sum(np.square(A[:,j])))
A[:,j] = np.divide(A[:,j],res_sum)
return A
#-- 训练字典
#-- Y = 64 x 11088
#-- D = 64 x 441
#-- 稀疏编码 OMP
def train():
S = 10 # 稀疏度
L = 5 # 迭代次数
e = 0.00001
K = 441
Y = read_train(10).reshape(-1,64).T
# 对训练数据进行归一化处理
Y_norm = np.zeros(Y.shape)
# 每一列归一化
for i in range(Y.shape[1]):
normlize = np.linalg.norm(Y[:,i])
mean = np.sum(Y[:,i])/Y.shape[0]
Y_norm[:,i] = (Y[:,i]-mean)/normlize
# -- 随机生成初始字典D0
indexs = np.arange(Y.shape[1])[:K]
D0 = Y_norm[:,indexs]
# -- 归一化为单位向量
D0 = normalization(D0)
# 训练字典
D, X = K_SVD(D0.copy(),S,Y_norm,e,L)
# 保存结果
np.save('D_train',D)
np.save('X_train',X)
2、测试
1 |
|
恢复效果
1、50%残差恢复效果
2、70%残差恢复效果
平均误差(RMSE)(5次迭代,稀疏度10)
1、50%残差RMSE: 0.2456584943753804
2、70%残差RMSE: 0.37693618384019295
六、小结
本次实验使用python复现了OMP算法和K-SVD算法,并完成了给定数据集的划分和预处理,通过训练字典,在测试集上重构残差图像,实现了人脸残差图像的恢复,并通过进一步的对比试验分析,了解了这些算法的一些性质(可能不完善不准确),基本达到了实验目的。
通过本课程的学习,了解了稀疏表达和低秩表达的相关概念以及非线性编码的一些概念,同时也了解到关于这些问题的一些解决方法。对于老师在课堂上的一些定理、结论的详细证明,也让人受益匪浅,感慨良多。而这些东西在人脸数据集上的实际应用也让人印象深刻,对表达学习这个领域也有了更多的好奇与兴趣。
参考文献
[1] J. Wright, A. Y. Yang, A. Ganesh, S. S. Sastry and Y. Ma, “Robust Face Recognition via Sparse Representation,” in IEEE Transactions on Pattern Analysis and Machine Intelligence, vol. 31, no. 2, pp. 210-227, Feb. 2009.
[2] 课程讲义