部分塔克分解

use*_*410 5 python machine-learning tensorflow tensorly

我想应用部分塔克分解算法来最小化 (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)
Run Code Online (Sandbox Code Playgroud)

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

Bob*_*Bob 5

就像主成分分析一样,当我们增加秩时,部分塔克分解将给出更好的结果,从某种意义上说,重建的最佳均方残差更小。

一般来说,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='$2^{%d}$', fontsize=16)
plt.xlabel('rank 2')
plt.ylabel('rank 1')
plt.grid()
plt.title('Reconstruction RMS error');
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

通常,您会获得更好的排名平衡的结果,即i彼此j之间差异不大。

当我们增加误差时,我们可以获得更好的压缩,我们可以(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)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

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