GCN实现节点分类任务

数据处理,数据集采用cora数据集

import dgl
from dgl.data import DGLDataset
import torch
import os
import pandas as pd
import torch
import numpy as np
import matplotlib.pyplot as plt
import networkx as nx
import os
os.environ["KMP_DUPLICATE_LIB_OK"]="TRUE"
import torch.nn.functional as F

class CoraDataset(DGLDataset):
    def __init__(self):
        super().__init__(name='cora')

    def process(self):
        nodes_data = pd.read_csv(r'../data/cora/cora.content', sep='\t', header=None)
        edges_data = pd.read_csv(r'../data/cora/cora.cites', sep='\t', header=None)
        node_f = nodes_data.iloc[:, 1:-1]
        node_len = nodes_data.iloc[:, 0]
        node_l = nodes_data.iloc[:, -1]
        edges_s = edges_data.iloc[:, 0]
        edges_d = edges_data.iloc[:, 1]
        idx = np.array(node_len, dtype=np.int32)

        idx_map = {j: i for i, j in enumerate(idx)}
        #print(idx_map)

        node_features = torch.from_numpy(node_f.to_numpy())

        node_labels = torch.from_numpy(node_l.astype('category').cat.codes.to_numpy().astype(np.int64))
        edges_src = torch.from_numpy(np.array(list(map(idx_map.get, edges_s))))
        edges_dst = torch.from_numpy(np.array(list(map(idx_map.get, edges_d))))



        #print(edges_src, edges_dst)
        self.graph = dgl.graph((edges_src, edges_dst), num_nodes=nodes_data.shape[0])
        self.graph.ndata['feat'] = node_features
        self.graph.ndata['label'] = node_labels

        n_nodes = nodes_data.shape[0]
        n_train = int(n_nodes * 0.6)
        n_val = int(n_nodes * 0.2)
        train_mask = torch.zeros(n_nodes, dtype=torch.bool)
        val_mask = torch.zeros(n_nodes, dtype=torch.bool)
        test_mask = torch.zeros(n_nodes, dtype=torch.bool)
        train_mask[:n_train] = True
        val_mask[n_train:n_train + n_val] = True
        test_mask[n_train + n_val:] = True
        self.graph.ndata['train_mask'] = train_mask
        self.graph.ndata['val_mask'] = val_mask
        self.graph.ndata['test_mask'] = test_mask

    def __getitem__(self, i):
        return self.graph

    def __len__(self):
        return 1




数据 导入neo4j中查看是否存在孤立节点

#查找入度为0的节点
match (n) where not()-[]-(n) return n

查找出度为0的节点
match (n) where not(n)-[]-() return n

模型搭建及训练

from dgl.nn import GraphConv
import torch.nn as nn
import torch.nn.functional as F
import torch
import dgl
from DLG_GCN.dataprocess import CoraDataset
import matplotlib.pyplot as plt
import numpy as np


class GCN(nn.Module):
    def __init__(self, in_feats, h_feats, num_classes):
        super(GCN, self).__init__()
        self.conv1 = GraphConv(in_feats, h_feats)
        self.conv2 = GraphConv(h_feats, num_classes)

    def forward(self, g, in_feat):
        h = self.conv1(g, in_feat)
        h = F.relu(h)
        h = self.conv2(g, h)
        return h




def train(g, model):
    optimizer = torch.optim.Adam(model.parameters(), lr = 0.0005)
    best_val_acc = 0
    best_test_acc = 0

    fig_loss = []
    fig_test_acc = []
    fig_val_acc = []

    features = g.ndata['feat']

    labels = g.ndata['label']
    train_mask = g.ndata['train_mask']
    val_mask = g.ndata['val_mask']
    test_mask = g.ndata['test_mask']

    for epoch in range(1000):
        logits = model(g, features)
        pred = logits.argmax(1)

        loss = F.cross_entropy(logits[train_mask], labels[train_mask])

        # Compute accuracy on training/validation/test
        train_acc = (pred[train_mask] == labels[train_mask]).float().mean()
        val_acc = (pred[val_mask] == labels[val_mask]).float().mean()
        test_acc = (pred[test_mask] == labels[test_mask]).float().mean()

        fig_loss.append(loss)
        fig_val_acc.append(val_acc)
        fig_test_acc.append(test_acc)

        if best_val_acc < val_acc:
            best_val_acc = val_acc
            best_test_acc = test_acc

        # Backward
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

        if epoch % 5 == 0:
            print('In epoch {}, loss: {:.3f}, val acc: {:.3f} (best {:.3f}), test acc: {:.3f} (best {:.3f})'.format(
                epoch, loss, val_acc, best_val_acc, test_acc, best_test_acc))
    fig, ax1 = plt.subplots()
    ax2 = ax1.twinx()
    ln1 = plt.plot(np.arange(len(fig_loss)), fig_loss, 'r', label='loss')
    ln2 = plt.plot(np.arange(len(fig_test_acc)), fig_test_acc, 'g', label='test_acc')
    ln3 = plt.plot(np.arange(len(fig_val_acc)), fig_val_acc, 'b', label='val_acc')
    ax1.set_xlabel('iteration')
    ax2.set_ylabel('training loss')
    ax2.set_ylabel('training accuracy')

    lns = ln1 + ln2 +ln3
    labels = ["train_loss", "test_acc", "val_acc"]
    # labels = [l.get_label() for l in lns]
    plt.legend(lns, labels, loc='upper left')
    plt.grid(True)

    plt.savefig("./mydata/train_val_test.png")

    plt.figure(2)
    plt.plot(np.arange(len(fig_loss)), fig_loss, 'r', label='loss')
    plt.legend(labels=['loss'])
    plt.grid(True)
    plt.savefig("./mydata/train.png")

    plt.figure(3)
    plt.plot(np.arange(len(fig_val_acc)), fig_val_acc, 'g', label='val_accuracy')
    plt.legend(labels=["test_acuracy"])
    plt.grid(True)
    plt.savefig("./mydata/val.png")

    plt.figure(4)
    plt.plot(np.arange(len(fig_test_acc)), fig_test_acc, 'b', label='test_accuracy')
    plt.legend(labels=["test_acuracy"])
    plt.grid(True)
    plt.savefig("./mydata/test.png")

    plt.show()

