如何从张量设计 partial_tucker 函数的测试?

How do I design a test for the partial_tucker function from tensorly?

我尝试设计一个测试,以验证来自 tensorly 的 partial_tucker 函数是否像我期望的那样工作。换句话说,我想为 partial_tucker 函数设计一个输入及其相关的预期输出。

所以,我尝试做的是取一个初始随机张量 A(4 阶),手动计算它的 "low rank" tucker 分解,然后重建形状相同的张量初始张量,比如 A_tilde。我认为 A_tilde 张量就是初始张量 A 的 "low rank approximation"。我说得对吗?

然后我想在 A_tilde 张量上使用 partial_tucker 函数,我希望结果与我手工计算的 tucker 分解相同。事实并非如此,所以我猜我手工制作的塔克分解是错误的。如果是,为什么?

import tensorly
import numpy as np

h, w, c, f = 3, 3, 64, 128
c_prim, f_prim = 16, 32
base_tensor = np.random.rand(h, w, c, f)


# compute tucker decomposition by hand using higher order svd describred here: https://www.alexejgossmann.com/tensor_decomposition_tucker/.
lst_fac = []
for k in [2, 3]:
    mod_k_unfold = tensorly.base.unfold(base_tensor, k)
    U, _, _ = np.linalg.svd(mod_k_unfold)
    lst_fac.append(U)

real_in_fac, real_out_fac = lst_fac[0], lst_fac[1]
real_core = multi_mode_dot(base_tensor, [real_in_fac.T, real_out_fac.T], modes=(2,3))
del base_tensor  # no need of it anymore

# what i call the "low rank tucker decomposition"
real_core = real_core[:,:,:c_prim,:f_prim]
real_in_fac = real_in_fac[:, :c_prim]
real_out_fac = real_out_fac[:, :f_prim]

# low rank approximation
base_tensor_low_rank = multi_mode_dot(real_core, [real_in_fac, real_out_fac], modes=(2,3))
in_rank, out_rank = c_prim, f_prim
core_tilde, (in_fac_tilde, out_fac_tilde) = partial_tucker(base_tensor_low_rank, modes=(2, 3), ranks=(in_rank, out_rank), init='svd')
base_tensor_tilde = multi_mode_dot(core_tilde, [in_fac_tilde, out_fac_tilde], modes=(2,3))
assert np.allclose(base_tensor_tilde, base_tensor_low_rank) # this is OK

assert np.allclose(in_fac_tilde, real_in_fac) # this fails

请注意,我已尝试计算 in_fac_tilde.T @ real_in_fac 以查看它是否是恒等式或类似的东西,我注意到只有第一列在两个矩阵中是共线的,并且与所有其他矩阵正交。

你在这里隐含地做了很多假设:你假设,例如,你可以 trim 一个 rank-R 分解来得到 rank-(R-1) 分解。这通常是不正确的。另请注意,您使用的 Tucker 分解不仅仅是高阶 SVD (HO-SVD)。相反,HO-SVD 用于初始化,然后是高阶正交迭代 (HOOI)。

您还假设低秩分解对于任何给定的秩都是唯一的,这样您就可以直接比较分解的因子。情况也并非如此(即使在矩阵情况下,并且具有正交性等强约束,您仍然会有符号不确定性)。

相反,您可以检查相对重建错误。我建议你看看 TensorLy 中的 tests。 如果您是从张量开始的,那么有很多很好的参考资料。例如,Kolda 和 Bader 的开创性工作;特别是对于 Tucker,De Lathauwer 等人(例如 on best low-rank approximation of tensors)等人的工作