当前位置: 首页 > news >正文

【论文阅读】Variational Graph Auto-Encoder

0、基本信息

  • 会议:2016-NIPS
  • 作者:Thomas N. Kipf,Max Welling
  • 文章链接:Variational Graph Auto-Encoder
  • 代码链接:Variational Graph Auto-Encoder

1、介绍

本文提出一个变分图自编码器,一个基于变分自编码(VAE)的,用于在图结构数据上无监督学习的框架。其基本思路是:用已知的图(graph)经过编码(图卷积)学到节点向量表示的分布,在分布中采样得到节点的向量表示,然后进行解码(链接预测)重新构建图。

2、创新点

  • 将变分自编码器(VAE)迁移到图领域

3、准备工作

3.1、自编码器(AE)

自编码器由两个部分组成,分别是编码器和解码器,其中编码器通过神经网络,得到原始数据的低维向量表示;解码器也通过神经网络,将低维向量表示还原为原始数据。
下图是自编码器的一个例子:
![[AE.png]]
自编码器的训练目标是最小化重建误差,即使输入和输出保持尽量一致。

3.2、变分自编码器

如果将解码器看做一个生成模型,我们只要有低维向量表示,就可以用这个生成模型得到近似真实的样本。但是,这样的生成模型存在一个问题:低维向量表示必须是由真实样本通过编码器得到的,否则随机产生的低维向量表示通过生成模型几乎不可能得到近似真实的样本。
那么,如果能将低维向量表示约束在一个分布(比如正态分布)中,那么从该分布中随机采样,产生的低维向量表示通过生成模型不是就能产生近似真实的样本了吗?

变分自编码器就是这样的一种自编码器:变分自编码器通过编码器学到的不是样本的低维向量表示,而是低维向量表示的分布。假设这个分布服从正态分布,然后在低维向量表示的分布中采样得到低维向量表示,接下来经过解码器还原出原始样本。
变分自编码器将真实样本 X X X输入变分图自编码器,通过编码器学到每个样本对应的低维向量表示的均值 μ \mu μ和方差 σ 2 \sigma^2 σ2,然后再 N ( μ , σ 2 ) N(\mu,\sigma^2) N(μ,σ2)中采样出变量的表征,再通过解码器(生成器)生成样本 X ^ \hat{X} X^。均值描述了概率分布的期望值,而标准差描述了概率分布的广度。

3.3、图自编码器(GAE)

图自编码器,即Graph Auto-Encoders,简写GAE。图自编码器也由两部分组成,编码器和解码器。

(1)编码器
GAE的编码器是一个简单的两层GCN模型:
Z = G C N ( A , X ) \mathrm{Z} = \mathrm{GCN}\mathrm(A,\mathrm{X}) Z=GCN(A,X)
更具体一些,两层的GCN在论文中定义如下:
G C N ( A , X ) = A ~ R e L U ( A ^ X W 0 ) W 1 \mathrm{GCN(A,X)}=\tilde{A}\mathrm{ReLU(\hat{A}\mathrm{X}\mathrm{W^0})W^1} GCN(A,X)=A~ReLU(A^XW0)W1
其中, A ~ = D − 1 2 A D − 1 2 \tilde{A}=D^{-\frac{1}{2}}AD^{-\frac{1}{2}} A~=D21AD21,即对称归一化邻接矩阵, W 1 W^1 W1 W 0 W^0 W0是GCN需要学习的参数。
通过编码器,我们可以得到结点的嵌入向量 Z Z Z.
(2)解码器
编码器得到节点表示的向量后,通过解码器通过向量的内积来重构邻接矩阵:
A ^ = σ ( Z Z T ) \hat{A} = \sigma{(ZZ^T)} A^=σ(ZZT)
在GAE中,我们需要优化编码器中的 W 0 W^0 W0 W 1 W^1 W1进而使得经解码器重构出的邻接矩阵 A ^ \hat{A} A^ 与原始的邻接矩阵A尽量相似。因为邻居矩阵决定了图的结构,经节点向量表示重构出的邻接矩阵与原始邻接矩阵越相似,说明节点的向量表示越符合图的结构。因此,GAE中的损失函数可以定义如下:
L = − 1 N ∑ ( y l o g ( y ^ ) + ( 1 − y ) l o g ( 1 − y ^ ) ) \mathcal{L}=-\frac{1}{N}\sum (ylog(\hat{y})+(1-y)log(1-\hat{y})) L=N1(ylog(y^)+(1y)log(1y^))
这里 y y y表示原始邻接矩阵A中的元素,其值为0或1; y ^ \hat{y} y^ 为重构的邻接矩阵 A ^ \hat{A} A^中的元素。从上述损失函数可以看出,损失函数的本质就是两个交叉熵损失函数之和。
当然,我们可以对原始论文中的GAE进行扩展,例如编码器可以使用其他的GNN模型。
2.4、KL散度(又叫相对熵)
如果我们对于同一个随机变量 x有两个单独的概率分布 P(x) 和 Q(x),我们可以使用 KL 散度(Kullback-Leibler (KL) divergence)来衡量这两个分布的差异。

