Beispiel #1
0
def pooling_matrices(A_list, coarsening_levels, pool):
    """
    Creates all the necessary matrices for decimation pooling and average
    pooling.
    :param A_list: a list of adjacency matrices
    :param coarsening_levels: a list of coarsening levels for pooling
    :param pool: pooling method to use (decim, graclus, nmf)
    :return:
        D_out: list of lists with decimation matrices for each graph
        A_out: list of Laplacians pyramids for each graph
        num_nodes_list: list with the number of nodes for each graph
        partition_list: list of lists, each list has N repeating integers where
        N is the size of each graph. Used as second argument for tf.segment_sum.
    """
    A_out = []
    D_out = []

    if pool == 'decim':
        for a in A_list:
            L = convolution.normalized_laplacian(a)
            graphs, indices = reduction(L,
                                        levels=max(coarsening_levels) + 1,
                                        mode='kron')
            graphs = [convolution.rescale_laplacian(g, lmax=2) for g in graphs]
            dm, gl = decimation_matrices(levels=coarsening_levels, L=graphs, indices=indices)
            D_out.append(dm)
            A_out.append(gl)
    elif pool == 'graclus':
        perm_list = []
        for a in A_list:
            a = sp.csr_matrix(a)  # pooling.coarsen wants sparse matrices
            graphs, perm = coarsen(a, levels=max(coarsening_levels) + 1)
            graphs = [graphs[i] for i in coarsening_levels]  # Keep only the right graphs
            graphs = [convolution.normalized_adjacency(g) for g in graphs]
            dm = graclus_pooling_matrices(graphs)
            D_out.append(dm)
            A_out.append(graphs)
            perm_list.append(perm)
    elif pool == 'nmf':
        for a in A_list:
            dm, gl = nmf_pooling(A=a, levels=coarsening_levels)
            gl = [convolution.normalized_adjacency(g) for g in gl]
            D_out.append(dm)
            A_out.append(gl)
    else:
        raise ValueError("pool must be 'decim', 'graclus' or 'nmf'")

    if pool == 'graclus':
        return A_out, D_out, perm_list
    else:
        return A_out, D_out
Beispiel #2
0
def test_graph_ops():
    A = np.ones((N, N))
    convert_to_sparse = [[True]]

    expected_output = convolution.normalized_adjacency(A)
    _check_op(ops.normalize_A, [A], expected_output, convert_to_sparse)

    expected_output = convolution.degree_matrix(A).sum(-1)
    _check_op(ops.degrees, [A], expected_output, convert_to_sparse)

    expected_output = convolution.degree_matrix(A)
    _check_op(ops.degree_matrix, [A], expected_output, convert_to_sparse)
Beispiel #3
0
def GNN(A, X):
    # 使用graph_hi构造图邻接矩阵A
    np.random.seed(0)  # for reproducibility
    ITER = 10000
    # Parameters
    P = OrderedDict([
        ('es_patience', ITER),
        ('dataset', ['cora'
                     ]),  # 'cora', 'citeseer', 'pubmed', 'cloud', or 'synth'
        ('H_', [None]),
        ('n_channels', [16]),
        ('learning_rate', [5e-4])
    ])
    ############################################################################
    # LOAD DATASET
    ############################################################################

    A = np.maximum(A, A.T)
    A = sp.csr_matrix(A, dtype=np.float32)

    X = X.todense()
    n_feat = X.shape[-1]

    ############################################################################
    # GNN MODEL
    ############################################################################
    X_in = Input(
        tensor=tf.placeholder(tf.float32, shape=(None, n_feat), name='X_in'))
    A_in = Input(tensor=tf.sparse_placeholder(tf.float32, shape=(None, None)),
                 name='A_in',
                 sparse=True)
    # S_in = Input(tensor=tf.placeholder(tf.int32, shape=(None,), name='segment_ids_in'))

    A_norm = normalized_adjacency(A)
    X_1 = GCSConv(P['n_channels'],
                  kernel_initializer='he_normal',
                  activation='elu')([X_in, A_in])

    pool1, adj1, C = MinCutPool(k=n_classes,
                                h=P['H_'],
                                activation='elu',
                                return_mask=True)([X_1, A_in])

    model = Model([X_in, A_in], [pool1, adj1, C])
    model.compile('adam', None)

    ############################################################################
    # TRAINING
    ############################################################################
    # Setup
    sess = K.get_session()
    loss = model.total_loss
    opt = tf.train.AdamOptimizer(learning_rate=P['learning_rate'])
    train_step = opt.minimize(loss)

    # Initialize all variables
    init_op = tf.global_variables_initializer()
    sess.run(init_op)

    # Fit layer
    tr_feed_dict = {X_in: X, A_in: sp_matrix_to_sp_tensor_value(A_norm)}

    best_loss = np.inf
    patience = P['es_patience']
    tol = 1e-5
    for _ in tqdm(range(ITER)):
        outs = sess.run([train_step, model.losses[0], model.losses[1], C],
                        feed_dict=tr_feed_dict)
        # c = np.argmax(outs[3], axis=-1)
        if outs[1] + outs[2] + tol < best_loss:
            best_loss = outs[1] + outs[2]
            patience = P['es_patience']
        else:
            patience -= 1
            if patience == 0:
                break

    ############################################################################
    # RESULTS
    ############################################################################
    C_ = sess.run([C], feed_dict=tr_feed_dict)[0]
    c = np.argmax(C_, axis=-1)
    K.clear_session()
    return c
