我有一个3d numpy数组,表示一个对象,其中单元格为体素,体素的值为1到10.我想压缩图像(a)使其变小;(b)稍后快速了解通过将图像压缩到与原始图像最小程度的一致来确定图像的复杂程度。
我已经使用SVD对2D图像执行此操作,并查看需要多少个奇异值,但它看起来很难处理3D图像。如果是我看一下S矩阵中的对角线项,它们都是零,我期待奇异的值。
有什么方法可以用svd压缩3D阵列(例如以某种方式展平)?或者其他方法更合适?如果有必要,我可以将体素值简化为0或1。
答案 0 :(得分:2)
基本上可以将相同的原理应用于3D数据而不会展平它。有一些算法可以分离N维矩阵,例如CP-ALS(使用交替最小二乘),这是在包sktensor中实现的。给定 rank :
,您可以使用该包来分解张量from sktensor import dtensor, cp_als
T = dtensor(X)
rank = 5
P, fit, itr, exectimes = cp_als(T, rank, init='random')
X
是您的数据。然后,您可以使用权重weights = P.lmbda
重建原始数组X
并计算重建错误,就像使用SVD一样。
3D数据(或一般张量)的其他分解方法包括Tucker Decomposition或规范分解(也可在同一包中使用)。
它不是直接的3D SVD,但上述所有方法都可用于分析数据的主要组成部分。
查找以下(仅为完整性)tucker分解的图像:
另外还有另一张CP-ALS(优化算法)试图获得的分解图像:
图片归功于:
1- http://www.slideshare.net/KoheiHayashi1/talk-in-jokyonokai-12989223
答案 1 :(得分:0)
您想要的是higher order svd / Tucker decomposition。
在3D情况下,您将获得三个投影矩阵(每个维度一个)和一个低秩核心张量(一个3D阵列)。
您可以使用TensorLy
轻松完成此操作from tensorly.decomposition import tucker
core, factors = tucker(tensor, ranks=[2, 3, 4])
此处,core
将具有形状(2,3,4),len(factors)
将为3
,每个维度都有一个因素。