Difference edge data , src and dst

I learned ResGatedGCN: Residual Gated Graph ConvNets . But i have a miss understand some concept. What is src and dst in message_func . Example in below code what is different g.ndata[‘Dh’] = self.D(h) and edges.src[‘Dh’] . Thank so much
class GatedGCNLayer(nn.Module):
“”"
Param: []
“”"
def init(self, input_dim, output_dim, dropout, graph_norm, batch_norm, residual=False):
super().init()
self.in_channels = input_dim
self.out_channels = output_dim
self.dropout = dropout
self.graph_norm = graph_norm
self.batch_norm = batch_norm
self.residual = residual

    if input_dim != output_dim:
        self.residual = False
    
    self.A = nn.Linear(input_dim, output_dim, bias=True)
    self.B = nn.Linear(input_dim, output_dim, bias=True)
    self.C = nn.Linear(input_dim, output_dim, bias=True)
    self.D = nn.Linear(input_dim, output_dim, bias=True)
    self.E = nn.Linear(input_dim, output_dim, bias=True)
    
    self.bn_node_h = GraphNorm(output_dim)
    self.bn_node_e = GraphNorm(output_dim)

def message_func(self, edges):
    Bh_j = edges.src['Bh']    
    e_ij = edges.data['Ce'] +  edges.src['Dh'] + edges.dst['Eh'] # e_ij = Ce_ij + Dhi + Ehj
    edges.data['e'] = e_ij
    return {'Bh_j' : Bh_j, 'e_ij' : e_ij}

def reduce_func(self, nodes):
    Ah_i = nodes.data['Ah']
    Bh_j = nodes.mailbox['Bh_j']
    e = nodes.mailbox['e_ij'] 
    sigma_ij = torch.sigmoid(e) # sigma_ij = sigmoid(e_ij)
    #h = Ah_i + torch.mean( sigma_ij * Bh_j, dim=1 ) # hi = Ahi + mean_j alpha_ij * Bhj 
    h = Ah_i + torch.sum(sigma_ij * Bh_j, dim=1 ) / ( torch.sum( sigma_ij, dim=1 ) + 1e-6 )  # hi = Ahi + sum_j eta_ij/sum_j' eta_ij' * Bhj <= dense attention       
    return {'h' : h}

def forward(self, g, h, e, snorm_n, snorm_e, graph_node_size, graph_edge_size):
    
    h_in = h # for residual connection
    e_in = e # for residual connection
    # g.ndata['h']  = h 
    g.ndata['h'] = h
    g.ndata['Ah'] = self.A(h) 
    g.ndata['Bh'] = self.B(h) 
    g.ndata['Dh'] = self.D(h)
    g.ndata['Eh'] = self.E(h) 
    g.edata['e']  = e 
    g.edata['Ce'] = self.C(e) 
    g.update_all(self.message_func,self.reduce_func) 
    h = g.ndata['h'] # result of graph convolution
    e = g.edata['e'] # result of graph convolution
    
    if self.graph_norm:
        h = h * snorm_n # normalize activation w.r.t. graph size
        e = e * snorm_e # normalize activation w.r.t. graph size
    
    if self.batch_norm:
        h = self.bn_node_h(h, graph_node_size) # graph normalization  
        e = self.bn_node_e(e, graph_edge_size) # graph normalization  

    
    h = F.relu(h) # non-linear activation
    e = F.relu(e) # non-linear activation
    
    if self.residual:
        h = h_in + h # residual connection
        e = e_in + e # residual connection
    
    h = F.dropout(h, self.dropout, training=self.training)
    e = F.dropout(e, self.dropout, training=self.training)
    
    return h, e

See User-defined Functions.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.