Beispiel #4
0
        _, S_pool = model(inputs, training=True)
        loss = sum(model.losses)
    gradients = tape.gradient(loss, model.trainable_variables)
    opt.apply_gradients(zip(gradients, model.trainable_variables))
    return model.losses[0], model.losses[1], S_pool


np.random.seed(1)
epochs = 5000  # Training iterations
lr = 5e-4  # Learning rate

################################################################################
# LOAD DATASET
################################################################################
A, X, y, _, _, _ = citation.load_data('cora')
A_norm = normalized_adjacency(A)
X = X.todense()
F = X.shape[-1]
y = np.argmax(y, axis=-1)
n_clusters = y.max() + 1

################################################################################
# MODEL
################################################################################
X_in = Input(shape=(F, ), name='X_in')
A_in = Input(shape=(None, ), name='A_in', sparse=True)

X_1 = GraphConvSkip(16, activation='elu')([X_in, A_in])
X_1, A_1, S = MinCutPool(n_clusters, return_mask=True)([X_1, A_in])

model = Model([X_in, A_in], [X_1, S])
Beispiel #5
0
                 "rb"))

    else:
        print('Computing coarsened Laplacians')
        A_train, X_train, D_train = preprocess(
            A_train,
            X_train,
            coarsening_levels=P['coarse_level'],
            pool=P['pool'])
        A_test, X_test, D_test = preprocess(
            A_test,
            X_test,
            coarsening_levels=P['coarse_level'],
            pool=P['pool'])

        L_train = [[normalized_adjacency(a_).astype(np.float32) for a_ in A]
                   for A in A_train]
        L_test = [[normalized_adjacency(a_).astype(np.float32) for a_ in A]
                  for A in A_test]

        # save
        f = open('data/' + P['dataset_ID'] + "_pool_" + P['pool'] + ".pkl",
                 "wb")
        pickle.dump([
            L_train, L_test, D_train, D_test, X_train, X_test, y_train, y_test
        ], f)
        f.close()
else:
    L_train = [normalized_adjacency(A_) for A_ in A_train]
    L_test = [normalized_adjacency(A_) for A_ in A_test]
    print('Downloading ' + dataset_name + ' from ' + data_url)
    req = requests.get(data_url + dataset_name)
    with open(dataset_name, 'wb') as out_file:
        out_file.write(req.content)

# Load data
loaded = np.load(dataset_name, allow_pickle=True)
X_train, A_train, y_train = loaded['tr_feat'], list(
    loaded['tr_adj']), loaded['tr_class']
X_test, A_test, y_test = loaded['te_feat'], list(
    loaded['te_adj']), loaded['te_class']
X_val, A_val, y_val = loaded['val_feat'], list(
    loaded['val_adj']), loaded['val_class']

# Preprocessing adjacency matrices for convolution
A_train = [normalized_adjacency(a) for a in A_train]
A_val = [normalized_adjacency(a) for a in A_val]
A_test = [normalized_adjacency(a) for a in A_test]

# Parameters
F = X_train[0].shape[-1]  # Dimension of node features
n_out = y_train[0].shape[-1]  # Dimension of the target
average_N = np.ceil(np.mean([a.shape[-1] for a in A_train
                             ]))  # Average number of nodes in dataset

################################################################################
# BUILD MODEL
################################################################################
X_in = Input(tensor=tf.placeholder(tf.float32, shape=(None, F), name='X_in'))
A_in = Input(tensor=tf.sparse_placeholder(tf.float32, shape=(None, None)),
             sparse=True)
Beispiel #7
0
        loss = sum(model.losses)
    gradients = tape.gradient(loss, model.trainable_variables)
    opt.apply_gradients(zip(gradients, model.trainable_variables))
    return model.losses[0], model.losses[1], S_pool


np.random.seed(1)
epochs = 5000  # Training iterations
lr = 5e-4  # Learning rate

