MCPcopy Create free account
hub / github.com/DeepGraphLearning/S3F / GVPConvLayer

Class GVPConvLayer

s3f/gvp_layer.py:293–388  ·  view source on GitHub ↗

Full graph convolution / message passing layer with Geometric Vector Perceptrons. Residually updates node embeddings with aggregated incoming messages, applies a pointwise feedforward network to node embeddings, and returns updated node embeddings. To only compute the agg

Source from the content-addressed store, hash-verified

291
292
293class GVPConvLayer(nn.Module):
294 '''
295 Full graph convolution / message passing layer with
296 Geometric Vector Perceptrons. Residually updates node embeddings with
297 aggregated incoming messages, applies a pointwise feedforward
298 network to node embeddings, and returns updated node embeddings.
299
300 To only compute the aggregated messages, see `GVPConv`.
301
302 :param node_dims: node embedding dimensions (n_scalar, n_vector)
303 :param edge_dims: input edge embedding dimensions (n_scalar, n_vector)
304 :param n_message: number of GVPs to use in message function
305 :param n_feedforward: number of GVPs to use in feedforward function
306 :param drop_rate: drop probability in all dropout layers
307 :param autoregressive: if `True`, this `GVPConvLayer` will be used
308 with a different set of input node embeddings for messages
309 where src >= dst
310 :param activations: tuple of functions (scalar_act, vector_act) to use in GVPs
311 :param vector_gate: whether to use vector gating.
312 (vector_act will be used as sigma^+ in vector gating if `True`)
313 '''
314 def __init__(self, node_dims, edge_dims,
315 n_message=3, n_feedforward=2, drop_rate=.1,
316 autoregressive=False,
317 activations=(F.relu, torch.sigmoid), vector_gate=False):
318
319 super(GVPConvLayer, self).__init__()
320 self.conv = GVPConv(node_dims, node_dims, edge_dims, n_message,
321 aggr="add" if autoregressive else "mean",
322 activations=activations, vector_gate=vector_gate)
323 GVP_ = functools.partial(GVP,
324 activations=activations, vector_gate=vector_gate)
325 self.norm = nn.ModuleList([GVPLayerNorm(node_dims) for _ in range(2)])
326 self.dropout = nn.ModuleList([Dropout(drop_rate) for _ in range(2)])
327
328 ff_func = []
329 if n_feedforward == 1:
330 ff_func.append(GVP_(node_dims, node_dims, activations=(None, None)))
331 else:
332 hid_dims = 4*node_dims[0], 2*node_dims[1]
333 ff_func.append(GVP_(node_dims, hid_dims))
334 for i in range(n_feedforward-2):
335 ff_func.append(GVP_(hid_dims, hid_dims))
336 ff_func.append(GVP_(hid_dims, node_dims, activations=(None, None)))
337 self.ff_func = nn.Sequential(*ff_func)
338
339 def forward(self, x, edge_index, edge_attr,
340 autoregressive_x=None, node_mask=None):
341 '''
342 :param x: tuple (s, V) of `torch.Tensor`
343 :param edge_index: array of shape [2, n_edges]
344 :param edge_attr: tuple (s, V) of `torch.Tensor`
345 :param autoregressive_x: tuple (s, V) of `torch.Tensor`.
346 If not `None`, will be used as src node embeddings
347 for forming messages where src >= dst. The corrent node
348 embeddings `x` will still be the base of the update and the
349 pointwise feedforward.
350 :param node_mask: array of type `bool` to index into the first

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected