def test_RGCN_apply_dense_directed(): G, features = create_graph_features(is_directed=True) As = get_As(G) As = [np.expand_dims(A.todense(), 0) for A in As] generator = RelationalFullBatchNodeGenerator(G, sparse=False) rgcnModel = RGCN([2], generator, num_bases=10, activations=["relu"], dropout=0.5) x_in, x_out = rgcnModel.in_out_tensors() model = keras.Model(inputs=x_in, outputs=x_out) # Check fit method out_indices = np.array([[0, 1]], dtype="int32") preds_1 = model.predict([features[None, :, :], out_indices] + As) assert preds_1.shape == (1, 2, 2) # Check fit method preds_2 = model.predict(generator.flow(["a", "b"])) assert preds_2.shape == (1, 2, 2) assert preds_1 == pytest.approx(preds_2)
def generator_flow(self, G, node_ids, node_targets, sparse=False): generator = RelationalFullBatchNodeGenerator(G, sparse=sparse) n_nodes = len(G.nodes()) gen = generator.flow(node_ids, node_targets) if sparse: [X, tind, *As], y = gen[0] As_indices = As[:self.num_relationships] As_values = As[self.num_relationships:] As_sparse = [ sps.coo_matrix( (A_val[0], (A_ind[0, :, 0], A_ind[0, :, 1])), shape=(n_nodes, n_nodes), ) for A_ind, A_val in zip(As_indices, As_values) ] As_dense = [A.toarray() for A in As_sparse] else: [X, tind, *As], y = gen[0] As_dense = As assert np.allclose(X, gen.features) # X should be equal to gen.features assert tind.shape[1] == len(node_ids) if node_targets is not None: assert np.allclose(y, node_targets) return As_dense, tind, y
def test_RGCN_apply_sparse_directed(): G, features = create_graph_features(is_directed=True) As = get_As(G) As = [A.tocoo() for A in As] A_indices = [ np.expand_dims(np.hstack((A.row[:, None], A.col[:, None])), 0) for A in As ] A_values = [np.expand_dims(A.data, 0) for A in As] generator = RelationalFullBatchNodeGenerator(G, sparse=True) rgcnModel = RGCN([2], generator, num_bases=10, activations=["relu"], dropout=0.5) x_in, x_out = rgcnModel.build() model = keras.Model(inputs=x_in, outputs=x_out) # Check fit method out_indices = np.array([[0, 1]], dtype="int32") preds_1 = model.predict([features[None, :, :], out_indices] + A_indices + A_values) assert preds_1.shape == (1, 2, 2) # Check fit_generator method preds_2 = model.predict_generator(generator.flow(["a", "b"])) assert preds_2.shape == (1, 2, 2) assert preds_1 == pytest.approx(preds_2)
def test_generator_flow_targets_as_list(self): generator = RelationalFullBatchNodeGenerator(self.G) node_ids = list(self.G.nodes())[:3] node_targets = [1] * len(node_ids) gen = generator.flow(node_ids, node_targets) inputs, y = gen[0] assert y.shape == (1, 3) assert np.sum(y) == 3
def test_generator_constructor(self): generator = RelationalFullBatchNodeGenerator(self.G) assert len(generator.As) == self.num_relationships assert all((A.shape == (self.N, self.N)) for A in generator.As) assert generator.features.shape == (self.N, self.n_feat)
def test_fullbatch_generator_transform(self): G, _ = create_graph_features() def func(features, A, **kwargs): return features, A.dot(A) generator = RelationalFullBatchNodeGenerator(G, "test", transform=func) assert generator.name == "test" As = [] edge_types = sorted(set(e[-1] for e in G.edges(include_edge_type=True))) node_list = list(G.nodes()) node_index = dict(zip(node_list, range(len(node_list)))) for edge_type in edge_types: col_index = [ node_index[n1] for n1, n2, etype in G.edges(include_edge_type=True) if etype == edge_type ] row_index = [ node_index[n2] for n1, n2, etype in G.edges(include_edge_type=True) if etype == edge_type ] data = np.ones(len(col_index), np.float64) A = sps.coo_matrix((data, (row_index, col_index)), shape=(len(node_list), len(node_list))) As.append(A) assert all( np.array_equal(A_1.dot(A_1).todense(), A_2.todense()) for A_1, A_2 in zip(As, generator.As))
def test_fullbatch_generator_init_3(self): G, _ = create_graph_features() func = "Not callable" with pytest.raises(TypeError): generator = RelationalFullBatchNodeGenerator(G, "test", transform=func)
def test_RGCN_init(): G, features = create_graph_features() generator = RelationalFullBatchNodeGenerator(G) rgcnModel = RGCN([2], generator, num_bases=10, activations=["relu"], dropout=0.5) assert rgcnModel.layer_sizes == [2] assert rgcnModel.activations == ["relu"] assert rgcnModel.dropout == 0.5 assert rgcnModel.num_bases == 10
def test_weighted(self): G, _ = create_graph_features(edge_weights=True) generator = RelationalFullBatchNodeGenerator(G, weighted=True, transform=lambda f, A: (f, A)) np.testing.assert_array_equal( generator.As[0].todense(), [[0, 2.0, 0], [2.0, 0, 0.5], [0, 0.5, 0]]) np.testing.assert_array_equal( generator.As[1].todense(), [[0, 0.0, 1.0], [0.0, 0, 0.0], [1.0, 0.0, 0]])
def test_kernel_and_bias_defaults(): graph, _ = create_graph_features() generator = RelationalFullBatchNodeGenerator(graph, sparse=False) rgcn = RGCN([2, 2], generator, num_bases=10) for layer in rgcn._layers: if isinstance(layer, RelationalGraphConvolution): assert isinstance(layer.kernel_initializer, tf.initializers.GlorotUniform) assert isinstance(layer.bias_initializer, tf.initializers.Zeros) assert layer.kernel_regularizer is None assert layer.bias_regularizer is None assert layer.kernel_constraint is None assert layer.bias_constraint is None
def test_generator_constructor_wrong_G_type(self): with pytest.raises(TypeError): generator = RelationalFullBatchNodeGenerator(self.G.to_networkx())
def test_fullbatch_generator_init_1(self): G, feats = create_graph_features() generator = RelationalFullBatchNodeGenerator(G, name="test") assert generator.name == "test" assert np.array_equal(feats, generator.features)
def test_generator_flow_targets_not_iterator(self): generator = RelationalFullBatchNodeGenerator(self.G) node_ids = list(self.G.nodes())[:3] node_targets = 1 with pytest.raises(TypeError): generator.flow(node_ids, node_targets)
def test_fullbatch_generator_init_heterogeneous_nodes(self): G = example_hin_1(feature_sizes={}) with pytest.raises(ValueError, match="G: expected one node type, found 'A', 'B'"): RelationalFullBatchNodeGenerator(G)
def test_RGCN_save_load(tmpdir, num_bases, sparse): graph, _ = create_graph_features() generator = RelationalFullBatchNodeGenerator(graph, sparse=sparse) rgcn = RGCN([2, 2], generator, num_bases=num_bases) test_utils.model_save_load(tmpdir, rgcn)