Hi,
I am building a recommender system using GNN and DGL. My graph is heterogeneous : I have 3 types of nodes (‘user’, ‘item’, ‘sport’), and 6 types of relations (user - buys - item, item - boughtby - user, user - practices - sport, etc.).
My main model consists of multiple layers of HeteroGraphConv. In the HeteroGraphConv, I specify a custom ConvLayer for each different relations.
This ConvLayer takes as input a tuple of input features dimensions (dimension of node features, dimension of neighbours nodes features), and output features dimension (dimension of the node embedding).
class ConvLayer(nn.Module):
def __init__(self,
in_feats,
out_feats):
super(ConvLayer, self).__init__()
self._in_self_feats, self._in_neigh_feats = in_feats
self._out_feats = out_feats
self.fc_self = nn.Linear(self._in_self_feats, out_feats)
self.fc_neigh = nn.Linear(self._in_neigh_feats, out_feats)
def forward(self, graph, x):
print(self._in_self_feats, self._in_neigh_feats)
h_neigh, h_self = x
graph.srcdata['h'] = h_neigh
graph.update_all(
fn.copy_src('h', 'm'),
fn.mean('m', 'neigh'))
h_neigh = graph.dstdata['neigh']
z = self.fc_self(h_self) + self.fc_neigh(h_neigh)
return z
layer = dglnn.HeteroGraphConv({'buys' : ConvLayer((user_dim, item_dim), hidden_dim), #5
'bought-by' : ConvLayer((item_dim, user_dim), hidden_dim), #1
'utilized-for' : ConvLayer((item_dim, sport_dim), hidden_dim), #2
'utilizes' : ConvLayer((sport_dim, item_dim), hidden_dim), #4
'practices' : ConvLayer((user_dim, sport_dim), hidden_dim), #6
'practiced-by' : ConvLayer((sport_dim, user_dim), hidden_dim)}, #3
aggregate='sum')
However, when I run my training, and I try to print the self._in_self_feats, self._in_neigh_feats, I do not get the right input dimensions.
E.g., ‘utilized-for’ seems to be the second relation type to be considered by HeteroGraphConv. The input dimension should be item dimension, sport dimension. But when I print them, I get sport dimension, user dimension.
Thanks in advance!