在机器学习中,P往往用来表示样本的真实分布,Q用来表示模型所预测的分布,那么KL散度就可以计算两个分布的差异,也就是Loss损失值。其公式定义如下:
K L ( p ∣ ∣ q ) = ∑ i = 1 n p ( x i ) l o g ( p ( x i ) q ( x i ) ) KL(p||q)=\sum_{i=1}^np(x_i)log(\frac{p(x_i)}{q(x_i)}) KL(p∣∣q)=i=1np(xi)log(q(xi)p(xi))
从KL散度公式中可以看到Q的分布越接近P(Q分布越拟合P),那么散度值越小,即损失值越小。

4、变分图自编码器(VGAE)

变分图自编码器也有两部分组成,分别是推理模型(编码器)和生成模型(解码器)。

4.1、推理模型

在GAE中,可训练的参数只有 W 0 W^0 W0 W 1 W^1 W1 ,训练结束后只要输入邻接矩阵 A A A和节点特征矩阵 X X X,就能得到节点的向量表征 Z Z Z

与GAE不同,在变分图自编码器VGAE中,节点表征 Z Z Z不是由一个确定的GCN得到,而是从一个多维高斯分布中采样得到。

多维高斯分布的均值和方差由两个GCN确定:
μ = G C N μ ( X , A ) \mu=\mathrm{GCN}_\mu(\mathrm{X,A}) μ=GCNμ(X,A)
以及
l o g σ = G C N σ ( X , A ) log \;\sigma = \mathrm{GCN}_\sigma(\mathrm{X,A}) logσ=GCNσ(X,A)
论文中,这两个不同的GCN都是两层,并且第一层的参数 W 0 W^0 W0是共享的。

有了均值和方差后,我们就能唯一地确定一个多维高斯分布,然后从中进行采样以得到节点的向量表示 Z Z Z,也就是说,向量表征的后验概率分布为:

q ( Z ∣ X , A ) = ∏ i = 1 N q ( z i ∣ X , A ) , q(\mathbf{Z}|\mathbf{X},\mathbf{A})=\prod_{i=1}^Nq(\mathbf{z}_i|\mathbf{X},\mathbf{A}), q(ZX,A)=i=1Nq(ziX,A),
其中,
q ( z i ∣ X , A ) = N ( z i ∣ μ i , diag ⁡ ( σ i 2 ) ) q(\mathbf{z}_i|\mathbf{X},\mathbf{A})=\mathcal{N}(\mathbf{z}_i|\boldsymbol{\mu}_i,\operatorname{diag}(\boldsymbol{\sigma}_i^2)) q(ziX,A)=N(ziμi,diag(σi2))
其中 和 μ i \mu_i μi σ i 2 \sigma^2_i σi2分别表示节点向量的均值和方差。也就是说,通过两个GCN我们得到了所有节点向量的均值和方差,然后再从中采样形成节点向量。具体来讲,编码器得到多维高斯分布的均值向量和协方差矩阵后,我们就可以通过采样来得到节点的向量表示,但是,采样操作无法提供梯度信息,这对神经网络来讲是没有意义的,因此作者做了重采样:

z = μ + ϵ σ \mathrm{z=\mu+\epsilon\sigma} z=μ+ϵσ
这里 ϵ \epsilon ϵ服从 N ( 0 , 1 ) \mathcal{N}(0,1) N(0,1),也就是标准高斯分布,因为 ϵ \epsilon ϵ服从标准高斯分布,所以 μ + ϵ σ \mu+\epsilon \sigma μ+ϵσ服从 N ( μ , σ 2 ) \mathcal{N}(\mu,\sigma^2) N(μ,σ2).

反复从训练集中抽取样本,并对每个样本重新拟合感兴趣的模型,以获得有关拟合模型的其他信息。

4.2、生成模型

生成模型,通过计算图中任意两个节点间存在边的概率来重构图,
p ( A ∣ Z ) = ∏ i = 1 N ∏ j = 1 N p ( A i j ∣ z i , z j ) , with p ( A i j = 1 ∣ z i , z j ) = σ ( z i ⊤ z j ) , p\left(\mathbf{A}|\mathbf{Z}\right)=\prod_{i=1}^N\prod_{j=1}^Np\left(A_{ij}|\mathbf{z}_i,\mathbf{z}_j\right),\quad\text{with}\quad p\left(A_{ij}=1|\mathbf{z}_i,\mathbf{z}_j\right)=\sigma(\mathbf{z}_i^\top\mathbf{z}_j), p(AZ)=i=1Nj=1Np(Aijzi,zj),withp(Aij=1∣zi,zj)=σ(zizj),

也就是说,解码器通过计算任意两个节点向量表示的相似性来重建图结构。

4.3、学习

损失函数定义如下:
L = E q ( Z ∣ X , A ) [ log ⁡ p ( A ∣ Z ) ] − K L [ q ( Z ∣ X , A ) ∣ ∣ p ( Z ) ] \mathcal{L}=\mathbb{E}_{q(\mathbf{Z}\mid\mathbf{X},\mathbf{A})}\big[\log p\left(\mathbf{A}\mid\mathbf{Z}\right)\big]-\mathrm{KL}\big[q(\mathbf{Z}\mid\mathbf{X},\mathbf{A})||p(\mathbf{Z})\big] L=Eq(ZX,A)[logp(AZ)]KL[q(ZX,A)∣∣p(Z)]

  • 第一部分与GAE中类似,为交叉熵函数,也就是经分布 q q q得到的向量重构出的图与原图的差异,这种差异越小越好;
  • 第二部分表示利用GCN得到的分布 q ( ⋅ ) q(·) q()与标准高斯分布 p ( Z ) p(Z) p(Z)间的KL散度,也就是要求分布 q q q尽量与标准高斯分布相似。
    其中, p ( Z ) p(Z) p(Z)为为标准高斯分布 p ( Z ) = ∏ i p ( z i ) = ∏ i N ( z i ∣ 0 , I ) . \begin{aligned}p(\mathbf{Z})=\prod_ip(\mathbf{z_i})=\prod_i\mathcal{N}(\mathbf{z}_i|0,\mathbf{I}).\end{aligned} p(Z)=ip(zi)=iN(zi∣0,I).

损失函数展开形式下:
∑ i = 1 n { − p ( x ) l o g ( p ( x ) ) − ( 1 − p ( x ) ) l o g ( 1 − p ( x ) ) + 1 / 2 ( μ ( i ) 2 + σ ( i ) 2 − l o g σ ( i ) 2 − 1 ) } \sum_{i=1}^n\{-p(x)log(p(x))-(1-p(x))log(1-p(x)) +1/2(\mu_{(i)}^{2}+\sigma_{(i)}^{2}-log\sigma_{(i)}^{2}-1)\} i=1n{p(x)log(p(x))(1p(x))log(1p(x))+1/2(μ(i)2+σ(i)2logσ(i)21)}

5、模型实现

import torch
import torch.nn as nn
import torch.nn.functional as F
import os
import numpy as np
import args
class VGAE(nn.Module):def __init__(self,adj) -> None:super(VGAE,self).__init__()self.adj = adjself.share_gcn = GraphConvLayer(args.infeat,args.hidfeat1)self.gcn_mean  = GraphConvLayer(args.hidfeat1,args.hidfeat2,activation = lambda x: x)self.gcn_logstd = GraphConvLayer(args.hidfeat1,args.hidfeat2,activation = lambda x:x)def encode(self,x,adj):hidden = self.share_gcn(x,adj)self.mean = self.gcn_mean(hidden,adj)self.logstd = self.gcn_logstd(hidden,adj)gaussian_noise = torch.randn(x.shape[0],args.hidfeat2)sampled_z = gaussian_noise * torch.exp(self.logstd) + self.meanreturn sampled_z@staticmethoddef decode(z):'''静态方法'''A_pred = F.sigmoid(torch.matmul(z,z.T))return A_preddef forward(self,x):Z = self.encode(x,self.adj)A_pred = self.decode(Z)return A_pred
class GraphConvLayer(nn.Module):    def __init__(self, infeat,outfeat,activation = F.relu) -> None:super(GraphConvLayer,self).__init__()self.activation = activationself.layer = nn.Linear(infeat,outfeat,bias=False)self.init_param()passdef init_param(self):self.layer.reset_parameters()def forward(self,x,adj):AX = torch.mm(adj,x)AXW = self.layer(AX)return self.activation(AXW)

参考链接

  • 参考链接1
  • 参考链接2
  • 参考链接3

相关文章:

【论文阅读】Variational Graph Auto-Encoder

0、基本信息 会议:2016-NIPS作者:Thomas N. Kipf,Max Welling文章链接:Variational Graph Auto-Encoder代码链接:Variational Graph Auto-Encoder 1、介绍 本文提出一个变分图自编码器,一个基于变分自编…...

如何把电脑中的项目快速传进Github中?

一、打开GitHub网站:https:github.com 登录自己的个人账号 1.新建一个项目 2.用鼠标直接拖拽电脑中的项目文件夹与文件到新创建的项目中点击保存即可。...

Plantuml之nwdiag网络图语法介绍(二十九)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏:多媒…...

MyBatis接口的方法上使用,定义对应的 SQL 操作

目录标题 一、Mapper:二、Select、Insert、Update、Delete:三、Results、Result:四、Param:五、# 和 $: MyBatis 是一款基于 Java 的持久层框架,它通过简化数据库操作来帮助开发者构建更好的数据库访问应用…...

(20)Linux初始文件描述符

前言:本章我们介绍 O_WRONLY, O_TRUNC, O_APPEND 和 O_RDONLY。之后我们开始讲解文件描述符。 一、系统传递标记位 1、O_WRONLY C 语言在 w 模式打开文件时,文件内容是会被清空的,但是 O_WRONLY 好像并非如此? 代码演示&…...

draw.io基础操作和代码高效画图进阶

文章目录 一、基础操作1、链接2、等比例变形3、复制4、插入表格 二、在线打开三、插入—功能聚集地1、插入图片2、插入画笔3、插入布局4、导出 四、图码转换——高效画图1、通用图码转换2、流程图生成:使用mermaid语言生成图: 五、图码转换高效画图的典型…...

2024-01-04 用llama.cpp部署本地llama2-7b大模型

点击 <C 语言编程核心突破> 快速C语言入门 用llama.cpp部署本地llama2-7b大模型 前言一、下载llama.cpp以及llama2-7B模型文件二、具体调用总结 前言 要解决问题: 使用一个准工业级大模型, 进行部署, 测试, 了解基本使用方法. 想到的思路: llama.cpp, 不必依赖显卡硬件…...

HTTP打怪升级之路

