近期买了一本图神经网络的入门书,接下里的几篇博客对书中的一些实战案例进行整理,具体的理论和原理部分可以自行查阅该书,该书购买链接:《深入浅出的图神经网络》。
本节我们通过一个完整的例子来理解如何通过GCN来实现对节点的分类。
目录
1. 数据集及预处理
我们使用的是Cora数据集,该数据集由2708篇论文,以及它们之间的引用关系构成的5429条边构成。这些论文根据主题划分为7类,分别是神经网络、强化学习、规则学习、概率方法、遗传算法、理论研究、案例相关。每篇论文的特征(向量)通过词袋模型得到,维度为1433(词典大小),每一维表示一个词,1表示该词在该论文中出现,0表示未出现。
首先定义类CoraData来对数据进行预处理,主要包括下载数据、规范化数据并进行缓存以备重复使用。最终得到的数据形式包括如下几个部分:
1)X:图中节点的特征,维度为N*D,即2708*1433(每个节点表示一条数据/一篇论文)
2)Y:节点对应的标签,包括7个类别。
3)adjacency:邻接矩阵,维度N*N(2708*2708),类型为scipy.sparse.coo_matrix
4)train_mask、val_mask、test_mask:与节点数相同的掩码,用于划分训练集、验证集、 测试集。
注意:我们把每条数据/每篇论文表示为图中的一个节点,和之前的深度学习数据集不同,以前我们假设数据之间是独立同分布的,在这里论文间都有引用关系,也就是每个数据都是有关联的,之前的假设不再适用。所以,我们把这种有关联的数据表示为图中节点,边表示数据之间的关系。这是一个典型的图数据。
#导入必要的库
import itertools
import os
import os.path as osp
import pickle
import urllib
from collections import namedtuple
import numpy as np
import scipy.sparse as sp #邻接矩阵用稀疏矩阵形式存储 节省空间
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.nn.init as init
import torch.optim as optim
import matplotlib.pyplot as plt
%matplotlib inline
- CoraData类定义
A为邻接矩阵 N*N;
(添加自连接 不仅考虑邻接节点的特征信息,还考虑自身节点的特征信息)
此时的度矩阵
为邻接矩阵
按行求和。
归一化拉普拉斯矩阵:(解决邻接节点较多的节点,有更大影响的问题)
Data = namedtuple('Data', ['x', 'y', 'adjacency',
'train_mask', 'val_mask', 'test_mask'])
def tensor_from_numpy(x, device): #将数据从数组格式转换为tensor格式 并转移到相关设备上
return torch.from_numpy(x).to(device)
class CoraData(object):
#数据集下载链接
download_url = "https://raw.githubusercontent.com/kimiyoung/planetoid/master/data"
#数据集中包含的文件名
filenames = ["ind.cora.{}".format(name) for name in
['x', 'tx', 'allx', 'y', 'ty', 'ally', 'graph', 'test.index']]
def __init__(self, data_root="cora", rebuild=False):
"""Cora数据,包括数据下载,处理,加载等功能
当数据的缓存文件存在时,将使用缓存文件,否则将下载、进行处理,并缓存到磁盘
处理之后的数据可以通过属性 .data 获得,它将返回一个数据对象,包括如下几部分:
* x: 节点的特征,维度为 2708 * 1433,类型为 np.ndarray
* y: 节点的标签,总共包括7个类别,类型为 np.ndarray
* adjacency: 邻接矩阵,维度为 2708 * 2708,类型为 scipy.sparse.coo.coo_matrix
* train_mask:



被折叠的 条评论
为什么被折叠?



