354 lines
9.2 KiB
Python
354 lines
9.2 KiB
Python
import torch
|
|
import torch.nn as nn
|
|
|
|
from dgl.nn.pytorch import (
|
|
AGNNConv,
|
|
APPNPConv,
|
|
ChebConv,
|
|
GATConv,
|
|
GINConv,
|
|
GraphConv,
|
|
SAGEConv,
|
|
SGConv,
|
|
TAGConv,
|
|
)
|
|
|
|
|
|
class GCN(nn.Module):
|
|
def __init__(
|
|
self, g, in_feats, n_classes, n_hidden, n_layers, activation, dropout
|
|
):
|
|
super(GCN, self).__init__()
|
|
self.g = g
|
|
self.layers = nn.ModuleList()
|
|
# input layer
|
|
self.layers.append(GraphConv(in_feats, n_hidden, activation=activation))
|
|
# hidden layers
|
|
for i in range(n_layers - 1):
|
|
self.layers.append(
|
|
GraphConv(n_hidden, n_hidden, activation=activation)
|
|
)
|
|
# output layer
|
|
self.layers.append(GraphConv(n_hidden, n_classes))
|
|
self.dropout = nn.Dropout(p=dropout)
|
|
|
|
def forward(self, features):
|
|
h = features
|
|
for i, layer in enumerate(self.layers):
|
|
if i != 0:
|
|
h = self.dropout(h)
|
|
h = layer(self.g, h)
|
|
return h
|
|
|
|
|
|
class GAT(nn.Module):
|
|
def __init__(
|
|
self,
|
|
g,
|
|
in_dim,
|
|
num_classes,
|
|
num_hidden,
|
|
num_layers,
|
|
heads,
|
|
activation,
|
|
feat_drop,
|
|
attn_drop,
|
|
negative_slope,
|
|
residual,
|
|
):
|
|
super(GAT, self).__init__()
|
|
self.g = g
|
|
self.num_layers = num_layers
|
|
self.gat_layers = nn.ModuleList()
|
|
self.activation = activation
|
|
# input projection (no residual)
|
|
self.gat_layers.append(
|
|
GATConv(
|
|
in_dim,
|
|
num_hidden,
|
|
heads[0],
|
|
feat_drop,
|
|
attn_drop,
|
|
negative_slope,
|
|
False,
|
|
self.activation,
|
|
)
|
|
)
|
|
# hidden layers
|
|
for l in range(1, num_layers):
|
|
# due to multi-head, the in_dim = num_hidden * num_heads
|
|
self.gat_layers.append(
|
|
GATConv(
|
|
num_hidden * heads[l - 1],
|
|
num_hidden,
|
|
heads[l],
|
|
feat_drop,
|
|
attn_drop,
|
|
negative_slope,
|
|
residual,
|
|
self.activation,
|
|
)
|
|
)
|
|
# output projection
|
|
self.gat_layers.append(
|
|
GATConv(
|
|
num_hidden * heads[-2],
|
|
num_classes,
|
|
heads[-1],
|
|
feat_drop,
|
|
attn_drop,
|
|
negative_slope,
|
|
residual,
|
|
None,
|
|
)
|
|
)
|
|
|
|
def forward(self, inputs):
|
|
h = inputs
|
|
for l in range(self.num_layers):
|
|
h = self.gat_layers[l](self.g, h).flatten(1)
|
|
# output projection
|
|
logits = self.gat_layers[-1](self.g, h).mean(1)
|
|
return logits
|
|
|
|
|
|
class GraphSAGE(nn.Module):
|
|
def __init__(
|
|
self,
|
|
g,
|
|
in_feats,
|
|
n_classes,
|
|
n_hidden,
|
|
n_layers,
|
|
activation,
|
|
dropout,
|
|
aggregator_type,
|
|
):
|
|
super(GraphSAGE, self).__init__()
|
|
self.layers = nn.ModuleList()
|
|
self.g = g
|
|
|
|
# input layer
|
|
self.layers.append(
|
|
SAGEConv(
|
|
in_feats,
|
|
n_hidden,
|
|
aggregator_type,
|
|
feat_drop=dropout,
|
|
activation=activation,
|
|
)
|
|
)
|
|
# hidden layers
|
|
for i in range(n_layers - 1):
|
|
self.layers.append(
|
|
SAGEConv(
|
|
n_hidden,
|
|
n_hidden,
|
|
aggregator_type,
|
|
feat_drop=dropout,
|
|
activation=activation,
|
|
)
|
|
)
|
|
# output layer
|
|
self.layers.append(
|
|
SAGEConv(
|
|
n_hidden,
|
|
n_classes,
|
|
aggregator_type,
|
|
feat_drop=dropout,
|
|
activation=None,
|
|
)
|
|
) # activation None
|
|
|
|
def forward(self, features):
|
|
h = features
|
|
for layer in self.layers:
|
|
h = layer(self.g, h)
|
|
return h
|
|
|
|
|
|
class APPNP(nn.Module):
|
|
def __init__(
|
|
self,
|
|
g,
|
|
in_feats,
|
|
n_classes,
|
|
n_hidden,
|
|
n_layers,
|
|
activation,
|
|
feat_drop,
|
|
edge_drop,
|
|
alpha,
|
|
k,
|
|
):
|
|
super(APPNP, self).__init__()
|
|
self.g = g
|
|
self.layers = nn.ModuleList()
|
|
# input layer
|
|
self.layers.append(nn.Linear(in_feats, n_hidden))
|
|
# hidden layers
|
|
for i in range(1, n_layers):
|
|
self.layers.append(nn.Linear(n_hidden, n_hidden))
|
|
# output layer
|
|
self.layers.append(nn.Linear(n_hidden, n_classes))
|
|
self.activation = activation
|
|
if feat_drop:
|
|
self.feat_drop = nn.Dropout(feat_drop)
|
|
else:
|
|
self.feat_drop = lambda x: x
|
|
self.propagate = APPNPConv(k, alpha, edge_drop)
|
|
self.reset_parameters()
|
|
|
|
def reset_parameters(self):
|
|
for layer in self.layers:
|
|
layer.reset_parameters()
|
|
|
|
def forward(self, features):
|
|
# prediction step
|
|
h = features
|
|
h = self.feat_drop(h)
|
|
h = self.activation(self.layers[0](h))
|
|
for layer in self.layers[1:-1]:
|
|
h = self.activation(layer(h))
|
|
h = self.layers[-1](self.feat_drop(h))
|
|
# propagation step
|
|
h = self.propagate(self.g, h)
|
|
return h
|
|
|
|
|
|
class TAGCN(nn.Module):
|
|
def __init__(
|
|
self, g, in_feats, n_classes, n_hidden, n_layers, activation, dropout
|
|
):
|
|
super(TAGCN, self).__init__()
|
|
self.g = g
|
|
self.layers = nn.ModuleList()
|
|
# input layer
|
|
self.layers.append(TAGConv(in_feats, n_hidden, activation=activation))
|
|
# hidden layers
|
|
for i in range(n_layers - 1):
|
|
self.layers.append(
|
|
TAGConv(n_hidden, n_hidden, activation=activation)
|
|
)
|
|
# output layer
|
|
self.layers.append(TAGConv(n_hidden, n_classes)) # activation=None
|
|
self.dropout = nn.Dropout(p=dropout)
|
|
|
|
def forward(self, features):
|
|
h = features
|
|
for i, layer in enumerate(self.layers):
|
|
if i != 0:
|
|
h = self.dropout(h)
|
|
h = layer(self.g, h)
|
|
return h
|
|
|
|
|
|
class AGNN(nn.Module):
|
|
def __init__(
|
|
self,
|
|
g,
|
|
in_feats,
|
|
n_classes,
|
|
n_hidden,
|
|
n_layers,
|
|
init_beta,
|
|
learn_beta,
|
|
dropout,
|
|
):
|
|
super(AGNN, self).__init__()
|
|
self.g = g
|
|
self.layers = nn.ModuleList(
|
|
[AGNNConv(init_beta, learn_beta) for _ in range(n_layers)]
|
|
)
|
|
self.proj = nn.Sequential(
|
|
nn.Dropout(dropout), nn.Linear(in_feats, n_hidden), nn.ReLU()
|
|
)
|
|
self.cls = nn.Sequential(
|
|
nn.Dropout(dropout), nn.Linear(n_hidden, n_classes)
|
|
)
|
|
|
|
def forward(self, features):
|
|
h = self.proj(features)
|
|
for layer in self.layers:
|
|
h = layer(self.g, h)
|
|
return self.cls(h)
|
|
|
|
|
|
class SGC(nn.Module):
|
|
def __init__(self, g, in_feats, n_classes, n_hidden, k, bias):
|
|
super(SGC, self).__init__()
|
|
self.g = g
|
|
self.net = SGConv(in_feats, n_classes, k=k, cached=True, bias=bias)
|
|
|
|
def forward(self, features):
|
|
return self.net(self.g, features)
|
|
|
|
|
|
class GIN(nn.Module):
|
|
def __init__(
|
|
self, g, in_feats, n_classes, n_hidden, n_layers, init_eps, learn_eps
|
|
):
|
|
super(GIN, self).__init__()
|
|
self.g = g
|
|
self.layers = nn.ModuleList()
|
|
self.layers.append(
|
|
GINConv(
|
|
nn.Sequential(
|
|
nn.Dropout(0.6),
|
|
nn.Linear(in_feats, n_hidden),
|
|
nn.ReLU(),
|
|
),
|
|
"mean",
|
|
init_eps,
|
|
learn_eps,
|
|
)
|
|
)
|
|
for i in range(n_layers - 1):
|
|
self.layers.append(
|
|
GINConv(
|
|
nn.Sequential(
|
|
nn.Dropout(0.6),
|
|
nn.Linear(n_hidden, n_hidden),
|
|
nn.ReLU(),
|
|
),
|
|
"mean",
|
|
init_eps,
|
|
learn_eps,
|
|
)
|
|
)
|
|
self.layers.append(
|
|
GINConv(
|
|
nn.Sequential(
|
|
nn.Dropout(0.6),
|
|
nn.Linear(n_hidden, n_classes),
|
|
),
|
|
"mean",
|
|
init_eps,
|
|
learn_eps,
|
|
)
|
|
)
|
|
|
|
def forward(self, features):
|
|
h = features
|
|
for layer in self.layers:
|
|
h = layer(self.g, h)
|
|
return h
|
|
|
|
|
|
class ChebNet(nn.Module):
|
|
def __init__(self, g, in_feats, n_classes, n_hidden, n_layers, k, bias):
|
|
super(ChebNet, self).__init__()
|
|
self.g = g
|
|
self.layers = nn.ModuleList()
|
|
self.layers.append(ChebConv(in_feats, n_hidden, k, bias=bias))
|
|
for _ in range(n_layers - 1):
|
|
self.layers.append(ChebConv(n_hidden, n_hidden, k, bias=bias))
|
|
|
|
self.layers.append(ChebConv(n_hidden, n_classes, k, bias=bias))
|
|
|
|
def forward(self, features):
|
|
h = features
|
|
for layer in self.layers:
|
|
h = layer(self.g, h, [2])
|
|
return h
|