【AM-GCN】代码解读之model结构

【AM-GCN】代码解读之model结构,第1张

前篇:
【AM-GCN】代码解读之初了解(一)
【AM-GCN】代码解读之主程序(二)
【AM-GCN】代码解读之utlis(三)
【AM-GCN】论文解读


该篇讲解具有前后联系的:layers.pymodels.py

壹、文件 layers.py

一、导入库

import math
import torch
from torch.nn.parameter import Parameter
from torch.nn.modules.module import Module

二、GCN卷积层

class GraphConvolution(Module):
    def __init__(self, in_features, out_features, bias=True):
        super(GraphConvolution, self).__init__()
        self.in_features = in_features
        self.out_features = out_features
        self.weight = Parameter(torch.FloatTensor(in_features, out_features))
        if bias:
            self.bias = Parameter(torch.FloatTensor(out_features))
        else:
            self.register_parameter('bias', None)
        self.reset_parameters()

    def reset_parameters(self):
        stdv = 1. / math.sqrt(self.weight.size(1))
        self.weight.data.uniform_(-stdv, stdv)
        if self.bias is not None:
            self.bias.data.uniform_(-stdv, stdv)

    def forward(self, input, adj):
        support = torch.mm(input, self.weight)
        output = torch.spmm(adj, support)
        if self.bias is not None:
            return output + self.bias
        else:
            return output

    def __repr__(self):
        return self.__class__.__name__ + ' (' \
               + str(self.in_features) + ' -> ' \
               + str(self.out_features) + ')'

这是所有图卷积层的基础框架,大同小异。



如果不明白的话,可以查看链接 《torch搭建GCN的详细介绍》
根据我个人的修改经验,在自己搭建框架的时候只需要注意两点:

  1. reset_parameters()中初始化的方法(不了解可查看超链接):
    • self.weight.data.uniform_(-stdv, stdv)[原文]
    • init.kaiming_uniform_(self.weight)[具体见下]
    def reset_parameters(self):
        """
        数据初始化的方法
        """
        init.kaiming_uniform_(self.weight)
        if self.use_bias:
            init.zeros_(self.bias)
  1. 矩阵的乘法(非点乘,可点开查看超链接)。


    有的A是稀疏的,有的不是,有的是二维乘法有的是多维乘法。


    根据不同情况,选择合适的函数。


    • torch.mm (仅试用于二维矩阵)
    • torch.matmul (多维矩阵乘法)
    • torch.spmm 稀疏矩阵乘法
    • torch.sparse.mm 稀疏矩阵乘法

贰、文件models.py

一、导入库

import torch.nn as nn #torch中定义好的神经网络层
import torch.nn.functional as F #torch中自带的一些函数
import torch

from layers import GraphConvolution #导入从前面定义好的GCN层

二、搭建GCN模块

class GCN(nn.Module):
    def __init__(self, nfeat, nhid, out, dropout):
        super(GCN, self).__init__()
        self.gc1 = GraphConvolution(nfeat, nhid)
        self.gc2 = GraphConvolution(nhid, out)
        self.dropout = dropout

    def forward(self, x, adj):
        x = F.relu(self.gc1(x, adj))
        x = F.dropout(x, self.dropout, training = self.training)
        x = self.gc2(x, adj)
        return x

1.区别:对GCNlayer和GCNmodule不理解的看过来!

GCNlayer—对应—单层神经网络
GCNmodule—对应—多层神经网络

  1. F.dropout()函数,不理解的可以查看对用链接

原理讲解
易错点


三、注意力机制

class Attention(nn.Module):
    def __init__(self, in_size, hidden_size=16):
        super(Attention, self).__init__()

        self.project = nn.Sequential(
            nn.Linear(in_size, hidden_size),
            nn.Tanh(),
            nn.Linear(hidden_size, 1, bias=False)
        )

    def forward(self, z):
        w = self.project(z)
        beta = torch.softmax(w, dim=1)
        return (beta * z).sum(1), beta

函数解释

  1. nn.Sequential(),是一个Model搭建的容器,按照添加的顺序运行


    如上代码中,添加的顺序为:nn.Linear, nn.Tanh, nn.Linear
    假设没有nn.Sequential这个容器。


    可以等价于如下。


    当Model中的神经层很多的时候比较麻烦。


    而nn.Sequential就可以更方便的书写了。


def __init__(self, in_size, hidden_size=16):
	self.l1 = nn.Linear(in_size, hidden_size)
	self.l2 =nn.Linear(hidden_size, 1, bias=False)
def forward(self, z):
	h1 = self.l1(z)
	h2 = nn.Tanh(h1)
	w = self.l2(h2)
	

可参考:torch.nn.Sequential()讲解,或者,torch.nn.Sequential()搭建神经网络

  1. torch.softmax()

sogtmax公式解析
函数解析
代码演示
用途:用于多分类任务进行分类的。



特点:非线性性,和为1.

  1. 作用:【见论文解读】文章中有三个嵌入:feature graph 的嵌入,topology graph 的嵌入以及 common 嵌入。


    对于这三个嵌入进行“资源分配”的。


    具体可以查看《注意力机制》


四、AM-GCN结构

class SFGCN(nn.Module):
    def __init__(self, nfeat, nclass, nhid1, nhid2, n, dropout):
        super(SFGCN, self).__init__()
        # nfeat特征,nhid1隐藏层1,nhid2隐藏层2,dropout丢弃率
        self.SGCN1 = GCN(nfeat, nhid1, nhid2, dropout) #gcnmodule
        self.SGCN2 = GCN(nfeat, nhid1, nhid2, dropout) #gcnmodule
        self.CGCN = GCN(nfeat, nhid1, nhid2, dropout)  #gcnmodule

        self.dropout = dropout
        self.a = nn.Parameter(torch.zeros(size=(nhid2, 1)))
        nn.init.xavier_uniform_(self.a.data, gain=1.414) # 初始化参数
        self.attention = Attention(nhid2) # 注意力机制
        self.tanh = nn.Tanh()

        self.MLP = nn.Sequential(
            nn.Linear(nhid2, nclass),
            nn.LogSoftmax(dim=1)
        )  # MLP(多层感知机)=神经网络

    def forward(self, x, sadj, fadj):
        emb1 = self.SGCN1(x, sadj) # Special_GCN out1 -- sadj structure graph
        com1 = self.CGCN(x, sadj)  # Common_GCN out1 -- sadj structure graph
        com2 = self.CGCN(x, fadj)  # Common_GCN out2 -- fadj feature graph
        emb2 = self.SGCN2(x, fadj) # Special_GCN out2 -- fadj feature graph
        Xcom = (com1 + com2) / 2
        ##attention
        emb = torch.stack([emb1, emb2, Xcom], dim=1)
        emb, att = self.attention(emb)
        output = self.MLP(emb)
        return output, att, emb1, com1, com2, emb2, emb

代码解析

  1. nn.Lineae():torch中全链接网络
  2. nn.LogSoftmax():torch中的函数,先求softmax函数,再求log函数。


  3. torch.stack:向量拼接

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/607146.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-14
下一篇 2022-04-14

发表评论

登录后才能评论

评论列表(0条)

保存