Pytorch: 图卷积神经网络-半监督网路实践-对比SVM, LP
Copyright: Jingmin Wei, Pattern Recognition and Intelligent System, School of Artificial and Intelligence, Huazhong University of Science and Technology
本教程不商用,仅供学习和参考交流使用,如需转载,请联系本人。
这一部分将使用半监督图卷积神经网络,针对 Cora 数据集实现图上节点的分类任务。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.metrics import accuracy_score
from sklearn.manifold import TSNE # 分布随机邻域嵌入-用于降维
from sklearn.svm import SVC # 支撑向量机
from sklearn.semi_supervised import LabelPropagation # 半监督标签传播算法
import torch
import torch.nn.functional as F
from torch_geometric.nn import GCNConv
from torch_geometric.datasets import Planetoid
from torch_geometric.utils import to_networkx
import networkx as nx # 用于网络图的数据可视化
# 模型加载选择GPU
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
print(device)
print(torch.cuda.device_count())
print(torch.cuda.get_device_name(0))
cuda
1
GeForce MX250
数据集介绍
Cora 数据集由 2708 2708 2708 篇机器学习领域的论文构成,每个样本点都是一篇论文,主要分为 7 7 7 个知识领域的论文,分别为基于案例(Case_Based),遗传算法(Genetic_Algorithms),神经网络(Neural_Networks),概率方法(Probabilistic_Methods),强化学习(Reinforcement_Learning),规则学习(Rule_Learning)与理论(Theory)。
在该数据集中,每篇论文至少引用了该数据集中的另一篇论文。针对每个节点所代表的论文,都由一个 1433 1433 1433 维的词向量表示,即图上每个节点具有 1433 1433 1433 个特征。词向量的每个元素都对应一个词,且该元素仅有 0 0 0 或 1 1 1 两个取值,取 0 0 0 表示该元素对应的词不在论文中,取 1 1 1 表示在论文中。因此所有的词都来源于一个具有 1433 1433 1433 个词的字典。
针对 Cora 数据集,torch_geometric 包已经准备好了可以直接使用的图形式的数据,通过 Planetoid() 即可导入 Cora, CiteSeer 和 PubMed 三个网络数据。
dataset = Planetoid(root='./data/Cora', name='Cora') # 通过name指定要下载的数据集
# 查看数据的情况
print('Class Number:', dataset.num_classes)
print('Feature Number:', dataset.num_edge_features)
print('Net Edge Number:', dataset.data.edge_index.shape[1] / 2)
print('Node Feature Number:', dataset.num_node_features)
print('Node Number:', dataset.data.x.shape[0])
Class Number: 7
Feature Number: 0
Net Edge Number: 5278.0
Node Feature Number: 1433
Node Number: 2708
即该数据集有 2708 2708 2708 个节点, 5278 5278 5278 条边,而且每个节点包含 1433 1433 1433 个特征,边则没有特征。
接下来查看其中的 data 属性,该属性包含数据集中的所有数据。
# 分析 data 的内容
dataset.data
Data(x=[2708, 1433], edge_index=[2, 10556], y=[2708], train_mask=[2708], val_mask=[2708], test_mask=[2708])
data 属性输出的 Data() 类型包含了多个子数据。
其中 x 的形状为 [num_nodes, num_node_features] ,即为 [节点数量, 每个节点的特征数量] 的二维矩阵。
edge_index 是图中节点的连接方式,网络连接为 COO 格式,形状为 [2, num_edges] ,即数据的每一列就代表了一条边(x[i, :])。
y 是对应的节点的标签,形状为 [num_nodes] ,即 [节点数量] 。
train_mask, val_mask, test_mask 表示节点是否为训练集、验证集和测试集。
接下来查看数据集中边的连接方式。
# 查看节点连接形式
dataset.data.edge_index
tensor([[ 0, 0, 0, ..., 2707, 2707, 2707],
[ 633, 1862, 2582, ..., 598, 1473, 2706]])
结果中表示,每一列为 2 2 2 个节点标号,代表 2 2 2 个节点有一条边,比如边 0 − 633 , 0 − 1862 , 2707 − 598 0-633,0-1862,2707-598 0−633,0−1862,2707−598 等等。
接下来查看数据中训练、验证和测试集的切分情况。通过 **_mask 数据查看。
# 查看切分情况
print(dataset.data.test_mask) # 通过mask表示样本是否在相应数据集
print('Training Dataset Node Number:', sum(dataset.data.train_mask))
print('Validating Dataset Node Number:', sum(dataset.data.val_mask))
print('Testing Dataset Node Number:', sum(dataset.data.test_mask))
tensor([False, False, False, ..., True, True, True])
Training Dataset Node Number: tensor(140)
Validating Dataset Node Number: tensor(500)
Testing Dataset Node Number: tensor(1000)
可以看出,数据集是以与类别标签等长的逻辑值向量进行切分的,且在 Cora 数据集中,