GCN实战深入浅出图神经网络第五章:基于Cora数据集的GCN节点分类 代码分析

GCN实战深入浅出图神经网络第五章:基于Cora数据集的GCN节点分类 代码分析

开源代码:https://github.com/MGzhou/gcn-model

SetUp,库声明

In [2]:

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

数据准备

Cora数据集说明

├── gcn
│   ├── data          //图数据
│   │   ├── ind.citeseer.allx
│   │   ├── ind.citeseer.ally
│   │   ├── ind.citeseer.graph
│   │   ├── ind.citeseer.test.index
│   │   ├── ind.citeseer.tx  # 1
│   │   ├── ind.citeseer.ty  # 2
│   │   ├── ind.citeseer.x   # 3
│   │   ├── ind.citeseer.y   # 4
│   │   ├── ind.cora.allx
│   │   ├── ind.cora.ally
│   │   ├── ind.cora.graph
│   │   ├── ind.cora.test.index
│   │   ├── ind.cora.tx
│   │   ├── ind.cora.ty
│   │   ├── ind.cora.x
│   │   ├── ind.cora.y
│   │   ├── ind.pubmed.allx
│   │   ├── ind.pubmed.ally
│   │   ├── ind.pubmed.graph
│   │   ├── ind.pubmed.test.index
│   │   ├── ind.pubmed.tx
│   │   ├── ind.pubmed.ty
│   │   ├── ind.pubmed.x
│   │   └── ind.pubmed.y
│   ├── __init__.py
│   ├── inits.py    //初始化的公用函数
│   ├── layers.py   //GCN层定义
│   ├── metrics.py  //评测指标的计算
│   ├── models.py   //模型结构定义
│   ├── train.py    //训练
│   └── utils.py    //工具函数的定义
├── LICENCE
├── README.md
├── requirements.txt
└── setup.py


实验时可能出现数据集下载出错的问题,可以自行下载,放进程序预定的文件夹即可

链接:https://pan.baidu.com/s/13JZDlHAlPow0FRtkwzJN8Q
提取码:7fay

image-20201112090241667

cora读取的文件说明:

ind.cora.x => 训练实例的特征向量,是scipy.sparse.csr.csr_matrix类对象,shape:(140, 1433),由于ind.cora.x的数据包含于 allx 中,所以实验中没有读取 x
ind.cora.tx => 测试实例的特征向量,shape:(1000, 1433)
ind.cora.allx => 有标签的+无无标签训练实例的特征向量,是ind.dataset_str.x的超集,shape:(1708, 1433)

# 实验中的完整的特征向量是有(allx,tx)拼接而成,(2708,1433),在实际训练是整体训练,只有当要计算损失值和精确度时才用掩码从(allx,tx)截取相应的输出

ind.cora.y => 训练实例的 标签,独热编码,numpy.ndarray类的实例,是numpy.ndarray对象,shape:(140, 7)
ind.cora.ty => 测试实例的标签,独热编码,numpy.ndarray类的实例,shape:(1000, 7)
ind.cora.ally => 对应于ind.dataset_str.allx的标签,独热编码,shape:(1708, 7)

# 同样是(ally,ty)拼接

ind.cora.graph => 图数据,collections.defaultdict类的实例,格式为 {index:[index_of_neighbor_nodes]}

ind.cora.test.index => 测试实例的id,(1000,)

In [3]:

Data = namedtuple('Data', ['x', 'y', 'adjacency',
                           'train_mask', 'val_mask', 'test_mask'])


def tensor_from_numpy(x, device):
    return torch.from_numpy(x).to(device)


