部分塔克分解

partial tucker decomposition

我想应用部分 tucker 分解算法来最小化 (60000,28,28) 的 MNIST 图像张量数据集,以便在之后应用其他机器算法(如 SVM)时保留其特征。 我有这段代码可以最小化张量的第二维和第三维

i = 16
j = 10
core, factors = partial_tucker(train_data_mnist, modes=[1,2],tol=10e-5, rank=[i,j])
train_datapartial_tucker = tl.tenalg.multi_mode_dot(train_data_mnist, factors, 
                              modes=modes, transpose=True)
test_data_partial_tucker = tl.tenalg.multi_mode_dot(test_data_mnist, factors, 
                              modes=modes, transpose=True)

当我在张量中使用 partial_tucker 时,如何找到最佳排名 [i,j],以便在保留尽可能多的数据的同时为图像提供最佳降维?

因此,如果您查看 tensorly 链接的 here 的源代码,您可以看到相关函数的文档 partial_tucker 说:

"""
Partial tucker decomposition via Higher Order Orthogonal Iteration (HOI)
Decomposes 'tensor' into a Tucker decomposition exclusively along 
the provided modes.

Parameters
----------
tensor: ndarray
modes: int list
list of the modes on which to perform the decomposition
rank: None, int or int list
size of the core tensor, 
if int, the same rank is used for all modes
"""

此函数的目的是为您提供近似值,该近似值可为给定等级保存尽可能多的数据。我不能给你哪个排名“将在保留尽可能多的数据的同时为图像提供最佳降维”,因为降维和精度损失之间的最佳权衡是抽象的客观“正确”答案,因为这在很大程度上取决于项目的具体目标以及实现这些目标可用的计算资源。

如果我告诉你做“最好的排名”,它首先会消除这种近似分解的目的,因为“最好的排名”将是没有“损失”的排名,也就是没有固定等级和某种程度的近似值会使术语 approximation 变得毫无意义。但是为了获得降维而偏离这个“最佳排名”多远,这不是任何人都可以客观地为您回答的问题。人们当然可以提出意见,但这一意见所依赖的信息要比我目前从您那里获得的信息多得多。如果您正在寻找关于这种权衡的更深入的观点以及哪种权衡最适合您,我建议您在 Stack 网络中的一个站点上发布一个问题,详细说明您的情况,更侧重于 mathematical/statistical 基础Stack Overflow 更关注的是降维,而不是编程方面,例如 Stack Exhange Cross Validated or perhaps Stack Exhange Data Science.

Sources/References/Further阅读:

  1. Blog/Article on Tucker Decompositions
  2. "Some mathematical notes on three-mode factor analysis" - Paper on Tucker Decomposition by Ledyard R Tucker
  3. "A Multilinear Singular Value Decomposition" by Lathauwer et al
  4. "On the Best Rank-1 and Rank-(R1 ,R2 ,. . .,RN) Approximation of Higher-Order Tensors" by Lathauwer et al

就像主成分分析一样,部分 tucker 分解会随着我们提高等级给出更好的结果,因为重建的最佳均方残差更小。

一般来说,能够准确重建原始数据的特征(core 张量)可用于进行类似的预测(给定任何模型,我们可以预先进行转换,从core 个特征)。

import mxnet as mx
import numpy as np
import tensorly as tl
import matplotlib.pyplot as plt
import tensorly.decomposition

# Load data
mnist = mx.test_utils.get_mnist()
train_data = mnist['train_data'][:,0]


err = np.zeros([28,28]) # here I will save the errors for each rank
batch = train_data[::100] # process only 1% of the data to go faster
for i in range(1,28):
  for j in range(1,28):
    if err[i,j] == 0:
      # Decompose the data
      core, factors = tl.decomposition.partial_tucker(
                        batch, modes=[1,2], tol=10e-5, rank=[i,j])
      # Reconstruct data from features
      c = tl.tenalg.multi_mode_dot(core, factors, modes=[1,2]);
      # Calculate the RMS error and save
      err[i,j] = np.sqrt(np.mean((c - batch)**2));

# Plot the statistics
plt.figure(figsize=(9,6))
CS = plt.contour(np.log2(err), levels=np.arange(-6, 0));
plt.clabel(CS, CS.levels, inline=True, fmt='^{%d}$', fontsize=16)
plt.xlabel('rank 2')
plt.ylabel('rank 1')
plt.grid()
plt.title('Reconstruction RMS error');

通常情况下,平衡排名会获得更好的结果,即 ij 彼此差别不大。

随着我们增加误差,我们可以获得更好的压缩,我们可以根据误差对 (i,j) 进行排名,并仅在给定特征维度 i * j 的误差最小的地方绘制,就像这样

X = np.zeros([28, 28])
X[...] = np.nan;
p = 28 * 28;
for e,i,j in sorted([(err[i,j], i, j) for i in range(1, 28) for j in range(1, 28)]):
  if p < i * j:
    # we can achieve this error with some better compression
    pass
  else:
    p = i * j;
    X[i,j] = e;
plt.imshow(X)

白色区域的任何地方你都在浪费资源,选择