Graph Convolutional Layer described in "Semi-Supervised Classification with Graph Convolutional Networks". Given an input feature representation for each node in a graph, the Graph Convolutional Layer aims to aggregate information from the node's neighborhood to update its
| 12 | |
| 13 | |
| 14 | class GraphConv(nn.Module): |
| 15 | """ |
| 16 | Graph Convolutional Layer described in "Semi-Supervised Classification with Graph Convolutional Networks". |
| 17 | |
| 18 | Given an input feature representation for each node in a graph, the Graph Convolutional Layer aims to aggregate |
| 19 | information from the node's neighborhood to update its own representation. This is achieved by applying a graph |
| 20 | convolutional operation that combines the features of a node with the features of its neighboring nodes. |
| 21 | |
| 22 | Mathematically, the Graph Convolutional Layer can be described as follows: |
| 23 | |
| 24 | H' = f(D^(-1/2) * A * D^(-1/2) * H * W) |
| 25 | |
| 26 | where: |
| 27 | H: Input feature matrix with shape (N, F_in), where N is the number of nodes and F_in is the number of |
| 28 | input features per node. |
| 29 | A: Adjacency matrix of the graph with shape (N, N), representing the relationships between nodes. |
| 30 | W: Learnable weight matrix with shape (F_in, F_out), where F_out is the number of output features per node. |
| 31 | D: The degree matrix. |
| 32 | """ |
| 33 | def __init__(self, input_dim, output_dim, use_bias=False): |
| 34 | super(GraphConv, self).__init__() |
| 35 | |
| 36 | # Initialize the weight matrix W (in this case called `kernel`) |
| 37 | self.kernel = nn.Parameter(torch.Tensor(input_dim, output_dim)) |
| 38 | nn.init.xavier_normal_(self.kernel) # Initialize the weights using Xavier initialization |
| 39 | |
| 40 | # Initialize the bias (if use_bias is True) |
| 41 | self.bias = None |
| 42 | if use_bias: |
| 43 | self.bias = nn.Parameter(torch.Tensor(output_dim)) |
| 44 | nn.init.zeros_(self.bias) # Initialize the bias to zeros |
| 45 | |
| 46 | def forward(self, input_tensor, adj_mat): |
| 47 | """ |
| 48 | Performs a graph convolution operation. |
| 49 | |
| 50 | Args: |
| 51 | input_tensor (torch.Tensor): Input tensor representing node features. |
| 52 | adj_mat (torch.Tensor): Normalized adjacency matrix representing graph structure. |
| 53 | |
| 54 | Returns: |
| 55 | torch.Tensor: Output tensor after the graph convolution operation. |
| 56 | """ |
| 57 | |
| 58 | support = torch.mm(input_tensor, self.kernel) # Matrix multiplication between input and weight matrix |
| 59 | output = torch.spmm(adj_mat, support) # Sparse matrix multiplication between adjacency matrix and support |
| 60 | # Add the bias (if bias is not None) |
| 61 | if self.bias is not None: |
| 62 | output = output + self.bias |
| 63 | |
| 64 | return output |
| 65 | |
| 66 | |
| 67 | class GCN(nn.Module): |