参考:
Graph Neural Network(GAE,GVAE,ARGA)
VGAE
VGAE(Variational graph auto-encoders)论文详解
自编码器(Auto Encoder)原理及其python实现
AE
autoEncoder,是一种无监督式学习模式。利用数据 X X X本身作为监督,指导神经网络学习一个映射关系,从而得到一个重构输出 X R X^{R} XR
PCA是通过求解特征向量进行降维,是一种线性降维方式,而自编码是一种非线性降维。
一个自编码器的输入、输出应有相同的结构,利用数据训练这个网络,等训练结束后,这个网络即学习出了x->h->x的能力,h是至关重要的,是在尽量不损失信息量的情况下,对原始数据的另一种表达。
希望通过自编码器,让潜在表征h具有价值属性。
搭建自编码器案例
数据集使用MNIST,这是一个包含手写数字的大型图像数据集。
使用对称结构,如下所示:
# 手写数字识别为例
import torch
import torchvision
import torch.utils.data as Data
import torch.nn as nn
import torch.nn.functional as F
import matplotlib.pyplot as plt
from matplotlib import cm
from mpl_toolkits.mplot3d import Axes3D
import time
starttime = time.time()
torch.manual_seed(1)
EPOCH = 10
BATCH_SIZE = 64
LR = 0.005
N_TEST_IMG = 5
train_data = torchvision.datasets.MNIST(
root="mnist",
train=True,
transform=torchvision.transforms.ToTensor(),
download=True
) # 网上下载并转换为张量格式
loader = Data.DataLoader(dataset=train_data, batch_size=BATCH_SIZE, shuffle=True)
print(train_data.train_data.size())
print(train_data.train_labels.size())
print(train_data.train_data[0])
plt.imshow(train_data.train_data[1].numpy(), cmap='Greys')
plt.show()
运行如下所示:
数据大小为[6000, 28, 28],6000是训练样本的数量,28*28是图像的宽高。
训练标签的大小,为6000,即每个图片都有一个标签。
搭建自编码器:
#自定义编码器网络
class AutoEncoder(nn.Module):
def __init__(self):
super(AutoEncoder, self).__init__()
self.encoder = nn.Sequential(
nn.Linear(28*28, 128),
nn.Tanh(),
nn.Linear(128, 64),
nn.Tanh(),
nn.Linear(64, 32),
nn.Tanh(),
nn.Linear(32, 16),
nn.Tanh(),
nn.Linear(16,3)
)
self.decoder = nn.Sequential(
nn.Linear(3, 16),
nn.Tanh(),
nn.Linear(16, 32),
nn.Tanh(),
nn.Linear(32, 64),
nn.Tanh(),
nn.Linear(64, 128),
nn.Tanh(),
nn.Linear(128, 28*28),
nn.Sigmoid()
)
def forward(self, x):
encoded = self.encoder(x)
decoded = self.decoder(encoded)
return encoded, decoded
然后进行网络训练:
定义的EPOCH
为10,即对数据集进行10次整个遍历,每一次遍历为一个epoch
。
# 优化器
optimizer = torch.optim.Adam(Coder.parameters(), lr=LR)
loss_func = nn.MSELoss()
for epoch in range(EPOCH):
for step, (x,y) in enumerate(loader):
b_x = x.view(-1, 28*28)
b_y = x.view(-1 ,28*28)
b_label = y
encoded, decoded = Coder(b_x)
loss = loss_func(decoded, b_y) # 和重建的进行计算
optimizer.zero_grad()
loss.backward()
optimizer.step()
if step%5==0:
print('Epoch:', epoch, '|', 'train_loss:%.4f'%loss.data)
torch.save(Coder, 'AutoEncoder.pkl')
print('__________')
print("finish training")
训练过程如下:
学到的encoded_data:
# 压缩的特征值
view_data = train_data.train_data[:200].view(-1, 28*28).type(torch.FloatTensor)/255.
encoded_data, _ = Coder(view_data)
print(encoded_data)
GAE
GAE
GAE的目的是通过encoder-decoder的结构去获取图中节点的embedding,然后再去做具体的下游任务。
在图上完成AE的操作,如下图所示:编码器负责压缩,解码器负责还原。
其中
Z
=
G
C
N
(
A
)
Z = GCN(A)
Z=GCN(A),代表的是所有节点的表示。decoder中不采用对称结构,采用内积inner-product重构原始图。
与AE的区别
GAE在encoder过程中使用了 n∗n 矩阵的卷积核,在decoder部分实际上没有解码,直接计算内积算邻接矩阵的相似度,然后用loss来约束
论文Variational Graph Auto-Encoders
如果将解码器看做一个生成模型,我们只要有低维向量表示,就可以用这个生成模型得到近似真实的样本。但是,这样的生成模型存在一个问题:低维向量表示必须是由真实样本通过编码器得到的,否则随机产生的低维向量表示通过生成模型几乎不可能得到近似真实的样本。
那么,如果能将低维向量表示约束在一个分布(比如正态分布)中,那么从该分布中随机采样,产生的低维向量表示通过生成模型不是就能产生近似真实的样本了吗?
变分自编码器就是这样的一种自编码器:如下图所示,变分自编码器通过编码器学到的不是样本的低维向量表示,而是低维向量表示的分布。假设这个分布服从正态分布,然后在低维向量表示的分布中采样得到低维向量表示,接下来经过解码器还原出原始样本。