【KD】实习day05

CondGen模型细节

网络嵌入

用到的方法是拉普拉斯特征映射(具体实现

# n = node个数
# d = 结点的表示维数
# adj = 邻接矩阵(shape为n*n)
from sklearn.manifold import SpectralEmbedding
emb = SpectralEmbedding(n_components=d)
rep = emb.fit_transform(adj)
# rep为每个结点的嵌入表征(shape为n*d)

结点编码

输入:整张网络的邻接矩阵
模型:GCN(图卷积神经网络)
输出:网络中每个结点的嵌入表征

GCN作用

保证模型的置换不变性

边生成

输入:结点嵌入i与结点嵌入j
模型:全连接神经网络
输出:链接概率

CondGen训练过程

对每个epoch

对每一张输入图

  1. 生成器先接受输入图的编码表征,然后重建一张图
  2. 依次将输入图的编码,重建图的编码和随机生成噪音图的编码投入判别器进行预测,预测值为0到1的概率
  3. 根据步骤2中的三者计算判别器的损失值 L d L_d Ld(计算方法为简单的二元交叉熵),并清除梯度更新一次参数(更新判别器)
  4. 依次将输入图的编码,重建图的编码和随机生成噪音图的编码投入刚更新过参数的判别器进行预测,预测值为0到1的概率
  5. 根据步骤4中的三者计算判别器的损失值 L d L_d Ld
  6. 根据重建图和输入图在判别器中的相似度,计算出重建损失 L r e c L_{rec} Lrec
  7. 计算得解码器的损失值为 L d e c = γ ∗ L r e c − L d L_{dec}=\gamma*L_{rec}-L_d Ldec=γLrecLd(原作者的gamma默认为15),并清除梯度更新一次参数(更新生成器及解码器)
  8. 计算prior_loss( L p r i o r L_{prior} Lprior),通过公式 L e n c = L p r i o r − L d + β ∗ L r e c L_{enc}=L_{prior}-L_{d}+\beta*L_{rec} Lenc=LpriorLd+βLrec(原作者的beta默认为5)计算出编码器损失值,并清除梯度更新一次参数(更新编码器)

Encoder定义

import torch.nn as nn

class Encoder(nn.Module):
	def __init__(self, av_size, d_size, gc_size, z_size, rep_size):
		"""
		:param av_size: D_A
		:param d_size: D_X
		:param gc_size: D'
		:param z_size: z
		"""
		super(Encoder, self).__init__()
		# input parameters
		self.z_size = z_size
		self.attr_vec = None
		self.gc_size = gc_size
		self.z_size = z_size
		self.d_size = d_size
		self.av_size = av_size
		self.rep_size = rep_size

		self.gc = GraphConvolution(d_size + av_size, gc_size)
		self.gc_mu = GraphConvolution(gc_size, z_size)
		self.gc_logvar = GraphConvolution(gc_size, z_size)

		self.mean = nn.Sequential(nn.Linear(self.gc_size, int(self.gc_size / 4)),
								  nn.BatchNorm1d(int(self.gc_size / 4)),
								  nn.ReLU(),
								  nn.Linear(int(self.gc_size / 4), self.z_size))

		self.logvar = nn.Sequential(nn.Linear(self.gc_size, int(self.gc_size / 4)),
									nn.BatchNorm1d(int(self.gc_size / 4)),
									nn.ReLU(),
									nn.Linear(int(self.gc_size / 4), self.z_size))

	def set_attr_vec(self, attr_vec):
		self.attr_vec = attr_vec

	def forward(self, adj):
		t0 = time.time()
		x = get_spectral_embedding(adj, d=self.d_size)
		t1 = time.time()
		adj = normalize(adj)
		x = cat_attr(x, self.attr_vec)
		x = F.relu(self.gc(x, adj))
		x = F.dropout(x, p=0.5)
		z_mean = self.mean(x)
		z_logvar = self.logvar(x)
		return z_mean, z_logvar

prior_loss计算过程:

encoder = Encoder(*args)
mean, logvar = encoder(adj)# 这里调用的是Encoder.forward(adj)
for j in range(mean.size()[0]):
    prior_loss = 1 + logvar[j, :] - mean[j, :].pow(2) - logvar[j, :].exp()
    prior_loss = (-0.5 * torch.sum(prior_loss)) / torch.numel(mean[j, :].data)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值