"...git@developer.sourcefind.cn:renzhc/diffusers_dcu.git" did not exist on "ada09bd3f0b38be6694f492c8ea463fd101f86cb"
Unverified Commit 2fbffd31 authored by Quan (Andy) Gan's avatar Quan (Andy) Gan Committed by GitHub
Browse files

[bug][doc] Fix bug in batched heterograph training documentation (#2204)



* [bug][doc] Fix bug in batched heterograph training documentation

* added references of "above" with hyperlinks

* address comments

* fix API doc on EdgeDataLoader
Co-authored-by: default avatarMufei Li <mufeili1996@gmail.com>
parent f3f646bb
...@@ -51,7 +51,8 @@ node representations on each edge. ...@@ -51,7 +51,8 @@ node representations on each edge.
import dgl.function as fn import dgl.function as fn
class DotProductPredictor(nn.Module): class DotProductPredictor(nn.Module):
def forward(self, graph, h): def forward(self, graph, h):
# h contains the node representations computed from the GNN above. # h contains the node representations computed from the GNN defined
# in the node classification section (Section 5.1).
with graph.local_scope(): with graph.local_scope():
graph.ndata['h'] = h graph.ndata['h'] = h
graph.apply_edges(fn.u_dot_v('h', 'h', 'score')) graph.apply_edges(fn.u_dot_v('h', 'h', 'score'))
...@@ -75,7 +76,8 @@ e.g. as logits of a categorical distribution. ...@@ -75,7 +76,8 @@ e.g. as logits of a categorical distribution.
return {'score': score} return {'score': score}
def forward(self, graph, h): def forward(self, graph, h):
# h contains the node representations computed from the GNN above. # h contains the node representations computed from the GNN defined
# in the node classification section (Section 5.1).
with graph.local_scope(): with graph.local_scope():
graph.ndata['h'] = h graph.ndata['h'] = h
graph.apply_edges(self.apply_edges) graph.apply_edges(self.apply_edges)
...@@ -122,6 +124,7 @@ not include early stopping and model saving. ...@@ -122,6 +124,7 @@ not include early stopping and model saving.
opt.step() opt.step()
print(loss.item()) print(loss.item())
.. _guide-training-edge-classification-heterogeneous-graph:
Heterogeneous graph Heterogeneous graph
~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~
...@@ -141,7 +144,8 @@ heterogeneous graph, you only need to specify the edge type in ...@@ -141,7 +144,8 @@ heterogeneous graph, you only need to specify the edge type in
class HeteroDotProductPredictor(nn.Module): class HeteroDotProductPredictor(nn.Module):
def forward(self, graph, h, etype): def forward(self, graph, h, etype):
# h contains the node representations for each edge type computed from # h contains the node representations for each edge type computed from
# the GNN above. # the GNN for heterogeneous graphs defined in the node classification
# section (Section 5.1).
with graph.local_scope(): with graph.local_scope():
graph.ndata['h'] = h # assigns 'h' of all node types in one shot graph.ndata['h'] = h # assigns 'h' of all node types in one shot
graph.apply_edges(fn.u_dot_v('h', 'h', 'score'), etype=etype) graph.apply_edges(fn.u_dot_v('h', 'h', 'score'), etype=etype)
...@@ -163,7 +167,9 @@ You can similarly write a ``HeteroMLPPredictor``. ...@@ -163,7 +167,9 @@ You can similarly write a ``HeteroMLPPredictor``.
return {'score': score} return {'score': score}
def forward(self, graph, h, etype): def forward(self, graph, h, etype):
# h contains the node representations computed from the GNN above. # h contains the node representations for each edge type computed from
# the GNN for heterogeneous graphs defined in the node classification
# section (Section 5.1).
with graph.local_scope(): with graph.local_scope():
graph.ndata['h'] = h # assigns 'h' of all node types in one shot graph.ndata['h'] = h # assigns 'h' of all node types in one shot
graph.apply_edges(self.apply_edges, etype=etype) graph.apply_edges(self.apply_edges, etype=etype)
...@@ -217,16 +223,18 @@ Predicting Edge Type of an Existing Edge on a Heterogeneous Graph ...@@ -217,16 +223,18 @@ Predicting Edge Type of an Existing Edge on a Heterogeneous Graph
Sometimes you may want to predict which type an existing edge belongs Sometimes you may want to predict which type an existing edge belongs
to. to.
For instance, given the heterogeneous graph above, your task is given an For instance, given the
edge connecting a user and an item, predict whether the user would :ref:`heterogeneous graph example <guide-training-heterogeneous-graph-example>`,
``click`` or ``dislike`` an item. your task is given an edge connecting a user and an item, to predict whether
the user would ``click`` or ``dislike`` an item.
This is a simplified version of rating prediction, which is common in This is a simplified version of rating prediction, which is common in
recommendation literature. recommendation literature.
You can use a heterogeneous graph convolution network to obtain the node You can use a heterogeneous graph convolution network to obtain the node
representations. For instance, you can still use the RGCN above for this representations. For instance, you can still use the
purpose. :ref:`RGCN defined previously <guide-training-rgcn-node-classification>`
for this purpose.
To predict the type of an edge, you can simply repurpose the To predict the type of an edge, you can simply repurpose the
``HeteroDotProductPredictor`` above so that it takes in another graph ``HeteroDotProductPredictor`` above so that it takes in another graph
...@@ -235,14 +243,17 @@ predicted, and emits the score of each type for every edge. ...@@ -235,14 +243,17 @@ predicted, and emits the score of each type for every edge.
In the example here, you will need a graph that has two node types In the example here, you will need a graph that has two node types
``user`` and ``item``, and one single edge type that merges all the ``user`` and ``item``, and one single edge type that merges all the
edge types from ``user`` and ``item``, i.e. ``like`` and ``dislike``. edge types from ``user`` and ``item``, i.e. ``click`` and ``dislike``.
This can be conveniently created using This can be conveniently created using the following syntax:
:meth:`relation slicing <dgl.DGLHeteroGraph.__getitem__>`.
.. code:: python .. code:: python
dec_graph = hetero_graph['user', :, 'item'] dec_graph = hetero_graph['user', :, 'item']
which returns a heterogeneous graphs with node type ``user`` and ``item``,
as well as a single edge type combining all edge types in between, i.e.
``click`` and ``dislike``.
Since the statement above also returns the original edge types as a Since the statement above also returns the original edge types as a
feature named ``dgl.ETYPE``, we can use that as labels. feature named ``dgl.ETYPE``, we can use that as labels.
...@@ -267,7 +278,8 @@ can write your predictor module as follows. ...@@ -267,7 +278,8 @@ can write your predictor module as follows.
def forward(self, graph, h): def forward(self, graph, h):
# h contains the node representations for each edge type computed from # h contains the node representations for each edge type computed from
# the GNN above. # the GNN for heterogeneous graphs defined in the node classification
# section (Section 5.1).
with graph.local_scope(): with graph.local_scope():
graph.ndata['h'] = h # assigns 'h' of all node types in one shot graph.ndata['h'] = h # assigns 'h' of all node types in one shot
graph.apply_edges(self.apply_edges) graph.apply_edges(self.apply_edges)
......
...@@ -233,14 +233,14 @@ representations for each node type. ...@@ -233,14 +233,14 @@ representations for each node type.
class RGCN(nn.Module): class RGCN(nn.Module):
def __init__(self, in_feats, hid_feats, out_feats, rel_names): def __init__(self, in_feats, hid_feats, out_feats, rel_names):
super().__init__() super().__init__()
self.conv1 = dglnn.HeteroGraphConv({ self.conv1 = dglnn.HeteroGraphConv({
rel: dglnn.GraphConv(in_feats, hid_feats) rel: dglnn.GraphConv(in_feats, hid_feats)
for rel in rel_names}, aggregate='sum') for rel in rel_names}, aggregate='sum')
self.conv2 = dglnn.HeteroGraphConv({ self.conv2 = dglnn.HeteroGraphConv({
rel: dglnn.GraphConv(hid_feats, out_feats) rel: dglnn.GraphConv(hid_feats, out_feats)
for rel in rel_names}, aggregate='sum') for rel in rel_names}, aggregate='sum')
def forward(self, graph, inputs): def forward(self, graph, inputs):
# inputs are features of nodes # inputs are features of nodes
h = self.conv1(graph, inputs) h = self.conv1(graph, inputs)
...@@ -251,21 +251,13 @@ representations for each node type. ...@@ -251,21 +251,13 @@ representations for each node type.
class HeteroClassifier(nn.Module): class HeteroClassifier(nn.Module):
def __init__(self, in_dim, hidden_dim, n_classes, rel_names): def __init__(self, in_dim, hidden_dim, n_classes, rel_names):
super().__init__() super().__init__()
self.conv1 = dglnn.HeteroGraphConv({ self.rgcn = RGCN(in_dim, hidden_dim, hidden_dim, rel_names)
rel: dglnn.GraphConv(in_feats, hid_feats)
for rel in rel_names}, aggregate='sum')
self.conv2 = dglnn.HeteroGraphConv({
rel: dglnn.GraphConv(hid_feats, out_feats)
for rel in rel_names}, aggregate='sum')
self.classify = nn.Linear(hidden_dim, n_classes) self.classify = nn.Linear(hidden_dim, n_classes)
def forward(self, g): def forward(self, g):
h = g.ndata['feat'] h = g.ndata['feat']
# Apply graph convolution and activation. h = self.rgcn(g, h)
h = F.relu(self.conv1(g, h))
h = F.relu(self.conv2(g, h))
with g.local_scope(): with g.local_scope():
g.ndata['h'] = h g.ndata['h'] = h
# Calculate graph representation by average readout. # Calculate graph representation by average readout.
...@@ -278,7 +270,8 @@ The rest of the code is not different from that for homogeneous graphs. ...@@ -278,7 +270,8 @@ The rest of the code is not different from that for homogeneous graphs.
.. code:: python .. code:: python
model = HeteroClassifier(10, 20, 5) # etypes is the list of edge types as strings.
model = HeteroClassifier(10, 20, 5, etypes)
opt = torch.optim.Adam(model.parameters()) opt = torch.optim.Adam(model.parameters())
for epoch in range(20): for epoch in range(20):
for batched_graph, labels in dataloader: for batched_graph, labels in dataloader:
......
...@@ -52,7 +52,8 @@ Model Implementation Difference from Edge Classification ...@@ -52,7 +52,8 @@ Model Implementation Difference from Edge Classification
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The neural network model to compute the score between :math:`u` and The neural network model to compute the score between :math:`u` and
:math:`v` is identical to the edge regression model described above. :math:`v` is identical to the edge regression model described
:ref:`above <guide-training-edge-classification>`.
Here is an example of using dot product to compute the scores on edges. Here is an example of using dot product to compute the scores on edges.
...@@ -60,7 +61,8 @@ Here is an example of using dot product to compute the scores on edges. ...@@ -60,7 +61,8 @@ Here is an example of using dot product to compute the scores on edges.
class DotProductPredictor(nn.Module): class DotProductPredictor(nn.Module):
def forward(self, graph, h): def forward(self, graph, h):
# h contains the node representations computed from the GNN above. # h contains the node representations computed from the GNN defined
# in the node classification section (Section 5.1).
with graph.local_scope(): with graph.local_scope():
graph.ndata['h'] = h graph.ndata['h'] = h
graph.apply_edges(fn.u_dot_v('h', 'h', 'score')) graph.apply_edges(fn.u_dot_v('h', 'h', 'score'))
...@@ -143,15 +145,16 @@ Link prediction on heterogeneous graphs is not very different from that ...@@ -143,15 +145,16 @@ Link prediction on heterogeneous graphs is not very different from that
on homogeneous graphs. The following assumes that we are predicting on on homogeneous graphs. The following assumes that we are predicting on
one edge type, and it is easy to extend it to multiple edge types. one edge type, and it is easy to extend it to multiple edge types.
For example, you can reuse the ``HeteroDotProductPredictor`` above for For example, you can reuse the ``HeteroDotProductPredictor``
computing the scores of the edges of an edge type for link prediction. :ref:`above <guide-training-edge-classification-heterogeneous-graph>`
for computing the scores of the edges of an edge type for link prediction.
.. code:: python .. code:: python
class HeteroDotProductPredictor(nn.Module): class HeteroDotProductPredictor(nn.Module):
def forward(self, graph, h, etype): def forward(self, graph, h, etype):
# h contains the node representations for each edge type computed from # h contains the node representations for each node type computed from
# the GNN above. # the GNN defined in the previous section (Section 5.1).
with graph.local_scope(): with graph.local_scope():
graph.ndata['h'] = h graph.ndata['h'] = h
graph.apply_edges(fn.u_dot_v('h', 'h', 'score'), etype=etype) graph.apply_edges(fn.u_dot_v('h', 'h', 'score'), etype=etype)
......
...@@ -179,7 +179,8 @@ all node types. ...@@ -179,7 +179,8 @@ all node types.
feature tensors as input, and returns another dictionary of node types feature tensors as input, and returns another dictionary of node types
and node features. and node features.
So given that we have the user and item features in the example above. So given that we have the user and item features in the
:ref:`heterogeneous graph example <guide-training-heterogeneous-graph-example>`.
.. code:: python .. code:: python
......
...@@ -31,6 +31,8 @@ get the graph for a single-graph dataset with something like ...@@ -31,6 +31,8 @@ get the graph for a single-graph dataset with something like
Note: In this chapter we will use PyTorch as backend. Note: In this chapter we will use PyTorch as backend.
.. _guide-training-heterogeneous-graph-example:
Heterogeneous Graphs Heterogeneous Graphs
~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment