• PyTorch搭建图卷积神经网络(GCN)完成对论文分类及预测实战(附源码和数据集)


    需要数据集和源码请点赞关注收藏后评论区留言~~~

    一、数据集简介

    我们将使用Cora数据集

    该数据集共2708个样本点,每个样本点都是一篇科学论文,所有样本点被分为7个类别,类别分别是1)基于案例;2)遗传算法;3)神经网络;4)概率方法;5)强化学习;6)规则学习;7)理论

    每篇论文都由一个1433维的词向量表示,所以,每个样本点具有1433个特征。词向量的每个元素都对应一个词,且该元素只有0或1两种取值。取0表示该元素对应的词不在论文中,取1表示在论文中。所有的词来源于一个具有1433个词的字典。

    每篇论文都至少引用了一篇其他论文,或者被其他论文引用,也就是样本点之间存在联系,没有任何一个样本点与其他样本点完全没联系。如果将样本点看作图中的点,则这是一个连通的图,不存在孤立点。

    数据集主要文件有两个:cora.cites, cora.content。其中,cora.content包含了2708个样本的具体信息,每行代表一个论文样本,格式为

    <论文id>  <由01组成的1433维特征>  <论文类别(label)>

    总的来说,如果将论文当作“图”的节点,则引用关系则为“图”的边,论文节点信息和引用关系共同构成了图数据。本次实验,我们将利用这些信息,对论文所属的类别进行预测,完成关于论文类别的分类任务。

    二、图神经网络与图卷积神经网络简介

     图神经网络(Graph Neural Networks, GNN)作为新的人工智能学习模型,可以将实际问题看作图数据中节点之间的连接和消息传播问题,对节点之间的依赖关系进行建模,挖掘传统神经网络无法分析的非欧几里得空间数据的潜在信息。在自然语言处理、计算机视觉、生物化学等领域中,图神经网络得到广泛的应用,并发挥着重要作用。

    图卷积神经网络(Graph Convolutional Networks, GCN)是目前主流的图神经网络分支,分类任务则是机器学习中的常见任务。我们将利用GCN算法完成分类任务,进一步体会理解图神经网络工作的原理、GCN的构建实现过程,以及如何将GCN应用于分类任务。

    三、运行效果

    如下图 可见随着训练次数的增加,损失率在下降,精确度在上升,大概在200次左右收敛。

     

     

     

     四、部分源码

    主测试类代码如下

    1. from __future__ import division
    2. from __future__ import print_function
    3. import os
    4. os.environ["KMP_DUPLICATE_LIB_OK"]="TRUE"
    5. import time
    6. import argparse
    7. import numpy as np
    8. from torch.utils.data import DataLoader
    9. import torch
    10. import torch.nn.functional as F
    11. import torch.optim as optim
    12. from utils import load_data, accuracy
    13. from models import GCN
    14. import matplotlib.pyplot as plt
    15. # Training settings
    16. parser = argparse.ArgumentParser()
    17. parser.add_argument('--no-cuda', action='store_true', default=False,
    18. help='Disables CUDA training.')
    19. parser.add_argument('--fastmode', action='store_true', default=False,
    20. help='Validate during training pass.')
    21. parser.add_argument('--seed', type=int, default=42, help='Random seed.')
    22. parser.add_argument('--epochs', type=int, default=300,
    23. help='Number of epochs to train.')
    24. parser.add_argument('--lr', type=float, default=0.01,
    25. help='Initial learning rate.')
    26. parser.add_argument('--weight_decay', type=float, default=5e-4,
    27. help='Weight decay (L2 loss on parameters).')
    28. parser.add_argument('--hidden', type=int, default=16,
    29. help='Number of hidden units.')
    30. parser.add_argument('--dropout', type=float, default=0.5,
    31. help='Dropout rate (1 - keep probability).')
    32. args = parser.parse_args()
    33. args.cuda = not args.no_cuda and torch.cuda.is_available()
    34. .manual_seed(args.seed)
    35. # Load data
    36. adj, features, labels, idx_train, idx_val, idx_test = load_data()
    37. # Model and optimizer
    38. model = GCN(nfeat=features.shape[1],
    39. nhid=args.hidden,
    40. nclass=labels.max().item() + 1,
    41. dropout=args.dropout)
    42. optimizer = optim.Adam(model.parameters(),
    43. lr=args.lr, weight_decay=args.weight_decay)
    44. if args.cuda:
    45. model.cuda()
    46. features = features.cuda()
    47. adj = adj.cuda()
    48. labels = labels.cuda()
    49. idx_train = idx_train.cuda()
    50. idx_val = idx_val.cuda()
    51. idx_test = idx_test.cuda()
    52. Loss_list = []
    53. accval=[]
    54. def train(epoch):
    55. t=time.time()
    56. model.train()
    57. optimizer.zero_grad()
    58. output=model(features,adj)
    59. loss_train=F.nll_loss(output[idx_train],labels[idx_train])
    60. acc_train=accuracy(output[idx_train],labels[idx_train])
    61. loss_train.backward()
    62. optimizer.step()
    63. if not args.fastmode:
    64. model.eval()
    65. output=model(features,adj)
    66. loss_val=F.nll_loss(output[idx_val],labels[idx_val])
    67. acc_val=accuracy(output[idx_val],labels[idx_val])
    68. print('Epoch:{:04d}'.format(epoch+1),
    69. 'loss_train:{:.4f}'.format(loss_train.item()),
    70. 'acc_train:{:.4f}'.format(acc_train.item()),
    71. 'loss_val:{:.4f}'.format(loss_val.item()),
    72. 'acc_val:{:.4f}'.format(acc_val.item()),
    73. 'time:{:.4f}s'.format(time.time()-t))
    74. Loss_list.append(loss_train.item())
    75. Accuracy_list.append(acc_train.item())
    76. lossval.append(loss_val.item())
    77. accval.append(acc_val.item())
    78. def test():
    79. model.eval()
    80. output = model(features, adj)
    81. loss_test = F.nll_loss(output[idx_test], labels[idx_test])
    82. acc_test = accuracy(output[idx_test], labels[idx_test])
    83. print("Test set results:",
    84. "loss= {:.4f}".format(loss_test.item()),
    85. "accuracy= {:.4f}".format(acc_test.item()))
    86. acc=acc_test.detach().numpy()
    87. loss=loss_test.detach().numpy()
    88. print(type(loss_test))
    89. print(type(acc_test))
    90. # 定义两个数组
    91. # Train model
    92. t_total = time.time()
    93. for epoch in range(args.epochs):
    94. train(epoch)
    95. print("Optimization Finished!")
    96. printal time elapsed: {:.4f}s".format(time.time() - t_total))
    97. '''
    98. plt.plot([i for i in range(len(Loss_list))],Loss_list)
    99. pplot([i for i in range(len(Accuracy_list))],Accuracy_list)
    100. '''
    101. plt.plot([i for i in range(len(lossval))],lossval)
    102. plot([i for i in range(len(accval))],accval)
    103. print(type(Loss_list))
    104. print(type(Accuracy_list))
    105. #plt.plot([i for i in range(len(Accuracy_list),Accuracy_list)])
    106. plt.show()
    107. # Testing
    108. test()

    模型类如下

    1. import torch.nn as nn
    2. import torch.nn.functional as F
    3. from layers import GraphConvolution
    4. class GCN(nn.Module):
    5. def __init__(self, nfeat, nhid, nclass, dropout):
    6. super(GCN, self).__init__()
    7. self.gc1 = GraphConvolution(nfeat, nhid)
    8. on(nhid, nclass)
    9. self.dropout = dropout
    10. def forward(self, x, adj):
    11. x=F.relu(self.gc1(x,adj))
    12. x=F.dropout(x,self.dropout,training=self.training)
    13. x=self.gc2(x,adj)
    14. return F.log_softmax(x,dim=1)

    layer类如下

    1. import math
    2. import torch
    3. from torch.nn.parameter import Parameter
    4. from torch.nn.modules.module import Module
    5. class GraphConvolution(Module):
    6. """
    7. Simple GCN layer, similar to https://arxiv.org/abs/1609.02907
    8. """
    9. def __init__(self, in_features, out_features, bias=True):
    10. super(GraphConvolution, self).__init__()
    11. self.in_features=in_features
    12. self.out_features=out_features
    13. self.weight=Parameter(torch.FloatTensor(in_features,out_features))
    14. if bias:
    15. self.bias=Parameter(torch.FloatTensor(out_features))
    16. else:
    17. self.register_parameter('bias',None)
    18. self.reset_parameters()
    19. def reset_parameters(self):
    20. stdv = 1. / math.sqrt(self.weight.size(1))
    21. self.weight.data.uniform_(-stdv, stdv)
    22. if self.bias is not None:
    23. self.bias.data.uniform_(-stdv, stdv)
    24. def forward(self, input, adj):
    25. support=torch.mm(input,self.weight)
    26. output=torch.spmm(adj,support)
    27. if self.bias is not None:
    28. return output+self.bias
    29. else:
    30. return output
    31. def __repr__(self):
    32. return self.__class__.__name__ + ' (' \
    33. + str(self.in_features) + ' -> ' \
    34. + str(self.out_features) + ')'

    util类如下

    1. import numpy as np
    2. import scipy.sparse as sp
    3. import torch
    4. def encode_onehot(labels):
    5. classes = set(labels)
    6. classes_dict = {c: np.identity(len(classes))[i, :] for i, c in
    7. enumerate(classes)}
    8. labels_onehot = np.array(list(map(classes_dict.get, labels)),
    9. dtype=np.int32)
    10. return labels_onehot
    11. def load_data(path="data/cora/", dataset="cora"):
    12. """Load citation network dataset (cora only for now)"""
    13. print('Loading {} dataset...'.format(dataset))
    14. idx_features_labels = np.genfromtxt("{}{}.content".format(path, dataset),
    15. dtype=np.dtype(str))
    16. features = sp.csr_matrix(idx_features_labels[:, 1:-1], dtype=np.float32)
    17. labels = encode_onehot(idx_features_labels[:, -1])
    18. # build graph
    19. idx = np.array(idx_features_labels[:, 0], dtype=np.int32)
    20. idx_map = {j: i for i, j in enumerate(idx)}
    21. edges_unordered = np.genfromtxt("{}{}.cites".format(path, dataset),
    22. dtype=np.int32)
    23. edges = np.array(list(map(idx_map.get, edges_unordered.flatten())),
    24. dtype=np.int32).reshape(edges_unordered.shape)
    25. adj = sp.coo_matrix((np.ones(edges.shape[0]), (edges[:, 0], edges[:, 1])),
    26. shape=(labels.shape[0], labels.shape[0]),
    27. dtype=np.float32)
    28. # build symmetric adjacency matrix
    29. adj = adj + adj.T.multiply(adj.T > adj) - adj.multiply(adj.T > adj)
    30. features = normalize(features)
    31. adj = normalize(adj + sp.eye(adj.shape[0]))
    32. idx_train = range(140)
    33. idx_val = range(200, 500)
    34. idx_test = range(500, 1500)
    35. features = torch.FloatTensor(np.array(features.todense()))
    36. labels = torch.LongTensor(np.where(labels)[1])
    37. adj = sparse_mx_to_torch_sparse_tensor(adj)
    38. idx_train = torch.LongTensor(idx_train)
    39. idx_val = torch.LongTensor(idx_val)
    40. idx_test = torch.LongTensor(idx_test)
    41. return adj, features, labels, idx_train, idx_val, idx_test
    42. def normalize(mx):
    43. """Row-normalize sparse matrix"""
    44. rowsum = np.array(mx.sum(1))
    45. r_inv = np.power(rowsum, -1).flatten()
    46. r_inv[np.isinf(r_inv)] = 0.
    47. r_mat_inv = sp.diags(r_inv)
    48. mx = r_mat_inv.dot(mx)
    49. return mx
    50. de_to_torch_sparse_tensor(sparse_mx):
    51. """Convert a scipy sparse matrix to a torch sparse tensor."""
    52. sparse_mx = sparse_mx.tocoo().astype(np.float32)
    53. indices = torch.from_numpy(
    54. np.vstack((sparse_mx.row, sparse_mx.col)).astype(np.int64))
    55. values = torch.from_numpy(sparse_mx.data)
    56. shape = torch.Size(sparse_mx.shape)
    57. return torch.sparse.FloatTensor(indices, values, shape)

    创作不易 觉得有帮助请点赞关注收藏~~~

  • 相关阅读:
    患上肝内胆管结石症状有哪些?
    linux学习(5)—— 项目部署
    docker安装oracle
    [单片机框架][bsp层][N32G4FR][bsp_flash] flash配置和使用
    不变矩特征在数字验证码识别中的应用研究-含Matlab代码
    汽配制造的智能化转型,百度智能云与海力达释义 “数实融合”
    Hive大数据项目环境搭建:安装部署Hive(超详细)
    Linux虚拟网络设备—Veth Pair
    BFS之最短路径
    网络编程扩展
  • 原文地址:https://blog.csdn.net/jiebaoshayebuhui/article/details/127820577