前言
本文是图神经网络系列的一部分内容,主要对图傅立叶变换 (Graph Fourier Transform,GFT) 进行讲解,用公式梳理了GFT的流程并举一个例子便于理解。
其他关于更全面的知识讲解,见博客《关于谱图理论-图傅里叶变换-谱卷积等谱图领域知识的理解》。
GFT流程
GFT公式为:
f
^
=
U
T
f
\hat{f}=U^Tf
f^=UTf,其中
U
U
U 是单位特征向量矩阵,
U
T
U^T
UT 的每一行是单位特征向量;
f
:
V
→
R
f: V \rightarrow \mathbb{R}
f:V→R 是定义在图
G
G
G 顶点上的信号,称之为图信号。
展开为矩阵的形式:
(
f
^
(
λ
1
)
f
^
(
λ
2
)
⋮
f
^
(
λ
l
)
)
=
[
u
1
(
1
)
u
1
(
2
)
⋯
u
1
(
n
)
u
2
(
1
)
u
2
(
2
)
⋯
u
2
(
n
)
⋮
⋮
⋮
u
n
(
1
)
u
2
(
2
)
⋯
u
n
(
n
)
]
⋅
[
f
(
1
)
f
(
2
)
⋮
f
(
n
)
]
\begin{pmatrix} \hat{f}(\lambda_1) \\ \hat{f}(\lambda_2) \\ \vdots \\ \hat{f}(\lambda_l) \end{pmatrix}= \begin{bmatrix} u_1(1) & u_1(2) & \cdots & u_1(n) \\ u_2(1) & u_2(2) & \cdots & u_2(n) \\ \vdots & \vdots & & \vdots \\ u_n(1) & u_2(2) & \cdots & u_n(n) \\ \end{bmatrix} \centerdot \begin{bmatrix} f(1) \\ f(2) \\ \vdots \\ f(n) \end{bmatrix}
⎝
⎛f^(λ1)f^(λ2)⋮f^(λl)⎠
⎞=⎣
⎡u1(1)u2(1)⋮un(1)u1(2)u2(2)⋮u2(2)⋯⋯⋯u1(n)u2(n)⋮un(n)⎦
⎤⋅⎣
⎡f(1)f(2)⋮f(n)⎦
⎤ 对等式右边的矩阵进行计算,可得:
(
f
^
(
λ
1
)
f
^
(
λ
2
)
⋮
f
^
(
λ
n
)
)
=
[
∑
i
=
1
n
f
(
i
)
u
1
(
i
)
∑
i
=
1
n
f
(
i
)
u
2
(
i
)
⋮
∑
i
=
1
n
f
(
i
)
u
n
(
i
)
]
\begin{pmatrix} \hat{f}(\lambda_1) \\ \hat{f}(\lambda_2) \\ \vdots \\ \hat{f}(\lambda_n) \end{pmatrix}= \begin{bmatrix} \textstyle\sum_{i=1}^nf(i)u_1(i) \\ \textstyle\sum_{i=1}^nf(i)u_2(i) \\ \vdots \\ \textstyle\sum_{i=1}^nf(i)u_n(i) \end{bmatrix}
⎝
⎛f^(λ1)f^(λ2)⋮f^(λn)⎠
⎞=⎣
⎡∑i=1nf(i)u1(i)∑i=1nf(i)u2(i)⋮∑i=1nf(i)un(i)⎦
⎤ 可以理解为图信号
f
f
f 的傅里叶变换的每个元素
f
^
(
λ
l
)
\hat{f}(\lambda_l)
f^(λl),都等于相应特征值下对应特征向量
u
l
u_l
ul 与 图信号
f
f
f 的内积。
GFT例子
设图 G G G 的形式如下:
图 | 度矩阵 | 邻接矩阵 | 拉普拉斯矩阵 |
---|---|---|---|
![]() | [ 2 0 0 0 0 2 0 0 0 0 3 0 0 0 0 1 ] \begin{bmatrix} 2 & 0 & 0 & 0 \\ 0& 2 & 0 & 0 \\ 0 & 0 & 3 & 0 \\ 0 & 0 & 0 & 1 \\ \end{bmatrix} ⎣ ⎡2000020000300001⎦ ⎤ | [ 0 1 1 0 1 0 1 0 1 1 0 1 0 0 1 0 ] \begin{bmatrix} 0&1&1&0 \\ 1&0&1&0 \\ 1&1&0&1 \\ 0&0&1&0 \\ \end{bmatrix} ⎣ ⎡0110101011010010⎦ ⎤ | [ 2 − 1 − 1 0 − 1 2 − 1 0 − 1 − 1 3 − 1 0 0 − 1 1 ] \begin{bmatrix} 2&-1&-1&0\\\\-1&2&-1&0\\\\-1&-1&3&-1\\\\0&0&-1&1 \end{bmatrix} ⎣ ⎡2−1−10−12−10−1−13−100−11⎦ ⎤ |
- 创建拉普拉斯矩阵 L L L
import numpy as np
L = np.array(
[[ 2., -1., -1., 0.],
[-1., 2., -1., 0.],
[-1., -1., 3., -1.],
[ 0., 0., -1., 1.]])
- 求
L
L
L 对应的特征值和特征向量
即求 ( λ 1 , λ 2 , λ 3 , λ 4 ) (\lambda_1,\lambda_2,\lambda_3,\lambda_4) (λ1,λ2,λ3,λ4) 和 U U U
vals_ori,vecs_ori = np.linalg.eig(L)
print(vals_ori.round(3))
print(vecs_ori.round(3))
##输出
"""
[4. 3. 0. 1.]
[[-0.289 0.707 -0.5 -0.408]
[-0.289 -0.707 -0.5 -0.408]
[ 0.866 0. -0.5 0. ]
[-0.289 -0. -0.5 0.816]]
"""
由于拉普拉斯图谱(Laplacian Graph Spectrum) 要求 0 = λ 0 ≤ λ 1 ≤ ⋯ ≤ λ N − 1 0= \lambda_0\leq\lambda_1\leq\cdots\leq\lambda_{N-1} 0=λ0≤λ1≤⋯≤λN−1,单位特征向量矩阵 U U U 按照这个顺序排列,因此我们可以得到按从小到大排序的特征值序列及对应的单位特征向量矩阵。
# 求特征值从小到大排序的索引
lambda_order_index = [x[0] for x in sorted(enumerate(vals_ori), key=lambda x:x[-1])]
# 调整特征向量矩阵中的特征向量位置
U = (vecs_ori.T)[lambda_order_index].T
print(U.round(3))
## 输出
"""
[[-0.5 -0.408 0.707 -0.289]
[-0.5 -0.408 -0.707 -0.289]
[-0.5 0. 0. 0.866]
[-0.5 0.816 -0. -0.289]]
"""
- 图信号
f
f
f
由于图信号 f f f 是关于图顶点的函数,为简单期间, f f f 是将顶点映射为顶点的值的函数,即:
f = [ f ( 1 ) f ( 2 ) f ( 3 ) f ( 4 ) ] = [ 1 2 3 4 ] f= \begin{bmatrix} f(1) \\ f(2) \\ f(3) \\ f(4) \end{bmatrix}= \begin{bmatrix} 1 \\ 2 \\ 3 \\ 4 \end{bmatrix} f=⎣ ⎡f(1)f(2)f(3)f(4)⎦ ⎤=⎣ ⎡1234⎦ ⎤所以, f f f 的代码如下
f_vec=np.array([[1],[2],[3],[4]])
- 求
f
f
f 的GFT
即实现: f ^ = U T f \hat{f}=U^Tf f^=UTf
f_hat = np.matmul(U.T, f_vec)
print(f_hat.round(3))
"""
[[-5. ]
[ 2.041]
[-0.707]
[ 0.577]]
"""
■ \blacksquare ■