NLP图神经网络GCN备忘_0

可以看做是对这篇博客备忘:-----hyperLink-------

 一个超容易理解的例子,

一个简单的有向图G:

图 1. 有向图 

考虑图G中各结点的出度,

结点0发出的边指向结点1,

结点1发出的边指向结点2与结点3,

结点2发出的边指向结点1,

结点3发出的边指向结点0与结点2,

该图的邻接矩阵A则表示如下,

A = np.matrix([
    [0, 1, 0, 0],
    [0, 0, 1, 1], 
    [0, 1, 0, 0],
    [1, 0, 1, 0]],
    dtype = float
)

接下来,根据每个结点的索引为每个结点生成两个整形特征,

X = np.matrix([
            [i, -i]
            for i in range(A.shape[0])
        ], dtype = float)
matrix([
           [ 0.,  0.],
           [ 1., -1.],
           [ 2., -2.],
           [ 3., -3.]
        ])

现在我们有了图G,它的邻接矩阵A,以及结点的输入特征X,

接下来应用简单的传播规则,f(X,A) = AX

A * X

matrix([
           [ 1., -1.],
           [ 5., -5.],
           [ 1., -1.],
           [ 2., -2.]]

 从 A*X 的结果可以看出,

现在每个结点的特征表示(每一行)都是它们邻居结点的特征之和,

图卷积层将每个结点表示为它的邻居结点的聚合

我们可以发现,

1.目前结点的集成表示并不包含结点本身的特征,

2. 结点的度数大那么它的特征表示最后往往也大,这可能会造成梯度消失或爆炸

为了解决第一个问题,为图中每个结点添加自循环,

做法是在应用传播规则前将单位矩阵I添加到邻接矩阵A中

I = np.matrix( np.eye( A.shape[0] ) )


matrix([
            [1., 0., 0., 0.],
            [0., 1., 0., 0.],
            [0., 0., 1., 0.],
            [0., 0., 0., 1.]
        ])
A_hat = A + I

A_hat * X


matrix([
            [ 1., -1.],
            [ 6., -6.],
            [ 3., -3.],
            [ 5., -5.]])

添加了结点自循环后,

现在集成每个结点的邻居特征表示时,

每个结点本身的特征表示也包含在内了

解决第二个问题,可以用结点的度来正则化每个结点的特征

通过将邻接矩阵A与逆度矩阵D相乘可以转换邻接矩阵A,

传播规则则变为:f(X,A) = D^{-1}AX

首先计算一下图的入度矩阵D,即考虑图中每个结点的入度

D = np.array( np.sum(A, axis=0) )[0]

D = np.matrix( np.diag( D ) )


matrix([
            [1., 0., 0., 0.],
            [0., 2., 0., 0.],
            [0., 0., 2., 0.],
            [0., 0., 0., 1.]
        ])

 初始的邻接矩阵A

A = np.matrix([
    [0, 1, 0, 0],
    [0, 0, 1, 1], 
    [0, 1, 0, 0],
    [1, 0, 1, 0]],
    dtype=float
)

 通过逆度矩阵将邻接矩阵A变换为

D**-1 * A

matrix([
             [0. , 1. , 0. , 0. ],
             [0. , 0. , 0.5, 0.5],
             [0. , 0.5, 0. , 0. ],
             [1. , 0. , 1. , 0. ]
])

可以看到邻接矩阵中每行的权重已除以该行所对应结点的度

继续传播规则

D**-1 * A * X


matrix([
             [ 1. , -1. ],
             [ 2.5, -2.5],
             [ 0.5, -0.5],
             [ 2. , -2. ]
         ])

从结果可以看出,每个结点的特征表示对应于其邻居结点的特征表示的均值

现在将以上整合,结合自循环与正则化方法,并引入先前省略的权重与激活函数

先计算下添加了自循环的邻接矩阵的度矩阵,

D_hat = np.array( np.sum( A_hat, axis=0 ) )[0]

D_hat = np.matrix( np.diag( D_hat ) )


matrix([[2., 0., 0., 0.],
        [0., 3., 0., 0.],
        [0., 0., 3., 0.],
        [0., 0., 0., 2.]])

将之前省略的权重加上

W = np.matrix([
             [1, -1],
             [-1, 1]
         ])
D_hat**-1 * A_hat * X * W


matrix([
            [ 1., -1.],
            [ 4., -4.],
            [ 2., -2.],
            [ 5., -5.]
        ])

如果想要降低输出特征表示的维度,可通过操作权重矩阵W来实现

W = np.matrix([
             [1],
             [-1]
         ])

D_hat**-1 * A_hat * X * W


matrix([[1.],
        [4.],
        [2.],
        [5.]]
)

将激活函数加上

这里保留了特征表示的维数,应用ReLU激活函数

W = np.matrix([
             [1, -1],
             [-1, 1]
         ])


relu( D_hat**-1 * A_hat * X * W )


 matrix([[1., 0.],
        [4., 0.],
        [2., 0.],
        [5., 0.]])

至此完成了一个带有邻接矩阵、输入特征、权重以及激活函数的完整的隐藏层

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值