################################################################################
# LOAD DATASET
################################################################################
dataset = Cora()
adj, x, y = dataset[0].a, dataset[0].x, dataset[0].y
a_norm = normalized_adjacency(adj)
a_norm = sp_matrix_to_sp_tensor(a_norm)
F = dataset.n_node_features
y = np.argmax(y, axis=-1)
n_clusters = y.max() + 1

################################################################################
# MODEL
################################################################################
x_in = Input(shape=(F, ), name="X_in")
a_in = Input(shape=(None, ), name="A_in", sparse=True)

x_1 = GCSConv(16, activation="elu")([x_in, a_in])
x_1, a_1, s_1 = MinCutPool(n_clusters, return_selection=True)([x_1, a_in])

model = Model([x_in, a_in], [x_1, s_1])
            X_test, A_test, y_test = loaded['te_feat'], list(
                loaded['te_adj']), loaded['te_class']
            X_val, A_val, y_val = loaded['val_feat'], list(
                loaded['val_adj']), loaded['val_class']
        else:
            raise ValueError

        # Parameters
        F = X_train[0].shape[-1]  # Dimension of node features
        n_out = y_train[0].shape[-1]  # Dimension of the target
        average_N = np.ceil(np.mean([a.shape[-1] for a in A_train
                                     ]))  # Average number of nodes in dataset

        # Preprocessing adjacency matrices for convolution
        if P['GNN_type'] == 'GCS' or P['GNN_type'] == 'ARMA':
            A_train = [normalized_adjacency(a) for a in A_train]
            A_val = [normalized_adjacency(a) for a in A_val]
            A_test = [normalized_adjacency(a) for a in A_test]
        elif P['GNN_type'] == 'GCN':
            A_train = [
                normalized_adjacency(a + sp.eye(a.shape[0])) for a in A_train
            ]
            A_val = [
                normalized_adjacency(a + sp.eye(a.shape[0])) for a in A_val
            ]
            A_test = [
                normalized_adjacency(a + sp.eye(a.shape[0])) for a in A_test
            ]
        else:
            raise ValueError('Unknown GNN type: {}'.format(P['GNN_type']))
Beispiel #9
0
X_val_A, y_val_A = load('val_ma.npy',
                        allow_pickle=True), load('val_may.npy',
                                                 allow_pickle=True)

X_train_B, A_train_B, y_train_B = load('tr_feat.npy', allow_pickle=True), list(
    load('tr_adj.npy', allow_pickle=True)), load('tr_class.npy',
                                                 allow_pickle=True)
X_test_B, A_test_B, y_test_B = load('te_feat.npy', allow_pickle=True), list(
    load('te_adj.npy', allow_pickle=True)), load('te_class.npy',
                                                 allow_pickle=True)
X_val_B, A_val_B, y_val_B = load('val_feat.npy', allow_pickle=True), list(
    load('val_adj.npy', allow_pickle=True)), load('val_class.npy',
                                                  allow_pickle=True)

# Preprocessing adjacency matrices for convolution
A_train_B = [normalized_adjacency(a) for a in A_train_B]
A_val_B = [normalized_adjacency(a) for a in A_val_B]
A_test_B = [normalized_adjacency(a) for a in A_test_B]

# Load pre-trained models
model_A = load_model('model_A.h5')
model_B = load_model('model_B.h5',
                     custom_objects={
                         'GraphConvSkip': GraphConvSkip,
                         'MinCutPool': MinCutPool,
                         'GlobalAvgPool': GlobalAvgPool
                     })

# Get the output before last layer of both models
model_A = Model(inputs=model_A.inputs, outputs=model_A.layers[-2].output)
model_B = Model(inputs=model_B.inputs, outputs=model_B.layers[-2].output)
Beispiel #10
0
from spektral.utils.convolution import normalized_adjacency

np.random.seed(1)

iterations = 5000  # Training iterations
gnn_channels = 16  # Units in the GNN layer
mlp_channels = None  # Units in the MLP of MinCutPool Layer (if None, the MLP has no hidden layers)
gnn_activ = 'elu'  # Activation for the GNN layer
mlp_activ = None  # Activation for the hidden layers of MinCutPool
lr = 5e-4  # Learning rate

################################################################################
# LOAD DATASET
################################################################################
A, X, y, _, _, _ = citation.load_data('cora')
A_norm = normalized_adjacency(A)  # Normalize adjacency matrix
X = X.todense()
n_feat = X.shape[-1]
y = np.argmax(y, axis=-1)
n_clust = y.max() + 1

################################################################################
# MODEL
################################################################################
X_in = Input(
    tensor=tf.placeholder(tf.float32, shape=(None, n_feat), name='X_in'))
A_in = Input(tensor=tf.sparse_placeholder(tf.float32, shape=(None, None)),
             name='A_in',
             sparse=True)

X_1 = GraphConvSkip(gnn_channels,