(self, inputs, training=None)
| 673 | self.store_optimizer = tf.train.AdamOptimizer(self.store_learning_rate) |
| 674 | |
| 675 | def call(self, inputs, training=None): |
| 676 | if not training: |
| 677 | return super(ScalableSageEncoder, self).call(inputs) |
| 678 | |
| 679 | node, neighbor = samples = euler_ops.sample_fanout( |
| 680 | inputs, [self.edge_type], [self.fanout], |
| 681 | default_node=self.max_id + 1)[0] |
| 682 | node_embedding, neigh_embedding = [self.node_encoder(sample) |
| 683 | for sample in samples] |
| 684 | |
| 685 | node_embeddings = [] |
| 686 | neigh_embeddings = [] |
| 687 | for layer in range(self.num_layers): |
| 688 | aggregator = self.aggregators[layer] |
| 689 | |
| 690 | neigh_shape = [-1, self.fanout, self.dims[layer]] |
| 691 | neigh_embedding = tf.reshape(neigh_embedding, neigh_shape) |
| 692 | node_embedding = aggregator((node_embedding, neigh_embedding)) |
| 693 | node_embeddings.append(node_embedding) |
| 694 | |
| 695 | if layer < self.num_layers - 1: |
| 696 | neigh_embedding = \ |
| 697 | tf.nn.embedding_lookup(self.stores[layer], neighbor) |
| 698 | neigh_embeddings.append(neigh_embedding) |
| 699 | |
| 700 | self.update_store_op = self._update_store(node, node_embeddings) |
| 701 | store_loss, self.optimize_store_op = \ |
| 702 | self._optimize_store(node, node_embeddings) |
| 703 | self.get_update_gradient_op = lambda loss: \ |
| 704 | self._update_gradient(loss + store_loss, |
| 705 | neighbor, |
| 706 | neigh_embeddings) |
| 707 | |
| 708 | output_shape = inputs.shape.concatenate(node_embedding.shape[-1]) |
| 709 | output_shape = [d if d is not None else -1 |
| 710 | for d in output_shape.as_list()] |
| 711 | return tf.reshape(node_embedding, output_shape) |
| 712 | |
| 713 | def _update_store(self, node, node_embeddings): |
| 714 | update_ops = [] |
nothing calls this directly
no test coverage detected