class CoraData(object):
    download_url = "https://github.com/kimiyoung/planetoid/raw/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: 训练集掩码向量,维度为 2708,当节点属于训练集时,相应位置为True,否则False
            * val_mask: 验证集掩码向量,维度为 2708,当节点属于验证集时,相应位置为True,否则False
            * test_mask: 测试集掩码向量,维度为 2708,当节点属于测试集时,相应位置为True,否则False

        Args:
        -------
            data_root: string, optional
                存放数据的目录,原始数据路径: {data_root}/raw
                缓存数据路径: {data_root}/processed_cora.pkl
            rebuild: boolean, optional
                是否需要重新构建数据集,当设为True时,如果存在缓存数据也会重建数据

        """
        self.data_root = data_root
        save_file = osp.join(self.data_root, "processed_cora.pkl")
        if osp.exists(save_file) and not rebuild:
            print("Using Cached file: {}".format(save_file))
            self._data = pickle.load(open(save_file, "rb"))
        else:
            self.maybe_download()
            self._data = self.process_data()
            with open(save_file, "wb") as f:
                pickle.dump(self.data, f)
            print("Cached file: {}".format(save_file))
    
    @property
    def data(self):
        """返回Data数据对象,包括x, y, adjacency, train_mask, val_mask, test_mask"""
        return self._data

    def process_data(self):
        """
        处理数据,得到节点特征和标签,邻接矩阵,训练集、验证集以及测试集
        引用自:https://github.com/rusty1s/pytorch_geometric
        """
        print("Process data ...")
        _, tx, allx, y, ty, ally, graph, test_index = [self.read_data(
            osp.join(self.data_root, "raw", name)) for name in self.filenames]
        
        # 测试test_index的形状(1000,),如果那里不明白可以测试输出一下矩阵形状
        print('test_index',test_index.shape)
        
        train_index = np.arange(y.shape[0])  # [0,...139] 140个元素
        print('train_index',train_index.shape) 
        
        val_index = np.arange(y.shape[0], y.shape[0] + 500) # [140 - 640] 500个元素
        print('val_index',val_index.shape)  
        
        sorted_test_index = sorted(test_index)  # #test_index就是随机选取的下标,排下序
#         print('test_index',sorted_test_index)

        x = np.concatenate((allx, tx), axis=0)  # 1708 +1000 =2708 特征向量
        y = np.concatenate((ally, ty), axis=0).argmax(axis=1) # 把最大值的下标重新作为一个数组 标签向量
        
        x[test_index] = x[sorted_test_index]  # 打乱顺序,单纯给test_index 的数据排个序,不清楚具体效果
        y[test_index] = y[sorted_test_index]
        num_nodes = x.shape[0]  #2078

        train_mask = np.zeros(num_nodes, dtype=np.bool)  # 生成零向量
        val_mask = np.zeros(num_nodes, dtype=np.bool)
        test_mask = np.zeros(num_nodes, dtype=np.bool)
        train_mask[train_index] = True  # 前140个元素为训练集
        val_mask[val_index] = True  # 140 -639 500个
        test_mask[test_index] = True  # 1708-2708 1000个元素
        
        #下面两句是我测试用的,本来代码没有
        #是为了知道使用掩码后,y_train_mask 的形状,由输出来说是(140,)
        # 这就是后面划分训练集的方法
        y_train_mask = y[train_mask]
        print('y_train_mask',y_train_mask.shape)
        
        #构建邻接矩阵
        adjacency = self.build_adjacency(graph)
        print("Node's feature shape: ", x.shape)
        print("Node's label shape: ", y.shape)
        print("Adjacency's shape: ", adjacency.shape)
        print("Number of training nodes: ", train_mask.sum())
        print("Number of validation nodes: ", val_mask.sum())
        print("Number of test nodes: ", test_mask.sum())

        return Data(x=x, y=y, adjacency=adjacency,
                    train_mask=train_mask, val_mask=val_mask, test_mask=test_mask)

    def maybe_download(self):
        save_path = os.path.join(self.data_root, "raw")
        for name in self.filenames:
            if not osp.exists(osp.join(save_path, name)):
                self.download_data(
                    "{}/{}".format(self.download_url, name), save_path)

    @staticmethod
    def build_adjacency(adj_dict):
        """根据邻接表创建邻接矩阵"""
        edge_index = []
        num_nodes = len(adj_dict)
        print('num_nodesaaaaaaaaaaaa',num_nodes)
        for src, dst in adj_dict.items():  # 格式为 {index:[index_of_neighbor_nodes]}
            edge_index.extend([src, v] for v in dst)  # 
            edge_index.extend([v, src] for v in dst)
            
        # 去除重复的边
        edge_index = list(k for k, _ in itertools.groupby(sorted(edge_index)))  # 以轮到的元素为k,每个k对应一个数组,和k相同放进数组,不
                                                                                # 同再生成一个k,sorted()是以第一个元素大小排序
        
        edge_index = np.asarray(edge_index)
        
        #稀疏矩阵 存储非0值 节省空间
        adjacency = sp.coo_matrix((np.ones(len(edge_index)), 
                                   (edge_index[:, 0], edge_index[:, 1])),
                    shape=(num_nodes, num_nodes), dtype="float32")
        return adjacency

    @staticmethod
    def read_data(path):
        """使用不同的方式读取原始数据以进一步处理"""
        name = osp.basename(path)
        if name == "ind.cora.test.index":
            out = np.genfromtxt(path, dtype="int64")
            return out
        else:
            out = pickle.load(open(path, "rb"), encoding="latin1")
            out = out.toarray() if hasattr(out, "toarray") else out
            return out

    @staticmethod
    def download_data(url, save_path):
        """数据下载工具,当原始数据不存在时将会进行下载"""
        if not os.path.exists(save_path):
            os.makedirs(save_path)
        data = urllib.request.urlopen(url)
        filename = os.path.split(url)[-1]

        with open(os.path.join(save_path, filename), 'wb') as f:
            f.write(data.read())

        return True

    @staticmethod
    def normalization(adjacency):
        """计算 L=D^-0.5 * (A+I) * D^-0.5"""
        adjacency += sp.eye(adjacency.shape[0])    # 增加自连接
        degree = np.array(adjacency.sum(1))
        d_hat = sp.diags(np.power(degree, -0.5).flatten())
        return d_hat.dot(adjacency).dot(d_hat).tocoo()  #返回稀疏矩阵的coo_matrix形式

# 这样可以单独测试Process_data函数
a = CoraData()
a.process_data()


Out[3]:

Using Cached file: cora\processed_cora.pkl
Process data ...
test_index (1000,)
train_index (140,)
val_index (500,)
y_train_mask (140,)
num_nodesaaaaaaaaaaaa 2708
Node's feature shape:  (2708, 1433)
Node's label shape:  (2708,)
Adjacency's shape:  (2708, 2708)
Number of training nodes:  140
Number of validation nodes:  500
Number of test nodes:  1000
Data(x=array([[0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       ...,
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.]], dtype=float32), y=array([3, 4, 4, ..., 3, 3, 3], dtype=int64), adjacency=<2708x2708 sparse matrix of type '<class 'numpy.float32'>'
	with 10556 stored elements in COOrdinate format>, train_mask=array([ True,  True,  True, ..., False, False, False]), val_mask=array([False, False, False, ..., False, False, False]), test_mask=array([False, False, False, ...,  True,  True,  True]))

图卷积层定义

In [13]:

class GraphConvolution(nn.Module):
    def __init__(self, input_dim, output_dim, use_bias=True):
        """图卷积:L*X*\theta
        
        完整GCN函数
        f = sigma(D^-1/2 A D^-1/2 * H * W)
        卷积是D^-1/2 A D^-1/2 * H * W
        adjacency = D^-1/2 A D^-1/2 已经经过归一化,标准化的拉普拉斯矩阵
        
        这样就把傅里叶变化和拉普拉斯矩阵结合起来了.
        
        Args:
        ----------
            input_dim: int
                节点输入特征的维度
            output_dim: int
                输出特征维度
            use_bias : bool, optional
                是否使用偏置
        """
        super(GraphConvolution, self).__init__()
        
        
        self.input_dim = input_dim
        self.output_dim = output_dim
        self.use_bias = use_bias
        
        # 定义GCN层的 W 权重形状
        self.weight = nn.Parameter(torch.Tensor(input_dim, output_dim))
        
        #定义GCN层的 b 权重矩阵
        if self.use_bias:
            self.bias = nn.Parameter(torch.Tensor(output_dim))
        else:
            self.register_parameter('bias', None)
        self.reset_parameters()
        
    # 这里才是声明初始化 nn.Module 类里面的W,b参数
    def reset_parameters(self):
        init.kaiming_uniform_(self.weight)
        if self.use_bias:
            init.zeros_(self.bias)

    def forward(self, adjacency, input_feature):
        """邻接矩阵是稀疏矩阵,因此在计算时使用稀疏矩阵乘法
    
        Args: 
        -------
            adjacency: torch.sparse.FloatTensor
                邻接矩阵
            input_feature: torch.Tensor
                输入特征
        """
        support = torch.mm(input_feature, self.weight)  # 矩阵相乘 m由matrix缩写
        output = torch.sparse.mm(adjacency, support)  # sparse 稀疏的
        if self.use_bias:
            output += self.bias  # bias 偏置,偏见
        return output
    
    # 一般是为了打印类实例的信息而重写的内置函数
    def __repr__(self):
        return self.__class__.__name__ + ' (' \
            + str(self.input_dim) + ' -> ' \
            + str(self.output_dim) + ')'

模型定义

读者可以自己对GCN模型结构进行修改和实验

In [14]:

class GcnNet(nn.Module):
    """
    定义一个包含两层GraphConvolution的模型
    """
    def __init__(self, input_dim=1433):
        super(GcnNet, self).__init__()
        self.gcn1 = GraphConvolution(input_dim, 16) #(N,1433)->(N,16)
        self.gcn2 = GraphConvolution(16, 7) #(N,16)->(N,7)
    
    def forward(self, adjacency, feature):
        h = F.relu(self.gcn1(adjacency, feature)) #(N,1433)->(N,16),经过relu函数
        logits = self.gcn2(adjacency, h) #(N,16)->(N,7)
        return logits

模型训练

In [16]:

# 超参数定义
LEARNING_RATE = 0.1 #学习率
WEIGHT_DACAY = 5e-4  #正则化系数 weight_dacay
EPOCHS = 200 #完整遍历训练集的次数
DEVICE = "cuda" if torch.cuda.is_available() else "cpu" #设备
# 如果当前显卡忙于其他工作,可以设置为 DEVICE = "cpu",使用cpu运行

In [17]:

# 加载数据,并转换为torch.Tensor
dataset = CoraData().data

node_feature = dataset.x / dataset.x.sum(1, keepdims=True)  # 归一化数据,使得每一行和为1

tensor_x = tensor_from_numpy(node_feature, DEVICE)  # (2708,1433)
tensor_y = tensor_from_numpy(dataset.y, DEVICE)  #(2708,)

tensor_train_mask = tensor_from_numpy(dataset.train_mask, DEVICE) #前140个为True
tensor_val_mask = tensor_from_numpy(dataset.val_mask, DEVICE)  # 140 - 639  500个
tensor_test_mask = tensor_from_numpy(dataset.test_mask, DEVICE) # 1708 - 2707 1000个

normalize_adjacency = CoraData.normalization(dataset.adjacency)   # 规范化邻接矩阵 计算 L=D^-0.5 * (A+I) * D^-0.5

num_nodes, input_dim = node_feature.shape  # 2708,1433

# 原始创建coo_matrix((data, (row, col)), shape=(4, 4)) indices为index复数 https://blog.csdn.net/chao2016/article/details/80344828?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522160509865819724838529777%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=160509865819724838529777&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_v2~rank_v28-2-80344828.pc_first_rank_v2_rank_v28&utm_term=%E7%A8%80%E7%96%8F%E7%9F%A9%E9%98%B5%E7%9A%84coo_matrix&spm=1018.2118.3001.4449
indices = torch.from_numpy(np.asarray([normalize_adjacency.row, 
                                       normalize_adjacency.col]).astype('int64')).long()

values = torch.from_numpy(normalize_adjacency.data.astype(np.float32))

tensor_adjacency = torch.sparse.FloatTensor(indices, values, 
                                            (num_nodes, num_nodes)).to(DEVICE)
#根据三元组 构造 稀疏矩阵向量,构造出来的张量是 (2708,2708)

In [18]:

# 模型定义:Model, Loss, Optimizer
model = GcnNet(input_dim).to(DEVICE)
criterion = nn.CrossEntropyLoss().to(DEVICE)  # criterion评判标准
optimizer = optim.Adam(model.parameters(),    # optimizer 优化程序 ,使用Adam 优化方法,权重衰减https://blog.csdn.net/program_developer/article/details/80867468
                       lr=LEARNING_RATE, 
                       weight_decay=WEIGHT_DACAY)

In [8]:

# 训练主体函数
def train():
    loss_history = []
    val_acc_history = []
    model.train() 
    
    train_y = tensor_y[tensor_train_mask]  # shape=(140,)不是(2708,)了
    # 共进行200次训练
    for epoch in range(EPOCHS):
        logits = model(tensor_adjacency, tensor_x)  # 前向传播,认为因为声明了 model.train(),不用forward了
        train_mask_logits = logits[tensor_train_mask]   # 只选择训练节点进行监督 (140,)
        
        loss = criterion(train_mask_logits, train_y)    # 计算损失值  
        optimizer.zero_grad()  # 梯度归零
        loss.backward()     # 反向传播计算参数的梯度
        optimizer.step()    # 使用优化方法进行梯度更新
        
        
        train_acc, _, _ = test(tensor_train_mask)     # 计算当前模型训练集上的准确率  调用test函数
        val_acc, _, _ = test(tensor_val_mask)     # 计算当前模型在验证集上的准确率
        
        # 记录训练过程中损失值和准确率的变化,用于画图
        loss_history.append(loss.item())
        val_acc_history.append(val_acc.item())
        print("Epoch {:03d}: Loss {:.4f}, TrainAcc {:.4}, ValAcc {:.4f}".format(
            epoch, loss.item(), train_acc.item(), val_acc.item()))
    
    return loss_history, val_acc_history

In [9]:

# 测试函数
def test(mask):
    model.eval()  # 表示将模型转变为evaluation(测试)模式,这样就可以排除BN和Dropout对测试的干扰
    
    with torch.no_grad():  # 显著减少显存占用
        logits = model(tensor_adjacency, tensor_x) #(N,16)->(N,7) N节点数
        test_mask_logits = logits[mask]  # 矩阵形状和mask一样
        
        predict_y = test_mask_logits.max(1)[1]  # 返回每一行的最大值中索引(返回最大元素在各行的列索引)
        accuarcy = torch.eq(predict_y, tensor_y[mask]).float().mean()
    return accuarcy, test_mask_logits.cpu().numpy(), tensor_y[mask].cpu().numpy()

In [13]:

def plot_loss_with_acc(loss_history, val_acc_history):
    fig = plt.figure()
    # 坐标系ax1画曲线1
    ax1 = fig.add_subplot(111)  # 指的是将plot界面分成1行1列,此子图占据从左到右从上到下的1位置
    ax1.plot(range(len(loss_history)), loss_history,
             c=np.array([255, 71, 90]) / 255.)  # c为颜色
    plt.ylabel('Loss')
    
    # 坐标系ax2画曲线2
    ax2 = fig.add_subplot(111, sharex=ax1, frameon=False)  # 其本质就是添加坐标系,设置共享ax1的x轴,ax2背景透明
    ax2.plot(range(len(val_acc_history)), val_acc_history,
             c=np.array([79, 179, 255]) / 255.)
    ax2.yaxis.tick_right()  # 开启右边的y坐标
    
    ax2.yaxis.set_label_position("right")
    plt.ylabel('ValAcc')
    
    plt.xlabel('Epoch')
    plt.title('Training Loss & Validation Accuracy')
    plt.show()

In [ ]:

loss, val_acc = train()
test_acc, test_logits, test_label = test(tensor_test_mask)
print("Test accuarcy: ", test_acc.item())

In [14]:

plot_loss_with_acc(loss, val_acc)

image-20201112091908533

  • 18
    点赞
  • 85
    收藏
    觉得还不错? 一键收藏
  • 14
    评论
### 回答1: GCN(Graph Convolutional Network)是一种用于结构数据的深度学习模型,而Cora数据集是一个常用的用于研究GCN模型性能的基准数据集Cora数据集是由论文《Revisiting Semi-Supervised Learning with Graph Embeddings》中提出的,用于研究半监督学习与嵌入方法。它包含了一个引文网络,其中节点代表了学术论文,边表示两篇论文之间的引用关系。数据集中的每篇论文都有一个包含1433个特征的特征向量,这些特征向量是通过将每篇论文的标题和摘要转化为词向量、计算TF-IDF得到的。 在Cora数据集中,论文被分为7个不同的类别(如机器学习、神经网络、数据库等)。数据集总共包含2708个节点(论文),其中有140个节点(论文)带有类别标签,其余节点没有标签。因此,Cora数据集被广泛用于基于结构的半监督学习问题的研究中。 GCN模型可以用于Cora数据集的半监督学习任务。模型接受Cora数据集的邻接矩阵和特征矩阵作为输入。通过对邻接矩阵进行卷积操作,并结合特征矩阵,GCN模型能够通过学习节点之间的关系以及节点的特征信息来预测未标记节点的标签。 研究者可以使用Cora数据集来验证自己所提出的GCN模型在半监督学习任务上的性能。当然,Cora数据集也可以用于其他与引文网络相关的研究,如节点分类、链路预测等。 总而言之,Cora数据集为研究者提供了一个用于验证GCN模型性能以及进行其他引文网络相关研究的标准数据集,通过该数据集可以促进神经网络领域的发展。 ### 回答2: GCN(Graph Convolutional Network)是一种用于数据学习的深度学习模型,可以学习节点的表示和的关系。Cora数据集是一个常用的数据集,用于评估和比较不同的学习算法。 Cora数据集包含一个包含2708个科学论文的引文网络。这些论文分为7个类别,其中每个类别对应着一个研究领域。引文网络的节点表示论文,边表示论文间的引用关系。论文的特征向量是词频的One-Hot编码,而边缘是无向的。 在使用GCNCora数据集进行训练时,首先需要将结构转换为邻接矩阵的表示。邻接矩阵中的每个元素代表两个节点之间的连接情况。随后,需要为每个节点生成初试的特征向量表示。GCN模型通过多层的卷积操作来学习节点表示。 在训练过程中,GCN会通过前向传播和反向传播来更新权重,使得模型能够尽可能地准确地预测每个节点的类别。通过迭代训练,GCN模型可以逐渐提升对节点表示和结构关系的学习能力。 在使用Cora数据集进行训练时,我们可以评估模型在节点分类任务上的性能。即给定一个节点,预测其所属的类别。通常,我们可以将数据集划分为训练集、验证集和测试集,并使用验证集来调整超参数,通过测试集来评估模型的泛化能力。 总之,GCN模型是一种用于数据学习的强大工具,在Cora数据集上的应用可以帮助我们更好地理解和分析引文网络中的关系。 ### 回答3: GCN(Graph Convolutional Network)是一种用于数据的深度学习模型,而Cora数据集则是用于GNN模型训练和评估的常用数据集之一。 Cora数据集是由Jon Kleinberg设计和发布的,用于文本分类任务。该数据集包含了从一系列研究论文中提取出的2708个文档的特征。这些文档分为7个类别,即机器学习、数据库、人类智能、设计与分析、系统、理论和数据结构。同时,这些文档之间的引用关系被用作结构,通过边来表示不同文档之间的引用关系。这个表示了论文之间的知识传播和交互。 在GCN中,每个节点代表一个文档,而边代表了文档之间的引用关系。对于Cora数据集而言,每个节点都有一个特征向量,包含了关于论文的内容信息。GCN模型通过使用卷积神经网络的聚合操作来从邻居节点中汇聚信息,并将这些信息进行特征提取和表示学习。 训练一个GCN模型需要将Cora数据集划分为训练集、验证集和测试集。通常,将140个样本用作训练集,500个样本用作验证集,剩余的2068个样本用作测试集。在训练过程中,GCN模型将根据训练集上的标签信息进行参数反向传播和优化,以减小预测标签与真实标签之间的差距。 通过训练GCN模型,并使用Cora数据集进行评估,我们可以评估GCN模型在文本分类任务中的性能。通过计算模型在测试集上的准确率或其他性能指标,我们可以了解其在准确地预测不同文档的类别方面的能力。在实际应用中,GCN模型和Cora数据集可以被用于许多数据相关的任务,如社交网络分析、推荐系统等。
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值