新手村 上个世纪80年代末&#xff0c;有一天&#xff0c;Tim Berners-Lee正在工作&#xff0c;他需要与另一台计算机上的同事共享一个文件。他尝试使用电子邮件&#xff0c;但发现电子邮件不能发送二进制文件。Tim Berners-Lee意识到&#xff0c;他需要一种新的协议来共享二进制…...

axure RP9.0安装字体图标库fontawesome

字体图库地址: Font AwesomeThe internets icon library toolkit. Used by millions of designers, devs, & content creators. Open-source. Always free. Always awesome.https://fontawesome.com/v6/download进入后下载想要的版本如我是6.3 下载后得到压缩包,解压之后…...

PiflowX组件-ReadFromUpsertKafka

ReadFromUpsertKafka组件 组件说明 upsert方式从Kafka topic中读取数据。 计算引擎 flink 有界性 Unbounded 组件分组 kafka 端口 Inport&#xff1a;默认端口 outport&#xff1a;默认端口 组件属性 名称展示名称默认值允许值是否必填描述例子kafka_hostKAFKA_HO…...

keil 5 ARM CC编译错误和警告解释大全(3)序列号2000-3000

2001年&#xff1a;已声明虚拟参数&#xff0c;但从未使用过 2002年&#xff1a;虚拟参数重新定义为do变量 2003&#xff1a;无法优化&#xff1a;常量/表达式传递给可能修改的变量 2004&#xff1a;重新维度的数组作为参数传递 2005&#xff1a;重维度数组等价 2006&…...

CentOS 7 实战指南:文件或目录的权限操作命令详解

前言 这篇文章详细介绍了文件和目录的常用权限操作命令&#xff0c;并提供了全面的技术解析。通过本文&#xff0c;你将学习如何使用 chmod 和 chown 命令来管理文件和目录的权限&#xff0c;控制用户和用户组的访问权限。无论你是初学者还是有经验的系统管理员&#xff0c;这…...

我的第一个前端项目,vue项目从零开始创建和运行

​入门前端&#xff0c;从基础做起&#xff0c;从零开始新建项目 背景&#xff1a;VUE脚手架项目是一个“单页面”应用&#xff0c;即整个项目中只有1个网页&#xff01; 在VUE脚手架项目中&#xff0c;主要是设计各个“视图组件”&#xff0c;它们都是整个网页中某个部分&…...

【OJ】C++,Java,Python,Go,Rust

for循环语法 // cpp// java// python for i in range(集合): for i, val in enumerate(集合): for v1,v2,v3,... in zip(集合1,集合2,集合3,...):Pair // cpp pair<int, string> first second // java Pair<Integer, String> first() new Pair<>(firstVal…...

Flink 任务指标监控

目录 状态监控指标 JobManager 指标 TaskManager 指标 Job 指标 资源监控指标 数据流监控指标 任务监控指标 网络监控指标 容错监控指标 数据源监控指标 数据存储监控指标 当使用 Apache Flink 进行流处理任务时&#xff0c;可以根据不同的监控需求&#xff0c;监控…...

Go语言程序设计-第7章--接口

Go语言程序设计-第7章–接口 接口类型是对其他类型行为的概括与抽象。 Go 语言的接口的独特之处在于它是隐式实现。对于一个具体的类型&#xff0c;无须声明它实现了哪些接口&#xff0c;只要提供接口所必须实现的方法即可。 7.1 接口即约定 7.2 接口类型 package iotype …...

性能优化-OpenMP基础教程(二)

本文主要介绍OpenMP并行编程技术&#xff0c;编程模型、指令和函数的介绍、以及OpenMP实战的几个例子。希望给OpenMP并行编程者提供指导。 &#x1f3ac;个人简介&#xff1a;一个全栈工程师的升级之路&#xff01; &#x1f4cb;个人专栏&#xff1a;高性能&#xff08;HPC&am…...

让电脑变得更聪明——用python实现五子棋游戏

