图自编码器(GAE)与变分图自编码器(VGAE)

目录

自编码器

变分自编码器与自编码器的区别

变分自编码器

图自编码器GAE

编码器

解码器

变分图自编码器VGAE

在学习图自编码器之前先了解一下自编码器与变分自编码器。

自编码器与变分自编码器

自编码器与变分自编码器

自编码器

        自编码器(auto-encoder, AE)是一类在半监督学习和无监督学习中使用的人工神经网络(Artificial Neural Networks, ANNs),其功能是通过将输入信息作为学习目标,对输入信息进行表征学习。 结构通常包括一个输入层一个或多个隐藏层一个输出层。自编码器的目标是学习将输入数据压缩到隐藏层中,并能够通过解码器将其从压缩表示中重建出输入数据。


        自编码器通常包括两部分:编码器解码器编码器将输入数据映射到隐藏层,通常通过一系列的非线性变换和特征提取来实现。解码器则将隐藏层的表示映射回到重构的输入数据,同时也通过非线性变换和特征提取来实现。

变分自编码器与自编码器的区别

        自编码器和变分自编码器都是属于无监督学习的神经网络模型,可以用于数据降维、特征提取、数据压缩等任务。主要区别在于训练细节和用途。

        自编码器的训练目标是最小化重建误差,也就是使输入和输出保持尽量一致。自编码器的输出通常是通过一组非线性变换和解码器映射回输入空间的重构数据。因此,自编码器常用于数据降维、特征提取等任务中。

        变分自编码器的训练目标是最小化重建误差和一个正则项。正则项通过引入潜在变量,实现对数据分布进行建模。变分自编码器通过从分布中采样潜在变量,从而可以生成新的数据样本。因此,变分自编码器常用于数据生成、异常检测等任务中。

变分自编码器

        变分自编码器不仅学习将输入数据压缩成一个低维的表示,同时还会学习这个低维表示的概率分布。这个概率分布对应着原始数据的隐空间,这使得我们可以从隐空间中生成全新的数据。概率分布的意义就是在隐空间中表示输入数据的总体分布情况也就是将输入数据映射到隐空间中的概率分布。这个映射过程是非线性的,通过变分自编码器的训练可以学习到这个映射的权重和偏置。因此VAE不仅可以重构原始数据,还可以生成与原始数据类似但并不存在于训练数据中的新数据,相当于对数据进行了无损压缩和有损压缩。

        并且这个概率分布通常选择高斯分布,它有两个参数:均值标准差均值描述了概率分布的期望值,而标准差描述了概率分布的广度

        总之,变分自编码器可以通过将隐含空间中的数据转换为概率分布进行编码,然后在解码过程中,通过随机采样的方式生成新的数据。而且,这个过程是可逆的,也就是说新的数据可以再次通过编码过程映射到隐空间中。这使得变分自编码器在生成新数据时能够保持一定的一致性,保持过程的可逆性,从而对于一些任务,如数据压缩、降维、数据重建和数据生成等都有很好的效果。

        生成新数据的核心是基于概率分布进行随机采样的过程。在训练过程中,变分自编码器通过学习到训练数据的概率分布,即隐空间中对应于原始数据的概率分布,从而生成新的数据。

下面进入正题!!!

图自编码器GAE

        GAE是图卷积神经网络GCN在Auto-Encoders (AE)的应用,隐变量Z是图上的N个节点经过GCN后的N*F维特征,编码器就是两层GCN, 解码器就是向量点积。可以将隐变量Z理解为某种意义上图的节点的相似度,通过向量点积得到的两个图节点的相似度越大,则两个节点之间存在边的概率越大。

        一个图自编码器,包含一个编码器目的是映射输入图到一个更低的维度一个解码器目的是从更低维度的嵌入来重构输入图。换句话说,解码器的输出为重构的邻接矩阵A*,目的就是优化模型使得重构损失即A*与原始图输入A的差异最小。

编码器

        GAE 使用 GCN 作为 encoder,来得到节点的潜在表示(或者说 embedding),这个过程
可用一行简短的公式表达:
Z=GCN(X,A)
两层的GCN定义为:
GCN(X,A)=\widetilde{A}ReLU(\widetilde{A}XW_{0})W_{1}
        整个encoder只有两层,每一层采用的均是切比雪夫多项式的一阶近似作为卷积核处理数据。GCN就相当于一个以节点特征和邻接矩阵为输入、以节点嵌入信息为输出的函数,目的是为了得到节点的嵌入向量Z。

解码器

GAE采用inner-product(内积)作为decoder来重构原始的图:
\widehat{A}=\sigma (ZZ^{T}) 即重构出来的邻接矩阵。

