def test_unsupervised(self): src_hops = [4, 5] dst_hops = [2, 6] neg = 2 src_g, src_dim = self.get_graph(src_hops) dst_g, dst_dim = self.get_graph(dst_hops) neg_g, neg_dim = self.get_graph(dst_hops, neg) layer_ui = EgoSAGELayer("heter_ui", input_dim=(src_dim, dst_dim), output_dim=12, agg_type="mean", com_type="concat") layer_ii = EgoSAGELayer("heter_ii", input_dim=dst_dim, output_dim=12, agg_type="mean", com_type="concat") layer_uii = EgoSAGELayer("heter_uii", input_dim=(12, 12), output_dim=8, agg_type="sum", com_type="concat") layer_iii = EgoSAGELayer("heter_iii", input_dim=(12, 12), output_dim=8, agg_type="sum", com_type="concat") layer_group_1 = EgoSAGELayerGroup([layer_ui, layer_ii]) layer_group_2 = EgoSAGELayerGroup([layer_uii]) src_model = EgoGraphSAGE( [layer_group_1, layer_group_2], bn_fn=None, active_fn=tf.nn.relu, droput=0.1) layer_group_3 = EgoSAGELayerGroup([layer_ii, layer_ii]) layer_group_4 = EgoSAGELayerGroup([layer_iii]) dst_model = EgoGraphSAGE( [layer_group_3, layer_group_4], bn_fn=None, active_fn=tf.nn.relu, droput=0.1) src_embeddings = src_model.forward(src_g) dst_embeddings = dst_model.forward(dst_g) neg_embeddings = dst_model.forward(neg_g) neg_embeddings = tf.reshape(neg_embeddings, [-1, neg, 8]) lp = UnsupervisedLinkPredictor(name="unlp", dims=[8, 4]) loss = lp.forward(src_embeddings, dst_embeddings, neg_embeddings) with tf.Session() as sess: sess.run(tf.local_variables_initializer()) sess.run(tf.global_variables_initializer()) loss = sess.run(loss) self.assertEqual(isinstance(loss, np.float32), True)
def test_supervised(self): src_hops = [4, 5] dst_hops = [2, 6] src_g, src_dim = self.get_graph(src_hops) dst_g, dst_dim = self.get_graph(dst_hops) layer_ui = EgoSAGELayer("heter_ui_super", input_dim=(src_dim, dst_dim), output_dim=12, agg_type="mean", com_type="concat") layer_ii = EgoSAGELayer("heter_ii_super", input_dim=dst_dim, output_dim=12, agg_type="mean", com_type="concat") layer_uii = EgoSAGELayer("heter_uii_super", input_dim=(12, 12), output_dim=8, agg_type="sum", com_type="concat") layer_iii = EgoSAGELayer("heter_iii_super", input_dim=(12, 12), output_dim=8, agg_type="sum", com_type="concat") layer_group_1 = EgoSAGELayerGroup([layer_ui, layer_ii]) layer_group_2 = EgoSAGELayerGroup([layer_uii]) src_model = EgoGraphSAGE( [layer_group_1, layer_group_2], bn_fn=None, active_fn=tf.nn.relu, droput=0.1) layer_group_3 = EgoSAGELayerGroup([layer_ii, layer_ii]) layer_group_4 = EgoSAGELayerGroup([layer_iii]) dst_model = EgoGraphSAGE( [layer_group_3, layer_group_4], bn_fn=None, active_fn=tf.nn.relu, droput=0.1) src_embeddings = src_model.forward(src_g) dst_embeddings = dst_model.forward(dst_g) super_lp = SupervisedLinkPredictor(name="superlp", dims=[8, 4]) logits, loss = super_lp.forward( src_embeddings, dst_embeddings, src_g.nodes.labels) with tf.Session() as sess: sess.run(tf.local_variables_initializer()) sess.run(tf.global_variables_initializer()) logits, loss = sess.run([logits, loss]) self.assertEqual(isinstance(loss, np.float32), True) self.assertListEqual([2], list(logits.shape)) # [batch_size]
def model_func(cls): src_hops = [4, 5] dst_hops = [2, 6] neg = 2 src_g, src_dim = cls.get_graph(src_hops) dst_g, dst_dim = cls.get_graph(dst_hops) neg_g, neg_dim = cls.get_graph(dst_hops, neg) layer_ui = EgoSAGELayer("heter_ui", input_dim=(src_dim, dst_dim), output_dim=12, agg_type="mean", com_type="concat") layer_ii = EgoSAGELayer("heter_ii", input_dim=dst_dim, output_dim=12, agg_type="mean", com_type="concat") layer_uii = EgoSAGELayer("heter_uii", input_dim=(12, 12), output_dim=8, agg_type="sum", com_type="concat") layer_iii = EgoSAGELayer("heter_iii", input_dim=(12, 12), output_dim=8, agg_type="sum", com_type="concat") layer_group_1 = EgoSAGELayerGroup([layer_ui, layer_ii]) layer_group_2 = EgoSAGELayerGroup([layer_uii]) src_model = EgoGraphSAGE([layer_group_1, layer_group_2], bn_fn=None, active_fn=tf.nn.relu, droput=0.1) layer_group_3 = EgoSAGELayerGroup([layer_ii, layer_ii]) layer_group_4 = EgoSAGELayerGroup([layer_iii]) dst_model = EgoGraphSAGE([layer_group_3, layer_group_4], bn_fn=None, active_fn=tf.nn.relu, droput=0.1) src_embeddings = src_model.forward(src_g) dst_embeddings = dst_model.forward(dst_g) neg_embeddings = dst_model.forward(neg_g) neg_embeddings = tf.reshape(neg_embeddings, [-1, neg, 8]) lp = UnsupervisedLinkPredictor(name="unlp", dims=[8, 4]) loss = lp.forward(src_embeddings, dst_embeddings, neg_embeddings) return src_embeddings, dst_embeddings, loss
def test_homogeneous_graph(self): # MAKE LAYERS dims = np.array([32, 8, 1]) layer1 = EgoSAGELayer("homo_1", input_dim=dims[0], output_dim=dims[1], agg_type="mean", com_type="add", parameter_share=True) layer2 = EgoSAGELayer("homo_2", input_dim=dims[1], output_dim=dims[2], agg_type="sum", com_type="add", parameter_share=True) layer_group_1 = EgoSAGELayerGroup([layer1, layer1]) layer_group_2 = EgoSAGELayerGroup([layer2]) # MAKE GRAPH DATA batch_size = 3 hops = np.array([5, 2]) # shape = [batch_size, input_dim] nodes = tf.convert_to_tensor( np.array(np.random.random([batch_size, dims[0]]), dtype=np.float32)) # shape = [batch_size * hop_1, input_dim] hop1 = tf.convert_to_tensor( np.array(np.random.random([batch_size * hops[0], dims[0]]), dtype=np.float32)) # shape = [batch_size * hop_1 * hop_2, input_dim] hop2 = tf.convert_to_tensor( np.array(np.random.random( [batch_size * hops[0] * hops[1], dims[0]]), dtype=np.float32)) # FORWARD inputs = [nodes, hop1, hop2] # h1 = [sage(nodes, hop1), sage(hop1, hop2)] h1 = layer_group_1.forward(inputs, hops) # h2 = [sage(h1[0], h1[1])] h2 = layer_group_2.forward(h1, hops[:-1]) self.assertEqual(len(h1), 2) self.assertEqual(len(h2), 1) with tf.Session() as sess: sess.run(tf.local_variables_initializer()) sess.run(tf.global_variables_initializer()) ret_1_0, ret_1_1, ret_2_0 = sess.run([h1[0], h1[1], h2[0]]) self.assertListEqual([batch_size, dims[1]], list(ret_1_0.shape)) self.assertListEqual([batch_size * hops[0], dims[1]], list(ret_1_1.shape)) self.assertListEqual([batch_size, dims[2]], list(ret_2_0.shape))
def __init__(self, dims, agg_type="mean", com_type="add", bn_fn=None, active_fn=None, dropout=None, **kwargs): """ In a homogeneous graph, all the nodes are of the same type, due to which different layers should share the model parameters. Args: `dims` is an integer list, in which two adjacent elements stand for the input and output dimensions of the corresponding layer. The length of `dims` is not less than 2. If len(`dims`) > 2, hidden layers will be constructed. e.g. `dims = [128, 256, 256, 64]`, means the input dimension is 128 and the output dimension is 64. Meanwhile, 2 hidden layers with dimension 256 will be added between the input and output layer. """ assert len(dims) > 2 layers = [] for i in range(len(dims) - 1): layer = EgoSAGELayer("homo_" + str(i), input_dim=dims[i], output_dim=dims[i + 1], agg_type=agg_type, com_type=com_type, parameter_share=True) # If the len(dims) = K, it means that (K-1) LEVEL layers will be added. At # each LEVEL, computation will be performed for each two adjacent hops, # such as (nodes, hop1), (hop1, hop2) ... . We have (K-1-i) such pairs at # LEVEL i. In a homogeneous graph, they will share model parameters. group = EgoSAGELayerGroup([layer] * (len(dims) - 1 - i)) layers.append(group) super(HomoEgoGraphSAGE, self).__init__(layers, bn_fn, active_fn, dropout)
def test_heterogeneous_graph(self): u_spec = FeatureSpec(10) for i in range(3): u_spec.append_dense() u_total_dim = 3 for i in range(7): dim = random.randint(8, 10) u_spec.append_sparse(20 + 10 * i, dim, False) u_total_dim += dim i_spec = FeatureSpec(19) for i in range(6): i_spec.append_dense() i_total_dim = 6 for i in range(13): dim = random.randint(8, 11) i_spec.append_sparse(30 + 10 * i, dim, False) i_total_dim += dim u_out_dim = 16 i_out_dim = 12 out_dim = 9 hops = [4, 5] # the centric vertices share the same spec with 2-hop neighbors # metapath: u--i--i schema = [("u_nodes", u_spec), ("nbr", i_spec), ("nbr", i_spec)] # [f_num, batch_size] = [3, 2] batch_floats = np.array([[1.0 * i, 2.0 * i] for i in range(3)]) batch_floats = tf.convert_to_tensor(batch_floats, dtype=tf.float32) # [i_num, batch_size] = [7, 2] batch_ints = np.array([[i, 2 * i] for i in range(7)]) batch_ints = tf.convert_to_tensor(batch_ints, dtype=tf.int64) vertices = Vertex(floats=batch_floats, ints=batch_ints) # [f_num, batch_size] = [6, 2 * 4] hop1_floats = np.array([[1.0 * i, 2.0 * i] * hops[0] for i in range(6)]) hop1_floats = tf.convert_to_tensor(hop1_floats, dtype=tf.float32) # [i_num, batch_size] = [13, 2 * 4] hop1_ints = np.array([[i, 2 * i] * hops[0] for i in range(13)]) hop1_ints = tf.convert_to_tensor(hop1_ints, dtype=tf.int64) neighbor_hop_1 = Vertex(floats=hop1_floats, ints=hop1_ints) # [f_num, batch_size] = [6, 2 * 4 * 5] hop2_floats = np.array([[1.0 * i, 2.0 * i] * hops[0] * hops[1] for i in range(6)]) hop2_floats = tf.convert_to_tensor(hop2_floats, dtype=tf.float32) # [i_num, batch_size] = [13, 2 * 4 * 5] hop2_ints = np.array([[i, 2 * i] * hops[0] * hops[1] for i in range(13)]) hop2_ints = tf.convert_to_tensor(hop2_ints, dtype=tf.int64) neighbor_hop_2 = Vertex(floats=hop2_floats, ints=hop2_ints) g = EgoGraph(vertices, [neighbor_hop_1, neighbor_hop_2], schema, hops) layer_ui = EgoSAGELayer("heter_uv", input_dim=(u_total_dim, i_total_dim), output_dim=u_out_dim, agg_type="mean", com_type="concat") layer_ii = EgoSAGELayer("heter_ii", input_dim=i_total_dim, output_dim=i_out_dim, agg_type="mean", com_type="concat") layer_uii = EgoSAGELayer("heter_uii", input_dim=(u_out_dim, i_out_dim), output_dim=out_dim, agg_type="sum", com_type="concat") layer_group_1 = EgoSAGELayerGroup([layer_ui, layer_ii]) layer_group_2 = EgoSAGELayerGroup([layer_uii]) model = EgoGraphSAGE([layer_group_1, layer_group_2], bn_fn=None, active_fn=tf.nn.relu, droput=0.1) embeddings = model.forward(g) with tf.Session() as sess: sess.run(tf.local_variables_initializer()) sess.run(tf.global_variables_initializer()) ret = sess.run(embeddings) self.assertListEqual([2, 9], list(ret.shape)) # [batch_size, output_dim]
def test_heterogeneous_graph(self): # MAKE LAYERS # user-vedio-item dims_0 = np.array([24, 32, 18]) # | / | / # | / | / dims_1 = np.array([16, 12]) # | / # | / dims_2 = np.array([1]) layer_uv = EgoSAGELayer("heter_uv", input_dim=(dims_0[0], dims_0[1]), output_dim=dims_1[0], agg_type="mean", com_type="concat") layer_vi = EgoSAGELayer("heter_vi", input_dim=(dims_0[1], dims_0[2]), output_dim=dims_1[1], agg_type="mean", com_type="concat") layer_uvi = EgoSAGELayer("heter_uvi", input_dim=(dims_1[0], dims_1[1]), output_dim=dims_2[0], agg_type="sum", com_type="concat") layer_group_1 = EgoSAGELayerGroup([layer_uv, layer_vi]) layer_group_2 = EgoSAGELayerGroup([layer_uvi]) # MAKE GRAPH DATA batch_size = 3 hops = np.array([5, 2]) # shape = [batch_size, input_dim] nodes = tf.convert_to_tensor( np.array(np.random.random([batch_size, dims_0[0]]), dtype=np.float32)) # shape = [batch_size * hop_1, input_dim] hop1 = tf.convert_to_tensor( np.array(np.random.random([batch_size * hops[0], dims_0[1]]), dtype=np.float32)) # shape = [batch_size * hop_1 * hop_2, input_dim] hop2 = tf.convert_to_tensor( np.array(np.random.random( [batch_size * hops[0] * hops[1], dims_0[2]]), dtype=np.float32)) # FORWARD inputs = [nodes, hop1, hop2] # h1 = [agg(nodes, hop1), agg(hop1, hop2)] h1 = layer_group_1.forward(inputs, hops) # h2 = [agg(h1[0], h1[1])] h2 = layer_group_2.forward(h1, hops[:-1]) self.assertEqual(len(h1), 2) self.assertEqual(len(h2), 1) with tf.Session() as sess: sess.run(tf.local_variables_initializer()) sess.run(tf.global_variables_initializer()) ret_1_0, ret_1_1, ret_2_0 = sess.run([h1[0], h1[1], h2[0]]) self.assertListEqual([batch_size, dims_1[0]], list(ret_1_0.shape)) self.assertListEqual([batch_size * hops[0], dims_1[1]], list(ret_1_1.shape)) self.assertListEqual([batch_size, dims_2[0]], list(ret_2_0.shape))