首页 > 解决方案 > 如何为 Tacker 分解实现 mode-k 乘积 Python?

问题描述

我正在尝试在 python 中进行 Tacker 分解。我参考这个页面

我想使用 NumPy 在 Python 中实现 mode-k 产品。根据上面的网页,我要做mode-k产品。

我写mode3产品。但我认为还有更多计算它们的好方法。

l1 = 3
l2 = 3
l3 = 3
l4 = 3
J = 2
X = np.random.uniform(0,1,(l1,l2,l3,l4))
M = np.random.uniform(0,1,(J,l3))

def mode_3_prodcut(X,M,mode=3):
    A = np.zeros((l1,l2,J,l4))
    for i1 in range(l1):
        for i2 in range(l2):
            for j in range(J):
                for i4 in range(l4):
                    term = 0
                    for i3 in range(l3):
                        term += X[i1,i2,i3,i4] * M[j,i3]

                    A[i1,i2,j,i4] = term

    return A

编辑

我写了张量 X ∈ R^{l_1×l_2×…×l_N} 和矩阵 M ∈ R^{J×l_n} 之间的 mode-k 乘积的定义。

l_1,l_2,…,l_N 是自然数。X 和 M 之间的模式 k 乘积为 X ⊗_n M,

( X ⊗_n M ) ∈ R^{l_1×l_2×…×l_(n-1)×J×l_(n+1)×…×l_N}

( X ⊗_n M ) {i_1,…,i {n-1},j,i_{n+1},…,i_N} = Σ_{i_n}^{l_n} X_{i_1,…,i_{n- 1},i_n,i_{n+1},…,i_N} m_{j,i_n}

标签: pythonnumpytensor

解决方案


这就是答案。

def mode_n_product(x, m, mode):
   x = np.asarray(x)
   m = np.asarray(m)
   if mode <= 0 or mode % 1 != 0:
       raise ValueError('`mode` must be a positive interger')
   if x.ndim < mode:
       raise ValueError('Invalid shape of X for mode = {}: {}'.format(mode, x.shape))
   if m.ndim != 2:
       raise ValueError('Invalid shape of M: {}'.format(m.shape))
   return np.swapaxes(np.swapaxes(x, mode - 1, -1).dot(m.T), mode - 1, -1)

推荐阅读