numpy - 如何从具有以下形状的 SVD 组件重建原始矩阵?
问题描述
我正在尝试使用 SVD 组件重建以下形状矩阵 (256 x 256 x 2)
U.shape = (256, 256, 256)
s.shape = (256, 2)
vh.shape = (256, 2, 2)
我已经尝试过 numpy 和 scipy 文档中的方法来重建原始矩阵,但多次失败,我认为可能 3D 矩阵有不同的重建方式。我正在使用numpy.linalg.svd进行分解。
解决方案
从np.linalg.svd的文档:
“...如果
a
有两个以上的维度,则应用广播规则,如 :ref: 中所述routines.linalg-broadcasting
。这意味着 SVD 正在“堆叠”模式下工作:它迭代第一个a.ndim - 2
维度的所有索引,并且对于每个组合 SVD应用于最后两个指数。”
这意味着您只需要处理s
矩阵(或一般情况下的张量)即可获得正确的张量。更准确地说,您需要做的是s
适当填充,然后只取前 2 列(或者通常,其行数vh
应等于返回的列数s
)。
这是一个适用于您的案例的工作代码:
import numpy as np
mat = np.random.randn(256, 256, 2) # Your matrix of dim 256 x 256 x2
u, s, vh = np.linalg.svd(mat) # Get the decomposition
# Pad the singular values' arrays, obtain diagonal matrix and take only first 2 columns:
s_rep = np.apply_along_axis(lambda _s: np.diag(np.pad(_s, (0, u.shape[1]-_s.shape[0])))[:, :_s.shape[0]], 1, s)
mat_reconstructed = u @ s_rep @ vh
mat_reconstructed
等于mat
精度误差。
推荐阅读
- vue.js - vuex的状态长度不出来
- postgresql - 查找两个最近订单之间的时差
- ios - 如何删除 Eureka buttonrow 中的行分隔符?
- javascript - 在 Vuex 中导入可重用的动作
- python - Python 实现一个由所有其他模块共享的模块
- java - 使用线程池执行器监视线程并在任何线程被自动终止时创建新线程
- python - 使用 Python Exchangelib 库的电子邮件正文中的表格格式
- node.js - Sequelize – id as uuid – 使用 bulkInsert 自动创建
- java - 如何在 vaadin 框架中实现 azure-storage
- c# - 无法使用 XAML 页面中的 X:Name 访问 UserControl