I am trying to minimize a custom loss function for a Variational Graph Auto-Encoder. However, my custom loss function is not decreasing, and I am not sure why. Any help is appreciated. Thanks in advance!!!
def network_stat(adj):
# Given a adjacency matrix, calculate graph statistics
# (holderA) Num of edges and (holderB) Num of two-stars
n = adj.shape[0]
holderA = torch.tensor([0],dtype=torch.float32)
holderB = torch.tensor([0],dtype=torch.float32)
for i in range(n):
for j in range(n):
if i < j:
holderA = holderA + adj[i,j]
for k in range(n):
if i < j and j < k:
holderB = holderB + (adj[i,k] * adj[j,k])
holder = torch.cat((holderA, holderB), dim=0)
return(holder)
class GVAE(nn.Module):
def __init__(self, feature_size):
super(GVAE, self).__init__()
self.encoder_embedding_size = 32
self.latent_size = 5
self.encode_conv1 = GCNConv(feature_size, 2 * self.encoder_embedding_size)
self.encode_conv2 = GCNConv(2 * self.encoder_embedding_size, 2 * self.encoder_embedding_size)
self.conv_mean = GCNConv(2 * self.encoder_embedding_size, self.latent_size)
self.conv_logstd = GCNConv(2 * self.encoder_embedding_size, self.latent_size)
def reparameterize(self, mu, logstd):
noise = torch.randn(NUM_NODE, self.latent_size)
output = mu + torch.exp(logstd) * noise
return output
def encode(self, x, edge_index):
x = self.encode_conv1(x, edge_index).tanh()
x = self.encode_conv2(x, edge_index).tanh()
mu = self.conv_mean(x, edge_index).tanh()
logstd = self.conv_logstd(x, edge_index).tanh()
return mu, logstd
def decode(self, Z):
return torch.sigmoid(torch.matmul(Z,Z.t()))
def forward(self, x, edge_index):
mu, logstd = self.encode(x, edge_index)
Z = self.reparameterize(mu, logstd)
A_pred = self.decode(Z)
return A_pred
def loss_function(A_pred):
# GOAL: generated graph has 15 edges and 10 two-star from the above network_stat(adj) function
g_exp = network_stat(torch.round(A_pred))
loss = torch.sum( (g_exp - torch.tensor([15,10],dtype=torch.float32))**2 )
return loss
model = GVAE(feature_size=NUM_NODE)
optimizer = torch.optim.Adam(model.parameters(), lr=0.000001)
for min_epoch in range(10000):
A_pred = model(node_feature, edge_list)
loss = loss_function(A_pred)
loss.backward()
optimizer.step()
optimizer.zero_grad()