(self, inputs, training=None)
| 329 | self.store_optimizer = tf.train.AdamOptimizer(self.store_learning_rate) |
| 330 | |
| 331 | def call(self, inputs, training=None): |
| 332 | if not training: |
| 333 | return super(ScalableGCNEncoder, self).call(inputs) |
| 334 | |
| 335 | (node, neighbor), (adj,) = \ |
| 336 | euler_ops.get_multi_hop_neighbor(inputs, [self.edge_type]) |
| 337 | node_embedding = self.node_encoder(node) |
| 338 | neigh_embedding = self.node_encoder(neighbor) |
| 339 | |
| 340 | node_embeddings = [] |
| 341 | neigh_embeddings = [] |
| 342 | for layer in range(self.num_layers): |
| 343 | aggregator = self.aggregators[layer] |
| 344 | |
| 345 | if self.use_residual: |
| 346 | node_embedding += aggregator((node_embedding, |
| 347 | neigh_embedding, |
| 348 | adj)) |
| 349 | else: |
| 350 | node_embedding = aggregator((node_embedding, |
| 351 | neigh_embedding, |
| 352 | adj)) |
| 353 | node_embeddings.append(node_embedding) |
| 354 | |
| 355 | if layer < self.num_layers - 1: |
| 356 | neigh_embedding = \ |
| 357 | tf.nn.embedding_lookup(self.stores[layer], neighbor) |
| 358 | neigh_embeddings.append(neigh_embedding) |
| 359 | |
| 360 | self.update_store_op = self._update_store(node, node_embeddings) |
| 361 | store_loss, self.optimize_store_op = \ |
| 362 | self._optimize_store(node, node_embeddings) |
| 363 | self.get_update_gradient_op = lambda loss: \ |
| 364 | self._update_gradient(loss + store_loss, |
| 365 | neighbor, |
| 366 | neigh_embeddings) |
| 367 | |
| 368 | output_shape = inputs.shape.concatenate(node_embedding.shape[-1]) |
| 369 | output_shape = [d if d is not None else -1 |
| 370 | for d in output_shape.as_list()] |
| 371 | return tf.reshape(node_embedding, output_shape) |
| 372 | |
| 373 | def _update_store(self, node, node_embeddings): |
| 374 | update_ops = [] |
nothing calls this directly
no test coverage detected