变分图自编码器VGAE

        VGAE是GCN在VAE的应用。编码器用两个两层GCN分别得到N个均值和标准差,这两个GCN会共享第一层的参数,从而得到N个正态分布;解码器仍然是向量inner-product(内积)。变分图自动编码器,它是基于变分自编码器(VAE)的无监督学习图结构数据的框架,该模型利用了潜在变量,并且有可能学习无向图的可解释潜在表示。

        在GAE中,一旦GCN中的W_{0}W_{1} 确定了,那么GCN就是一个确定的函数,给定X和A,输出的Z 就是确定的。而在 VGAE 中,Z不再由一个确定的函数得到,而是从一个(多维)高斯分布中采样得到。更明确些,就是先通过GCN确定一个(多维)高斯分布,再从这个分布中采样得到Z。

         高斯分布可以唯一地由二阶矩确定。故确定一 个高斯分布,只需要知道均值和方差。VGAE利用GCN来分别计算均值和方差:

\mu =GCN_{\mu }(X,A)

log\sigma =GCN_{\sigma }(X,A)

        通过均值和方差就能唯一确定一个多维高斯分布,从中进行采样得到节点的嵌入表示Z。采样操作无法提供梯度信息对神经网络来说是无意义的,可通过重采样得到节点的向量表示,即服从标准高斯分布N(0,1)。
学习总结到此就结束lu!!!
  • 4
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用PyTorch实现对抗正则化变分自编码器(Adversarial Regularization Variational Graph Autoencoder)的代码: ```python import torch import torch.nn as nn import torch.nn.functional as F class GAE(nn.Module): def __init__(self, n_feat, n_hid, n_latent): super(GAE, self).__init__() self.n_latent = n_latent self.encoder = nn.Sequential( nn.Linear(n_feat, n_hid), nn.ReLU(), nn.Linear(n_hid, n_hid), nn.ReLU(), nn.Linear(n_hid, n_latent * 2) ) self.decoder = nn.Sequential( nn.Linear(n_latent, n_hid), nn.ReLU(), nn.Linear(n_hid, n_hid), nn.ReLU(), nn.Linear(n_hid, n_feat) ) def encode(self, x): h = self.encoder(x) mu, log_var = torch.chunk(h, 2, dim=-1) return mu, log_var def decode(self, z): return self.decoder(z) def reparameterize(self, mu, log_var): std = torch.exp(0.5 * log_var) eps = torch.randn_like(std) return mu + eps * std def forward(self, x): mu, log_var = self.encode(x) z = self.reparameterize(mu, log_var) x_hat = self.decode(z) return x_hat, mu, log_var def loss_function(self, x, x_hat, mu, log_var): recon_loss = F.mse_loss(x_hat, x, reduction='mean') kld_loss = -0.5 * torch.sum(1 + log_var - mu.pow(2) - log_var.exp(), dim=-1).mean() return recon_loss + kld_loss class Discriminator(nn.Module): def __init__(self, n_latent, n_hid): super(Discriminator, self).__init__() self.model = nn.Sequential( nn.Linear(n_latent, n_hid), nn.ReLU(), nn.Linear(n_hid, 1), nn.Sigmoid() ) def forward(self, z): return self.model(z) class ARVGA(nn.Module): def __init__(self, n_feat, n_hid, n_latent, n_hid_d): super(ARVGA, self).__init__() self.gae = GAE(n_feat, n_hid, n_latent) self.discriminator = Discriminator(n_latent, n_hid_d) def forward(self, x): x_hat, mu, log_var = self.gae(x) z = self.gae.reparameterize(mu, log_var) return x_hat, mu, log_var, z def loss_function(self, x, x_hat, mu, log_var, z): recon_loss = F.mse_loss(x_hat, x, reduction='mean') kld_loss = -0.5 * torch.sum(1 + log_var - mu.pow(2) - log_var.exp(), dim=-1).mean() g_loss = recon_loss + kld_loss d_real = self.discriminator(torch.randn(z.shape).to(z.device)) d_fake = self.discriminator(z.detach()) d_loss = -torch.mean(torch.log(d_real + 1e-8) + torch.log(1 - d_fake + 1e-8)) return g_loss, d_loss ``` 其中,`GAE`类定义了变分自编码器(Variational Graph Autoencoder),包括编码器和解码器,以及相关的函数,如重参数化函数等。`Discriminator`类定义了对抗正则化中的判别器。`ARVGA`类整合了变分自编码器和判别器,并定义了前向传递和损失函数。 在训练模型时,可以使用以下代码: ```python model = ARVGA(n_feat, n_hid, n_latent, n_hid_d) optimizer_g = torch.optim.Adam(model.gae.parameters(), lr=lr) optimizer_d = torch.optim.Adam(model.discriminator.parameters(), lr=lr) for epoch in range(n_epochs): for batch in data_loader: x = batch.to(device) x_hat, mu, log_var, z = model(x) g_loss, d_loss = model.loss_function(x, x_hat, mu, log_var, z) optimizer_g.zero_grad() g_loss.backward(retain_graph=True) optimizer_g.step() optimizer_d.zero_grad() d_loss.backward() optimizer_d.step() ``` 其中,`data_loader`是一个`torch.utils.data.DataLoader`对象,用于加载训练数据。`n_epochs`是训练轮数,`lr`是学习率。调用`model.loss_function()`可以得到生成器和判别器的损失,并分别使用对应的优化器进行反向传播和参数更新。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值