TensorLy 笔记系列
TensorLy 基本操作
4.1. 创建 tensor
tensor
是一个多维数组, 例如,从前部切片定义tensor X
.
X
1
=
[
0
2
4
6
8
10
12
14
16
18
20
22
]
and
X
2
=
[
1
3
5
7
9
11
13
15
17
19
21
23
]
{X_1 = \left[ \begin{matrix} 0 & 2 & 4 & 6\\ 8 & 10 & 12 & 14\\ 16 & 18 & 20 & 22\\ \end{matrix} \right] \text {and} X_2 = \left[ \begin{matrix} 1 & 3 & 5 & 7\\ 9 & 11 & 13 & 15\\ 17 & 19 & 21 & 23\\ \end{matrix} \right]}
X1=⎣⎡0816210184122061422⎦⎤andX2=⎣⎡1917311195132171523⎦⎤
在 Python
中,数组可以按照下面方式表达:
import numpy as np
import tensorly as tl
X = tl.tensor(np.arange(24).reshape((3, 4, 2)))
从最后维度查看 tensor
的前向切片。
>>> X[..., 0]
array([[ 0, 2, 4, 6],
[ 8, 10, 12, 14],
[16, 18, 20, 22]])
>>> X[..., 1]
array([[ 1, 3, 5, 7],
[ 9, 11, 13, 15],
[17, 19, 21, 23]])
4.2. 展开
按照给定的方法将 tensor
展开为矩阵,被称为矩阵化。对于一个 n
阶 tensor
,
(
I
0
,
I
1
,
⋯
,
I
N
)
(I_0, I_1, \cdots, I_N)
(I0,I1,⋯,IN), tensor n-mode
展开的尺寸是
(
I
n
,
I
0
,
I
1
×
⋯
×
I
n
−
1
×
I
n
+
1
⋯
×
I
N
)
(I_n, I_0, I_1 \times \cdots \times I_{n-1} \times I_{n+1} \cdots \times I_N)
(In,I0,I1×⋯×In−1×In+1⋯×IN).
在tensorly中为了取得更好的性能,我们使用一种不同于经典的 1-mode 展开方法。给定tensor
,
X
~
∈
R
I
0
,
I
1
×
I
2
×
⋯
×
I
N
\tilde X \in \mathbb{R}^{I_0, I_1 \times I_2 \times \cdots \times I_N}
X~∈RI0,I1×I2×⋯×IN,
X
~
\tilde X
X~的n-mode
展开成为一个矩阵
X
∈
R
I
n
,
I
M
\mathbf{X} \in \mathbb{R}^{I_n, I_M}
X∈RIn,IM, 其中
M
=
∏
k
=
0
,
k
≠
n
N
I
k
M = \prod_{k=0, \\k \neq n}^N I_k
M=∏k=0,k=nNIk, 通过元素映射
(
i
0
,
i
1
,
⋯
,
i
N
)
(i_0, i_1, \cdots, i_N)
(i0,i1,⋯,iN) 到
(
i
n
,
j
)
(i_n,j)
(in,j),
j
=
∑
k
=
0
,
k
≠
n
N
i
k
×
∏
m
=
k
+
1
,
k
≠
n
N
I
m
j = \sum_{k=0, \\k \neq n}^N i_k \times \prod_{m=k+1, \\k \neq n}^N I_m
j=∑k=0,k=nNik×∏m=k+1,k=nNIm
传统的 mode-1
展开方式通常是按照第一维度开始,但是为了和 Python
保持一致,tensorly
从0维度展开,也就是说, unfold(tensor, 0)
是按照第一维度展开。
例如,使用上述定义的 tesnor
X
~
\tilde X
X~, 0-mode
展开方式:
X
~
[
0
]
=
[
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
]
\tilde X_{[0]} = \left[ \begin{matrix} 0 & 1 & 2 & 3 & 4 & 5 & 6 & 7\\ 8 & 9 & 10 & 11 & 12 & 13 & 14 & 15\\ 16 & 17 & 18 & 19 & 20 & 21 & 22 & 23\\ \end{matrix} \right]
X~[0]=⎣⎡08161917210183111941220513216142271523⎦⎤
1-mode
展开方式:
X
~
[
1
]
=
[
0
1
8
9
16
17
2
3
10
11
18
19
4
5
12
13
20
21
6
7
14
15
22
23
]
\tilde X_{[1]} = \left[ \begin{matrix} 0 & 1 & 8 & 9 & 16 & 17\\ 2 & 3 & 10 & 11 & 18 & 19\\ 4 & 5 & 12 & 13 & 20 & 21\\ 6 & 7 & 14 & 15 & 22 & 23\\ \end{matrix} \right]
X~[1]=⎣⎢⎢⎡02461357810121491113151618202217192123⎦⎥⎥⎤
2-mode
展开方式:
X
~
[
2
]
=
[
0
2
4
6
8
10
12
14
16
18
20
22
1
3
5
7
9
11
13
15
17
19
21
23
]
\tilde X_{[2]} = \left[ \begin{matrix} 0 & 2 & 4 & 6 & 8 & 10 & 12 & 14 & 16 & 18 & 20 & 22\\ 1 & 3 & 5 & 7 & 9 & 11 & 13 & 15 & 17 & 19 & 21 & 23\\ \end{matrix} \right]
X~[2]=[01234567891011121314151617181920212223]
在tensorly
中:
>>> from tensorly import unfold
>>> unfold(X, 0) # mode-1 unfolding
array([[ 0, 1, 2, 3, 4, 5, 6, 7],
[ 8, 9, 10, 11, 12, 13, 14, 15],
[16, 17, 18, 19, 20, 21, 22, 23]])
>>> unfold(X, 1) # mode-2 unfolding
array([[ 0, 1, 8, 9, 16, 17],
[ 2, 3, 10, 11, 18, 19],
[ 4, 5, 12, 13, 20, 21],
[ 6, 7, 14, 15, 22, 23]])
>>> unfold(X, 2) # mode-3 unfolding
array([[ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22],
[ 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23]])
4.3. 折叠
通过 tensorly.base.fold
函数将矩阵折叠为 tensor
。
>>> from tensorly import fold
>>> unfolding = unfold(X, 1)
>>> original_shape = X.shape
>>> fold(unfolding, 1, original_shape)
array([[[ 0, 1],
[ 2, 3],
[ 4, 5],
[ 6, 7]],
[[ 8, 9],
[10, 11],
[12, 13],
[14, 15]],
[[16, 17],
[18, 19],
[20, 21],
[22, 23]]])
参考资料
- T.G.Kolda and B.W.Bader, “Tensor Decompositions and Applications”, SIAM REVIEW, vol. 51, n. 3, pp. 455-500, 2009.
- tensorly