首先是自动编码器和图自动编码器。自动编码器的主要作用是学习一个东西的主要特征,从高维编码到低维,再从低维解码到高维。衡量编码和解码的好坏就是重构损失,也就是看原始向量和重构向量像不像,一般用交叉熵或者均方误差来衡量损失。而图自动编码器主要是用来学习图的主要特征,更具体来讲是学习每个节点的主要特征。在编码阶段,AE是用全连接层或者卷积层,GAE一般使用的是GCN进行编码,输入是邻接矩阵和节点的特征矩阵,当然特征矩阵也可以没有。在解码阶段有些不同,AE使用的是一个隐层,但是GAE直接用Z*Z的转置来还原图的邻接矩阵,损失的话也是用交叉熵来看这两个图的邻接矩阵像不像。
但是自动编码器存在的2个问题,一个问题是隐层表示的质量差,比如说它可能把相似的数据放的很远,只要解码器足够强大,它就能记住所有数据在空间中的坐标,那么编码编进去的嵌入表示也就毫无意义。第二个问题是数据生成的质量差,比如在8和7之间这个点的数据是4,也有可能在训练集没有覆盖到的地方生成一些乱七八糟的东西。
主要原因还是在于他的这个code是针对于特定的训练集生成的,它的权重参数W是已经固定了的,如果我们随机人为的随机给一个code它是大概率会给我们一个乱七八糟的东西的。所以接下来的VAE和VGAE,变分主要就是来解决这个问题的。变分的大概意义就是变量是分布的,也就是说输入同一个input,编码的code也是不一样的,VAE的AE的最大区别就是,AE的code是固定的,而vae的code只是满足特定分布,但不固定。如果是VAE,我们随机输入一个满足特定分布的code,那么生成的数据大概率也是有意义的。
再来讲一讲VAE,这是VAE的模型。在编码部分,它不像AE学的是W的参数,他学的是正态分布的两个参数,均值和方差(一般情况下我们都用的是正态分布),这样就得到了每个样本的正态分布,再从每个正态分布中进行采样,具体是从正态分布中生成一个向量,再将这个向量乘以标准差加上均值,这样就是每个样本的嵌入表示,解码部分的话是一样的。
事实上,均值(或者说均值向量)代表的是AE中间编码的确定的点的坐标,而方差代表的噪音,在这个正态分布中采样,中心点就是这个训练集数据本身,而在中心点附近的是很像这个数据但又加了点噪音的不完全像的这个数据。比如在图中,8编码成了上面这个分布,而9编码成了下面这个分布,在8和9中间的数据就是既像8又像9的东西。
所以VAE能够更好地解决AE解决不了的隐层表示和数据生成的问题,比如8和9之间是既像8又像9的东西,随机给定一个code他也是有意义的。
接下来再说一下VAE的损失,VAE的损失包含两个部分,一部分是重构损失,也就是生成样本是真实样本像不像,这部分是AE就有的,另一部分是限制分布情况的,也就是要让每一个样本的分布都逼近于标准正态分布,因为不过只有重构损失的话,VAE在学习过程中会把故意制造噪音的方差变成0,这样就退化成了AE,不是我们希望看到的,所以我们要让每一个分布都逼近到标准正态分布,均值为0,方差为1。
接下来有几个问题。为什么要学分布的参数而不是直接学分布?为什么使用的正态分布而不是其他分布?为什么要让生成的分布向标准正态分布靠近?第一个问题的话是因为只能通过分布的参数让梯度下降奏效,直接学分布的话会造成梯度断裂问题,无法计算梯度写不了代码。第二个问题的话可以用正态分布,也可以用其他分布,但是这个分布必须是先验的,你必须指定一个分布给他,因为我们只能学分布的参数,不同的分布有不同的参数,参数的个数也是不尽相同的,所以我们只能去试分布,但不能学分布。第三个问题的话,可以不向标准正态分布靠近,方差不为0让他有噪音能变化就行。
讲完了这些就能理解图的变分自编码器。通过输入邻接矩阵A和特征矩阵X,经过2层GCN,得到均值和方差,再从分布中采样得到嵌入表示Z,再通过Z乘以Z的转置还原邻接矩阵。其实就是融合了VAE和GAE变成了VGAE。
参考资料:
https://blog.csdn.net/sinat_36197913/article/details/93630246
https://zhuanlan.zhihu.com/p/34998569
https://www.bilibili.com/video/BV1hf4y1r7C7
https://blog.csdn.net/c9Yv2cf9I06K2A9E/article/details/104765097
https://mp.weixin.qq.com/s?__biz=MzIwMDIzNDI2Ng==&mid=2247484815&idx=1&sn=1b891d454d8a43356c29a90671ac108a&source=41#wechat_redirect