cora_data = CoraDataset()
graph = cora_data[0]

g = dgl.to_bidirected(graph, copy_ndata=True)

model = GCN(g.ndata['feat'].shape[1], 16, 7)

train(g, model)


训练结果

 

 

 

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在GCN中,每个节点的最终表示是由其自身特征和邻居节点特征的线性组合得到的。具体来说,对于每个节点 $i$,它的最终表示 $h_i$ 可以表示为: $$h_i = \sigma\left(\sum_{j\in N_i}\frac{1}{c_{i,j}}W h_j\right)$$ 其中,$N_i$ 是节点 $i$ 的邻居节点集合,$c_{i,j}$ 是节点 $i$ 和节点 $j$ 之间的边的归一化系数,$W$ 是权重矩阵,$\sigma$ 是一个非线性激活函数。这个公式表示了每个节点的最终表示是其邻居节点表示的加权平均值,其中权重是由边的归一化系数和权重矩阵共同确定的。这样的表示形式可以保留节点的局部信息和全局信息,使得节点的表示具有更好的表达能力。 ### 回答2: GCN(图卷积网络)是一种用于处理图数据的深度学习模型,它通过学习每个节点的表示来解决节点分类、链接预测等问题。GCN最终节点的表示原理如下: GCN的核心思想是通过聚合节点的邻居信息来更新每个节点的表示。节点的表示由其自身特征向量表示,以及邻居节点信息的加权和来构成。具体来说,GCN通过以下几个步骤实现最终节点的表示: 1. 初始化节点表示:首先,每个节点根据自身的特征向量来初始化表示,这个特征向量可以是节点的属性、拓扑结构等。 2. 聚合邻居信息:对于每个节点GCN会将其自身特征向量与其邻居节点的表示进行加权求和,得到聚合后的邻居信息。这个加权求和过程可以看作是图的卷积操作。 3. 更新节点表示:根据聚合的邻居信息,GCN使用一个学习得到的参数矩阵对节点的表示进行线性变换,再经过一个激活函数(如ReLU)进行非线性映射,得到更新后的节点表示。 4. 重复上述步骤:通过多次迭代,每次迭代都会更新节点的表示,直到达到设定的收敛条件。 5. 输出最终节点表示:经过多次迭代后,GCN会得到最终的节点表示。这些表示可以用于节点分类、链接预测等任务。 总结起来,GCN最终节点的表示原理是通过聚合节点的邻居信息,并通过线性变换和非线性映射来更新节点的表示。这样的迭代过程使得每个节点能够利用其邻居节点的信息,从而获得更丰富准确的表示,为后续的图任务提供更好的特征基础。 ### 回答3: GCN(Graph Convolutional Networks)是一种用于处理图结构数据的深度学习算法。在GCN中,节点的表示是通过将其与其邻居节点表示进行聚合得到的。 GCN的表示原理如下: 1.初始化节点表示:对于一个图,每个节点都会初始化一个表示向量。这些向量可以是随机初始化的,也可以由其他任务(如节点分类)学习得到。 2.聚合邻居节点信息:GCN通过聚合每个节点的邻居节点信息来更新节点的表示。聚合的过程中,会使用邻居节点的表示和权重矩阵进行加权求和。权重矩阵的计算可以使用图的邻接矩阵和节点的度矩阵等方式。 3.更新节点表示:将聚合后的邻居节点信息与原始节点表示相结合,得到节点的新表示。这个更新的方式可以采用类似卷积神经网络中的非线性激活函数,如ReLU等来增加模型的表达能力。 4.迭代更新:GCN会多次迭代上述步骤,每次迭代都会使用前一轮迭代得到的节点表示作为输入,继续更新节点表示。 5.最终节点表示:当GCN迭代达到指定的轮数后,得到的节点表示就是最终节点表示。这些表示可以用于后续任务,如节点分类、链接预测等。 需要注意的是,GCN的最终节点表示会受邻居节点信息的影响。邻居节点信息的聚合会通过权重矩阵进行加权,因此与节点距离较近的邻居节点节点表示的影响更大。这种聚合方式能够有效地捕捉到节点与其邻居节点之间的关系,从而提取有关节点的重要特征。通过多轮迭代,GCN能够逐渐提取出更多的节点信息,得到更准确的节点表示。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值