【代码解析(4)】Federated Social Recommendation with Graph Neural Network

GAT(GraphAttentionNetwork)是一种利用自注意机制学习节点嵌入的图神经网络层。它通过应用注意力机制聚合邻居节点信息,其中包含了用户-用户和用户-项目的关系。在GAT层中,W矩阵用于线性变换,a向量用于计算注意力权重,经过LeakyReLU和softmax函数处理后形成注意权重,最后通过加权聚合得到节点的新嵌入表示。
摘要由CSDN通过智能技术生成

GAT.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Python version: 3.7

import numpy as np
import torch
import torch.nn as nn
import torch.nn.functional as F
import pdb
''' 
    *****user调用model调用GAT*****
    
    (1) 采用GAT层学习节点嵌入
    (2) GAT层通过应用自注意机制设计
    (3) 采用注意层聚合社交邻居和项目邻居
    (4) 利用本地GAT层最终推断节点嵌入
'''


class GraphAttentionLayer(nn.Module):
    def __init__(self, in_features, out_features, alpha=0.1):
        super().__init__()

        self.in_features = in_features

        self.out_features = out_features

        self.alpha = alpha

        '''self.W是W1, W2'''
        self.W = nn.Parameter(torch.empty(size=(in_features, out_features)))

        nn.init.xavier_uniform_(self.W.data)

        # a为权重向量,attention layer vector for user-user interaction
        self.a = nn.Parameter(torch.empty(size=(2 * out_features, 1)))

        nn.init.xavier_uniform_(self.a.data)

        '''这里的W_1映射权重矩阵是共享的'''
        self.W_1 = nn.Parameter(torch.randn(in_features, out_features))

        # LeakyReLU
        self.leakyrelu = nn.LeakyReLU(self.alpha)

    def forward(self, h, adj):  # h表示中心节点  adj表示邻居节点(用户邻居、项目邻居)

        """
            GAT是通用的,不仅用于用户-用户(邻居用户),也用户-项目(邻居项目)
            W1W2是映射矩阵,相不相同?要看self.W = nn.Parameter(torch.empty(size=(in_features, out_features)))
            调用GraphAttentionLayer的in_features, out_features相不相同
            model.py中调用了
                self.GAT_neighbor = GraphAttentionLayer(embed_size, embed_size)

                self.GAT_item = GraphAttentionLayer(embed_size, embed_size)
            user调用了model.py
                self.model = model(embed_size)
            embed_size是设定好的

            【【【所以用户邻居的W1和项目邻居的W2是相同的吗?】】】
        """
        # W为user-user交互的线性映射矩阵
        '''h为中心节点u的嵌入'''
        '''对于用户邻居W1*e_un   对于项目邻居W2*e_un'''
        W_h = torch.matmul(h, self.W)

        # W为user-user交互的线性映射矩阵
        '''adj为用户邻居节点的嵌入W1*e_up'''
        '''adj为项目邻居节点的嵌入W2*e_un'''
        W_adj = torch.mm(adj, self.W)

        # 连接层,将两个向量W_h和W_adj串联  [We_un||We_up]
        '''将两个向量W_h和W_adj串联  [W*e_un||W*e_ik]'''
        a_input = torch.cat((W_h.repeat(W_adj.shape[0], 1), W_adj), dim=1)

        '''【【【【(一)两种关系的注意层不同之处】】】'''
        '''对于用户邻居self.a指的是a(user-user交互的注意层权重向量)'''
        '''对于项目邻居self.a指的是b(user-item交互的注意层权重向量)'''
        # 通过注意层     LeakyReLU(a^T[W1e_un||We_up])得到注意力权重attention
        '''对于项目邻居,LeakyReLU(b^T[W2e_un||We_ik]) W2为item-item interaction的线性映射矩阵'''
        attention = self.leakyrelu(torch.matmul(a_input, self.a)).squeeze(-1)

        # 通过softmax层 通过使用softmax函数形成<概率分布>,这里的attention是最终的注意力权重
        '''最终得到用户-邻居(u_n,u_p)的注意权重'''
        '''最终得到用户-项目(u_n,i_k)的注意权重'''
        attention = F.softmax(attention, dim=-1)

        '''推断中心用户嵌入需要将邻居用户节点和邻居项目节点与其关联的注意权重进行聚合'''

        '''这里的W_1映射权重矩阵是共享的'''
        # W*e_up和W*e_tk   W为线性映射权重矩阵
        W_adj_transform = torch.mm(adj, self.W_1)

        '''这里的attention就是得到的归一化注意权重'''
        # 得到聚合用户邻居的隐藏嵌入h_u和聚合项目邻居的隐藏嵌入h_t
        h = torch.matmul(attention, W_adj_transform)

        '''直观地,我们应该聚合隐藏嵌入和中心节点嵌入来推断u_n的嵌入,但是社会关系、用户-项目交互和中心节点嵌入'''
        '''在学习过程中的作用并不相同,我们应该在聚合步骤中处理异构性'''

        return h



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值