作为经典的棋类游戏&#xff0c;五子棋深受大众喜爱&#xff0c;但如果仅实现人与人的博弈&#xff0c;那程序很简单&#xff0c;如果要实现人机对战&#xff0c;教会计算机如何战胜人类&#xff0c;那就不是十分容易的事了。本文我们先从简单入手&#xff0c;完成五子棋游戏的…...

C#-接口

接口 (interface) 定义了一个可由类和结构实现的协定。接口可以包含方法、属性、事件和索引器。接口不提供它所定义的成员的实现 — 它仅指定实现该接口的类或结构必须提供的成员。 接口可支持多重继承。在下面的示例中,接口 IComboBox 同时从 ITextBox 和 IListBox 继承。 i…...

ASP.NET可视化流程设计器源码

源码介绍: ASP.NET可视化流程设计器源码已应用于众多大型企事业单位。拥有全浏览器兼容的可视化流程设计器、表单设计器、基于角色的权限管理等系统开发必须功能&#xff0c;大大为您节省开发时间&#xff0c;是您开发OA.CRM、HR等企事业各种应用管理系统和工作流系统的最佳基…...

ES6从入门到精通:前言

ES6简介 ES6&#xff08;ECMAScript 2015&#xff09;是JavaScript语言的重大更新&#xff0c;引入了许多新特性&#xff0c;包括语法糖、新数据类型、模块化支持等&#xff0c;显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var&#xf…...

3.3.1_1 检错编码(奇偶校验码)

从这节课开始&#xff0c;我们会探讨数据链路层的差错控制功能&#xff0c;差错控制功能的主要目标是要发现并且解决一个帧内部的位错误&#xff0c;我们需要使用特殊的编码技术去发现帧内部的位错误&#xff0c;当我们发现位错误之后&#xff0c;通常来说有两种解决方案。第一…...

centos 7 部署awstats 网站访问检测

一、基础环境准备&#xff08;两种安装方式都要做&#xff09; bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats&#xff0…...

【决胜公务员考试】求职OMG——见面课测验1

2025最新版&#xff01;&#xff01;&#xff01;6.8截至答题&#xff0c;大家注意呀&#xff01; 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:&#xff08; B &#xff09; A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...

3-11单元格区域边界定位(End属性)学习笔记

返回一个Range 对象&#xff0c;只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意&#xff1a;它移动的位置必须是相连的有内容的单元格…...

有限自动机到正规文法转换器v1.0

1 项目简介 这是一个功能强大的有限自动机&#xff08;Finite Automaton, FA&#xff09;到正规文法&#xff08;Regular Grammar&#xff09;转换器&#xff0c;它配备了一个直观且完整的图形用户界面&#xff0c;使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...

2025季度云服务器排行榜

在全球云服务器市场&#xff0c;各厂商的排名和地位并非一成不变&#xff0c;而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势&#xff0c;对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析&#xff1a; 一、全球“三巨头”…...

JAVA后端开发——多租户

数据隔离是多租户系统中的核心概念&#xff0c;确保一个租户&#xff08;在这个系统中可能是一个公司或一个独立的客户&#xff09;的数据对其他租户是不可见的。在 RuoYi 框架&#xff08;您当前项目所使用的基础框架&#xff09;中&#xff0c;这通常是通过在数据表中增加一个…...

宇树科技,改名了!

提到国内具身智能和机器人领域的代表企业&#xff0c;那宇树科技&#xff08;Unitree&#xff09;必须名列其榜。 最近&#xff0c;宇树科技的一项新变动消息在业界引发了不少关注和讨论&#xff0c;即&#xff1a; 宇树向其合作伙伴发布了一封公司名称变更函称&#xff0c;因…...

0x-3-Oracle 23 ai-sqlcl 25.1 集成安装-配置和优化

是不是受够了安装了oracle database之后sqlplus的简陋&#xff0c;无法删除无法上下翻页的苦恼。 可以安装readline和rlwrap插件的话&#xff0c;配置.bahs_profile后也能解决上下翻页这些&#xff0c;但是很多生产环境无法安装rpm包。 oracle提供了sqlcl免费许可&#xff0c…...