2.2CP分解CP-RALS算法推导python实现

由于ALS CP分解算法不能保证收敛到最小值,我们可以用正则项来解决。
《Some convergence results on the Regularized Alternating Least-Squares method for tensor decomposition》分析了如下的正则项约束Regularized Alternating Least-Squares (RALS),它惩罚了现在的因子矩阵和上一个迭代的因子矩阵的误差,是近端最小化方法,the proximal point modification of the GS (PGS) method。通过加入惩罚项来将使得函数严格凸,避免了当ALS没有critical point却会产生critical point的情况
在这里插入图片描述
因此每一步的优化就变成如下问题:
在这里插入图片描述

这个问题就变为吉洪诺夫Tikhonov正则化问题
第一个子问题的闭合解推导如下:
在这里插入图片描述
因此每一个子问题的解如下
在这里插入图片描述

关于惩罚系数的取值,可以参考SWAMP REDUCING TECHNIQUE FOR TENSOR DECOMPOSITION,即一般和噪声水平成正比
在这里插入图片描述
在迭代过程中也可以对正则项进行一个衰减decaying操作
在这里插入图片描述
整个算法如下:
在这里插入图片描述
python写出来的代码如下:

import numpy as np
import tensorly as tl
import tqdm
from tensorly.decomposition._cp import initialize_cp
tl.set_backend('numpy')

a = np.array([[1,3,5,7,8],[8,4,6,2,10]])
b = np.array([[5,13,55,17,18],[58,14,46,12,1]])
c = np.array([[14,1,5,17,18],[58,14,46,12,1]])

X = np.einsum('i,j,k->ijk',a[0],b[0],c[0])
X += np.einsum('i,j,k->ijk',a[1],b[1],c[1])
X = X.astype(float)

def CP_RALS(X, r=1, max_iter=100, err=1e-10, tao = 0.5):
    N = tl.ndim(X)

    # random initialize
    A = initialize_cp(X, r,init='svd',svd='numpy_svd').factors

    # # random initialize
    # A = []
    # for n in range(N):
    #     A.append(tl.tensor(np.random.random((X.shape[n], r))))


    for epoch in range(max_iter):
        for n in range(N):
            identity = np.eye(A[n].shape[1])
            V = np.ones((r,r))
            for i in range(N):
                if i != n:
                    V = A[i].T@A[i] * V

            A[n] = (tl.unfold(X,mode=n)@tl.tenalg.khatri_rao(A, skip_matrix=n) + tao*A[n])@np.linalg.pinv(V+tao*identity)

        X_pred = tl.fold(A[0]@tl.tenalg.khatri_rao(A,skip_matrix = 0).T,mode=0,shape=X.shape)
        error = tl.norm(X-X_pred)
        print("epoch:",epoch,",error:",error)
        if error<err:
            break
    return A
A = CP_RALS(X,r=2,max_iter=1000,tao = 0.8)
print("hi")
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值