def test_graphsage_apply_1(): gs = GraphSAGE( layer_sizes=[2, 2, 2], n_samples=[2, 2, 2], bias=False, input_dim=2, multiplicity=1, normalize=None, kernel_initializer="ones", ) inp = [keras.Input(shape=(i, 2)) for i in [1, 2, 4, 8]] out = gs(inp) model = keras.Model(inputs=inp, outputs=out) x = [ np.array([[[1, 1]]]), np.array([[[2, 2], [2, 2]]]), np.array([[[3, 3], [3, 3], [3, 3], [3, 3]]]), np.array([[[4, 4], [4, 4], [4, 4], [4, 4], [5, 5], [5, 5], [5, 5], [5, 5]]]), ] expected = np.array([[16, 25]]) actual = model.predict(x) assert expected == pytest.approx(actual) # Use the node model: xinp, xout = gs.build() model2 = keras.Model(inputs=xinp, outputs=xout) assert pytest.approx(expected) == model2.predict(x)
def test_graphsage_passing_regularisers(): with pytest.raises(ValueError): GraphSAGE(layer_sizes=[4], n_samples=[2], input_dim=2, kernel_initializer="fred") GraphSAGE(layer_sizes=[4], n_samples=[2], input_dim=2, kernel_initializer="ones") GraphSAGE( layer_sizes=[4], n_samples=[2], input_dim=2, kernel_initializer=initializers.ones(), ) GraphSAGE( layer_sizes=[4], n_samples=[2], input_dim=2, kernel_regularizer=regularizers.l2(0.01), ) with pytest.raises(ValueError): GraphSAGE(layer_sizes=[4], n_samples=[2], input_dim=2, kernel_regularizer="wilma")
def test_graphsage_constructor_passing_aggregator(): gs = GraphSAGE(layer_sizes=[4], n_samples=[2], input_dim=2, aggregator=MeanAggregator) assert gs.dims == [2, 4] assert gs.n_samples == [2] assert gs.max_hops == 1 assert gs.bias assert len(gs._aggs) == 1 with pytest.raises(TypeError): GraphSAGE(layer_sizes=[4], n_samples=[2], input_dim=2, aggregator=1)
def test_graphsage_serialize(): gs = GraphSAGE( layer_sizes=[4], n_samples=[2], bias=False, input_dim=2, multiplicity=1, normalize=None, ) inp1 = keras.Input(shape=(1, 2)) inp2 = keras.Input(shape=(2, 2)) out = gs([inp1, inp2]) model = keras.Model(inputs=[inp1, inp2], outputs=out) # Save model model_json = model.to_json() # Set all weights to one model_weights = [np.ones_like(w) for w in model.get_weights()] # Load model from json & set all weights model2 = keras.models.model_from_json( model_json, custom_objects={"MeanAggregator": MeanAggregator}) model2.set_weights(model_weights) # Test loaded model x1 = np.array([[[1, 1]]]) x2 = np.array([[[2, 2], [3, 3]]]) expected = np.array([[2, 2, 5, 5]]) actual = model2.predict([x1, x2]) assert expected == pytest.approx(actual)
def gs_nai_model(num_samples, generator, targets, optimizer, bias, dropout, normalize): layer_sizes = [50] * len(num_samples) graphsage = GraphSAGE( layer_sizes=layer_sizes, generator=generator, bias=bias, dropout=dropout, normalize=normalize, ) # Build the model and expose input and output sockets of graphsage, for node pair inputs: x_inp, x_out = graphsage.build() pred = tf.keras.layers.Dense(units=targets.shape[1], activation="softmax")(x_out) model = tf.keras.Model(inputs=x_inp, outputs=pred) model.compile(optimizer=optimizer, loss=tf.keras.losses.categorical_crossentropy) return model
def test_kernel_and_bias_defaults(): gs = GraphSAGE(layer_sizes=[4, 4], n_samples=[2, 2], input_dim=2, multiplicity=1) for layer in gs._aggs: 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 unsup_gs_model(num_samples, generator, optimizer, bias, dropout, normalize): layer_sizes = [50] * len(num_samples) graphsage = GraphSAGE( layer_sizes=layer_sizes, generator=generator, bias=bias, dropout=dropout, normalize=normalize, ) # Build the model and expose input and output sockets of graphsage, for node pair inputs: x_inp, x_out = graphsage.build() prediction = link_classification( output_dim=1, output_act="sigmoid", edge_embedding_method="ip" )(x_out) model = tf.keras.Model(inputs=x_inp, outputs=prediction) model.compile(optimizer=optimizer, loss=tf.keras.losses.binary_crossentropy) return model
def test_graphsage_constructor_1(): gs = GraphSAGE(layer_sizes=[4, 6, 8], n_samples=[2, 4, 6], input_dim=2, bias=True, dropout=0.5) assert gs.dims == [2, 4, 6, 8] assert gs.n_samples == [2, 4, 6] assert gs.max_hops == 3 assert gs.bias assert len(gs._aggs) == 3
def test_graphsage_apply(): gs = GraphSAGE( layer_sizes=[4], n_samples=[2], bias=False, input_dim=2, normalize=None, kernel_initializer="ones", ) inp1 = keras.Input(shape=(1, 2)) inp2 = keras.Input(shape=(2, 2)) out = gs([inp1, inp2]) model = keras.Model(inputs=[inp1, inp2], outputs=out)
def test_graphsage_passing_activations(): gs = GraphSAGE(layer_sizes=[4], n_samples=[2], input_dim=2, multiplicity=1) assert gs.activations == ["linear"] gs = GraphSAGE(layer_sizes=[4, 4], n_samples=[2, 2], input_dim=2, multiplicity=1) assert gs.activations == ["relu", "linear"] gs = GraphSAGE(layer_sizes=[4, 4, 4], n_samples=[2, 2, 2], input_dim=2, multiplicity=1) assert gs.activations == ["relu", "relu", "linear"] with pytest.raises(ValueError): GraphSAGE( layer_sizes=[4, 4, 4], n_samples=[2, 2, 2], input_dim=2, multiplicity=1, activations=["relu"], ) with pytest.raises(ValueError): GraphSAGE( layer_sizes=[4, 4, 4], n_samples=[2, 2, 2], input_dim=2, multiplicity=1, activations=["relu"] * 2, ) with pytest.raises(ValueError): GraphSAGE( layer_sizes=[4, 4, 4], n_samples=[2, 2, 2], input_dim=2, multiplicity=1, activations=["fred", "wilma", "barney"], ) gs = GraphSAGE( layer_sizes=[4, 4, 4], n_samples=[2, 2, 2], input_dim=2, multiplicity=1, activations=["linear"] * 3, ) assert gs.activations == ["linear"] * 3
def test_graphsage_constructor(): gs = GraphSAGE(layer_sizes=[4], n_samples=[2], input_dim=2, normalize="l2") assert gs.dims == [2, 4] assert gs.n_samples == [2] assert gs.max_hops == 1 assert gs.bias assert len(gs._aggs) == 1 # Check incorrect normalization flag with pytest.raises(ValueError): GraphSAGE(layer_sizes=[4], n_samples=[2], input_dim=2, normalize=lambda x: x) with pytest.raises(ValueError): GraphSAGE(layer_sizes=[4], n_samples=[2], input_dim=2, normalize="unknown") # Check requirement for generator or n_samples with pytest.raises(ValueError): GraphSAGE(layer_sizes=[4]) # Construction from generator G = example_graph_1(feature_size=3) gen = GraphSAGENodeGenerator(G, batch_size=2, num_samples=[2, 2]).flow([1, 2]) gs = GraphSAGE(layer_sizes=[4, 8], generator=gen, bias=True) assert gs.dims == [3, 4, 8] assert gs.n_samples == [2, 2] assert gs.max_hops == 2 assert gs.bias assert len(gs._aggs) == 2
def test_graphsage_zero_neighbours(): gs = GraphSAGE( layer_sizes=[2, 2], n_samples=[0, 0], bias=False, input_dim=2, normalize="none", kernel_initializer="ones", ) inp = [keras.Input(shape=(i, 2)) for i in [1, 0, 0]] out = gs(inp) model = keras.Model(inputs=inp, outputs=out) x = [np.array([[[1.5, 1]]]), np.zeros((1, 0, 2)), np.zeros((1, 0, 2))] actual = model.predict(x) expected = np.array([[5, 5]]) assert actual == pytest.approx(expected)
def test_graphsage_constructor(): gs = GraphSAGE(layer_sizes=[4], n_samples=[2], input_dim=2, normalize="l2", multiplicity=1) assert gs.dims == [2, 4] assert gs.n_samples == [2] assert gs.max_hops == 1 assert gs.bias assert len(gs._aggs) == 1 # Check incorrect normalization flag with pytest.raises(ValueError): GraphSAGE( layer_sizes=[4], n_samples=[2], input_dim=2, normalize=lambda x: x, multiplicity=1, ) with pytest.raises(ValueError): GraphSAGE( layer_sizes=[4], n_samples=[2], input_dim=2, normalize="unknown", multiplicity=1, ) # Check requirement for generator or n_samples with pytest.raises(KeyError): GraphSAGE(layer_sizes=[4]) # Construction from generator G = example_graph(feature_size=3) gen = GraphSAGENodeGenerator(G, batch_size=2, num_samples=[2, 2]) gs = GraphSAGE(layer_sizes=[4, 8], generator=gen, bias=True) # The GraphSAGE should no longer accept a Sequence t_gen = gen.flow([1, 2]) with pytest.raises(TypeError): gs = GraphSAGE(layer_sizes=[4, 8], generator=t_gen, bias=True) assert gs.dims == [3, 4, 8] assert gs.n_samples == [2, 2] assert gs.max_hops == 2 assert gs.bias assert len(gs._aggs) == 2
def test_graphsage_save_load(tmpdir): gs = GraphSAGE(layer_sizes=[4, 4], n_samples=[2, 2], input_dim=2, multiplicity=1) test_utils.model_save_load(tmpdir, gs)