def prepare_specific_graph_model(self) -> None:
        h_dim = self.params['hidden_size']
        # inputs
        self.placeholders['graph_state_keep_prob'] = tf.placeholder(
            tf.float32, None, name='graph_state_keep_prob')
        self.placeholders['initial_node_representation'] = tf.placeholder(
            tf.float32, [None, None, self.params['hidden_size']],
            name='node_features')
        self.placeholders['node_mask'] = tf.placeholder(tf.float32,
                                                        [None, None],
                                                        name='node_mask')
        self.placeholders['num_vertices'] = tf.placeholder(tf.int32, ())
        self.placeholders['adjacency_matrix'] = tf.placeholder(
            tf.float32,
            [None, self.num_edge_types, None, None])  # [b, e, v, v]
        self.__adjacency_matrix = tf.transpose(
            self.placeholders['adjacency_matrix'],
            [1, 0, 2, 3])  # [e, b, v, v]

        # weights
        self.weights['edge_weights'] = tf.Variable(
            glorot_init([self.num_edge_types, h_dim, h_dim]))
        if self.params['use_edge_bias']:
            self.weights['edge_biases'] = tf.Variable(
                np.zeros([self.num_edge_types, 1, h_dim]).astype(np.float32))
        with tf.variable_scope("gru_scope"):
            cell = tf.contrib.rnn.GRUCell(h_dim)
            cell = tf.nn.rnn_cell.DropoutWrapper(
                cell,
                state_keep_prob=self.placeholders['graph_state_keep_prob'])
            self.weights['node_gru'] = cell
    def __init__(self, config):
        self.config = config

        h_dim = self.config['gnn_h_size']
        num_edge_types = self.config['num_edge_types']

        self.weights = {}

        edge_weights = tf.Variable(glorot_init([num_edge_types * h_dim,
                                                h_dim]),
                                   name='edge_weights')
        self.weights['edge_weights'] = tf.reshape(
            edge_weights, [num_edge_types, h_dim, h_dim])

        if self.config['use_edge_bias'] == 1:
            self.weights['edge_biases'] = tf.Variable(np.zeros(
                [num_edge_types, h_dim], dtype=np.float32),
                                                      name='gnn_edge_biases')

        cell_type = self.config['graph_rnn_cell'].lower()
        activation_fun = tf.nn.tanh
        if cell_type == 'gru':
            cell = tf.nn.rnn_cell.GRUCell(h_dim, activation=activation_fun)
        elif cell_type == 'cudnncompatiblegrucell':
            import tensorflow.contrib.cudnn_rnn as cudnn_rnn
            cell = cudnn_rnn.CudnnCompatibleGRUCell(h_dim)
        elif cell_type == 'rnn':
            cell = tf.nn.rnn_cell.BasicRNNCell(h_dim,
                                               activation=activation_fun)
        else:
            raise Exception("Unknown RNN cell type '%s'." % cell_type)
        self.weights['rnn_cells'] = cell
    def prepare_specific_graph_model(self) -> None:
        h_dim = self.params['hidden_size']
        self.placeholders['initial_node_representation'] = tf.placeholder(
            tf.float32, [None, h_dim], name='node_features')
        self.placeholders['adjacency_list'] = tf.placeholder(
            tf.int64, [None, 2], name='adjacency_list')
        self.placeholders['adjacency_weights'] = tf.placeholder(
            tf.float32, [None], name='adjacency_weights')
        self.placeholders['graph_nodes_list'] = tf.placeholder(
            tf.int32, [None], name='graph_nodes_list')
        self.placeholders['graph_state_keep_prob'] = tf.placeholder(
            tf.float32, None, name='graph_state_keep_prob')

        with tf.variable_scope('gcn_scope'):
            self.weights['edge_weights'] = [
                tf.Variable(glorot_init((h_dim, h_dim)),
                            name="gcn_weights_%i" % i)
                for i in range(self.params['num_timesteps'])
            ]

            if self.params['gcn_use_bias']:
                self.weights['edge_biases'] = [
                    tf.Variable(np.zeros([h_dim], dtype=np.float32),
                                name="gcn_bias_%i" % i)
                    for i in range(self.params['num_timesteps'])
                ]
    def prepare_specific_graph_model(self) -> None:
        h_dim = self.params['hidden_size']
        self.placeholders['initial_node_representation'] = tf.placeholder(
            tf.float32, [None, h_dim], name='node_features')
        self.placeholders['adjacency_lists'] = [
            tf.placeholder(tf.int64, [None, 2], name='adjacency_e%s' % e)
            for e in range(self.num_edge_types)
        ]
        self.placeholders['num_incoming_edges_per_type'] = tf.placeholder(
            tf.float32, [None, self.num_edge_types],
            name='num_incoming_edges_per_type')
        self.placeholders['graph_nodes_list'] = tf.placeholder(
            tf.int64, [None, 2], name='graph_nodes_list')
        self.placeholders['graph_state_keep_prob'] = tf.placeholder(
            tf.float32, None, name='graph_state_keep_prob')

        activation_name = self.params['graph_rnn_activation'].lower()
        if activation_name == 'tanh':
            activation_fun = tf.nn.tanh
        elif activation_name == 'relu':
            activation_fun = tf.nn.relu
        else:
            raise Exception("Unknown activation function type '%s'." %
                            activation_name)

        # Generate per-layer values for edge weights, biases and gated units. If we tie them, they are just copies:
        self.weights['edge_weights'] = []
        self.weights['edge_biases'] = []
        self.weights['rnn_cells'] = []
        for step in range(self.params['num_timesteps']):
            with tf.variable_scope('gnn_layer_%i' % step):
                if step == 0 or not (self.params['tie_gnn_layers']):
                    self.weights['edge_weights'].append(
                        tf.Variable(glorot_init(
                            [self.num_edge_types * h_dim, h_dim]),
                                    name='gnn_edge_weights_%i' % step))

                    if self.params['use_edge_bias']:
                        self.weights['edge_biases'].append(
                            tf.Variable(np.zeros([self.num_edge_types, h_dim],
                                                 dtype=np.float32),
                                        name='gnn_edge_biases_%i' % step))

                    cell_type = self.params['graph_rnn_cell'].lower()
                    if cell_type == 'gru':
                        cell = tf.nn.rnn_cell.GRUCell(
                            h_dim, activation=activation_fun)
                    elif cell_type == 'rnn':
                        cell = tf.nn.rnn_cell.BasicRNNCell(
                            h_dim, activation=activation_fun)
                    else:
                        raise Exception("Unknown RNN cell type '%s'." %
                                        cell_type)
                    cell = tf.nn.rnn_cell.DropoutWrapper(
                        cell,
                        state_keep_prob=self.
                        placeholders['graph_state_keep_prob'])
                    self.weights['rnn_cells'].append(cell)
    def prepare_specific_graph_model(self) -> None:
        h_dim = self.params['hidden_size']
        self.placeholders['initial_node_representation'] = tf.placeholder(
            tf.float32, [None, h_dim], name='node_features')

        # Initial nodes I_{r}: Node IDs that will have no incoming edge in round r.
        self.placeholders['initial_nodes'] = [
            tf.placeholder(tf.int32, [None],
                           name="initial_nodes_round%i" % prop_round)
            for prop_round in range(self.params['propagation_rounds'])
        ]

        # Sending nodes S_{r,s,e}: Source nodes ids of edge propagating in step s of round r.
        # Restrictions: If v in S_{r,s,e}, then v in R_{r,s'} for s' < s or v in I_{r}
        self.placeholders['sending_nodes'] = [[
            [
                tf.placeholder(tf.int32, [None],
                               name="sending_nodes_round%i_step%i_edgetyp%i" %
                               (prop_round, step, edge_typ))
                for edge_typ in range(self.num_edge_types)
            ] for step in range(self.params['propagation_substeps'])
        ] for prop_round in range(self.params['propagation_rounds'])]

        # Normalised edge target nodes T_{r,s}: Targets of edge propagating in step s of round r, normalised to a
        # continuous range starting from 0. This is used for aggregating messages from the sending nodes.
        self.placeholders['msg_targets'] = [[
            tf.placeholder(tf.int32, [None],
                           name="msg_targets_nodes_round%i_step%i" %
                           (prop_round, step))
            for step in range(self.params['propagation_substeps'])
        ] for prop_round in range(self.params['propagation_rounds'])]

        # Receiving nodes R_{r,s}: Target nodes ids of aggregated messages in propagation step s of round r.
        # Restrictions: If v in R_{r,s}, v not in R_{r,s'} for all s' != s and v not in I_{r}
        self.placeholders['receiving_nodes'] = [[
            tf.placeholder(tf.int32, [None],
                           name="receiving_nodes_round%i_step%i" %
                           (prop_round, step))
            for step in range(self.params['propagation_substeps'])
        ] for prop_round in range(self.params['propagation_rounds'])]

        # Number of receiving nodes N_{r,s}
        # Restrictions: N_{r,s} = len(R_{r,s})
        self.placeholders['receiving_node_num'] = [
            tf.placeholder(tf.int32, [self.params['propagation_substeps']],
                           name="receiving_nodes_num_round%i" % (prop_round, ))
            for prop_round in range(self.params['propagation_rounds'])
        ]

        self.placeholders['graph_nodes_list'] = tf.placeholder(
            tf.int32, [None], name='graph_nodes_list')
        self.placeholders['graph_state_keep_prob'] = tf.placeholder(
            tf.float32, None, name='graph_state_keep_prob')

        activation_name = self.params['graph_rnn_activation'].lower()
        if activation_name == 'tanh':
            activation_fun = tf.nn.tanh
        elif activation_name == 'relu':
            activation_fun = tf.nn.relu
        else:
            raise Exception("Unknown activation function type '%s'." %
                            activation_name)

        # Generate per-layer values for edge weights, biases and gated units. If we tie them, they are just copies:
        self.weights['edge_weights'] = [
            tf.Variable(glorot_init([h_dim, h_dim]),
                        name='gnn_edge_weights_typ%i' % e_typ)
            for e_typ in range(self.num_edge_types)
        ]

        if self.params['use_edge_bias']:
            self.weights['edge_biases'] = [
                tf.Variable(np.zeros([h_dim], dtype=np.float32),
                            name='gnn_edge_biases_typ%i' % e_typ)
                for e_typ in range(self.num_edge_types)
            ]

        cell_type = self.params['graph_rnn_cell'].lower()
        if cell_type == 'gru':
            cell = tf.nn.rnn_cell.GRUCell(h_dim, activation=activation_fun)
        elif cell_type == 'rnn':
            cell = tf.nn.rnn_cell.BasicRNNCell(h_dim,
                                               activation=activation_fun)
        else:
            raise Exception("Unknown RNN cell type '%s'." % cell_type)
        cell = tf.nn.rnn_cell.DropoutWrapper(
            cell, state_keep_prob=self.placeholders['graph_state_keep_prob'])
        self.weights['rnn_cells'] = cell
    def prepare_specific_graph_model(self) -> None:
        h_dim = self.params['hidden_size']
        self.placeholders['initial_node_representation'] = tf.placeholder(
            tf.float32, [None, h_dim], name='node_features')
        self.placeholders['adjacency_lists'] = [
            tf.placeholder(tf.int32, [None, 2], name='adjacency_e%s' % e)
            for e in range(self.num_edge_types)
        ]
        self.placeholders['num_incoming_edges_per_type'] = tf.placeholder(
            tf.float32, [None, self.num_edge_types],
            name='num_incoming_edges_per_type')
        self.placeholders['graph_nodes_list'] = tf.placeholder(
            tf.int32, [None], name='graph_nodes_list')
        self.placeholders['graph_state_keep_prob'] = tf.placeholder(
            tf.float32, None, name='graph_state_keep_prob')
        self.placeholders['edge_weight_dropout_keep_prob'] = tf.placeholder(
            tf.float32, None, name='edge_weight_dropout_keep_prob')

        activation_name = self.params['graph_rnn_activation'].lower()
        if activation_name == 'tanh':
            activation_fun = tf.nn.tanh
        elif activation_name == 'relu':
            activation_fun = tf.nn.relu
        else:
            raise Exception("Unknown activation function type '%s'." %
                            activation_name)

        # Generate per-layer values for edge weights, biases and gated units:
        self.weights = {}  # Used by super-class to place generic things
        self.gnn_weights = GGNNWeights([], [], [], [])
        for layer_idx in range(len(self.params['layer_timesteps'])):
            with tf.variable_scope('gnn_layer_%i' % layer_idx):
                edge_weights = tf.Variable(
                    glorot_init([self.num_edge_types * h_dim, h_dim]),
                    name='gnn_edge_weights_%i' % layer_idx)
                edge_weights = tf.reshape(edge_weights,
                                          [self.num_edge_types, h_dim, h_dim])
                edge_weights = tf.nn.dropout(
                    edge_weights,
                    keep_prob=self.
                    placeholders['edge_weight_dropout_keep_prob'])
                self.gnn_weights.edge_weights.append(edge_weights)

                if self.params['use_propagation_attention']:
                    self.gnn_weights.edge_type_attention_weights.append(
                        tf.Variable(np.ones([self.num_edge_types],
                                            dtype=np.float32),
                                    name='edge_type_attention_weights_%i' %
                                    layer_idx))

                if self.params['use_edge_bias']:
                    self.gnn_weights.edge_biases.append(
                        tf.Variable(np.zeros([self.num_edge_types, h_dim],
                                             dtype=np.float32),
                                    name='gnn_edge_biases_%i' % layer_idx))

                cell_type = self.params['graph_rnn_cell'].lower()
                if cell_type == 'gru':
                    cell = tf.nn.rnn_cell.GRUCell(h_dim,
                                                  activation=activation_fun)
                elif cell_type == 'cudnncompatiblegrucell':
                    assert (activation_name == 'tanh')
                    import tensorflow.contrib.cudnn_rnn as cudnn_rnn
                    cell = cudnn_rnn.CudnnCompatibleGRUCell(h_dim)
                elif cell_type == 'rnn':
                    cell = tf.nn.rnn_cell.BasicRNNCell(
                        h_dim, activation=activation_fun)
                else:
                    raise Exception("Unknown RNN cell type '%s'." % cell_type)
                cell = tf.nn.rnn_cell.DropoutWrapper(
                    cell,
                    state_keep_prob=self.placeholders['graph_state_keep_prob'])
                self.gnn_weights.rnn_cells.append(cell)