示例#1
0
def gcn_chebyshev(v_size, F, N, n_classes, support):
    x_in = Input(shape=(F, ))
    g = [Input((N, ), sparse=True) for i in range(support)]

    # transformer
    embedding = Embedding(v_size, emb_dim)
    e = embedding(x_in)
    h = Attention(8, 16)([e, e, e])
    h = GlobalAveragePooling1D()(h)

    # gcn, support=1
    out = GraphConvolution(n_classes, support, activation='sigmoid')([h] + g)

    model = Model(inputs=[x_in] + g, outputs=out)
    model.compile(loss='binary_crossentropy', optimizer='adam')

    return model
示例#2
0
def gcn(N, ):
    x_in = Input(shape=(maxlen, embed_dim))
    a_in = Input(shape=(maxlen, embed_dim))
    g = Input((batch_size, ), sparse=True)

    x = x_in
    a = a_in

    h = Attention(8, 16)([a, x, x])
    h = GlobalAveragePooling1D()(h)

    # gcn, support=1
    h = GraphConvolution(h_dim, 1, activation='relu')([h, g])
    #h = Dropout(0.2)(h)
    #out = GraphConvolution(3, 1, activation='softmax')([h,g])
    out = Dense(3, activation='softmax')(h)

    model = Model(inputs=[x_in, a_in, g], outputs=out)
    model.compile(loss='categorical_crossentropy', optimizer='adam')

    return model
示例#3
0
    G = [
        Input(shape=(None, None), batch_shape=(None, None), sparse=True)
        for _ in range(support)
    ]

else:
    raise Exception('Invalid filter type.')

X_in = Input(shape=(X.shape[1], ))

# Define model architecture
# NOTE: We pass arguments for graph convolutional layers as a list of tensors.
# This is somewhat hacky, more elegant options would require rewriting the Layer base class.
H = Dropout(0.5)(X_in)
H = GraphConvolution(16,
                     support,
                     activation='relu',
                     kernel_regularizer=l2(5e-4))([H] + G)
H = Dropout(0.5)(H)
Y = GraphConvolution(y.shape[1], support, activation='softmax')([H] + G)

# Compile model
model = Model(inputs=[X_in] + G, outputs=Y)
model.compile(loss='categorical_crossentropy', optimizer=Adam(lr=0.01))

# Helper variables for main training loop
wait = 0
preds = None
best_val_loss = 99999

# Fit
for epoch in range(1, NB_EPOCH + 1):
示例#4
0
def main():
    # Parse command line arguments
    arg_parser = argparse.ArgumentParser()
    arg_parser.add_argument('--dataset',
                            default=DATASET,
                            choices=['cora'],
                            help='the data set to load')
    arg_parser.add_argument('--filter',
                            default=FILTER,
                            choices=['localpool', 'chebyshev'],
                            help='the filter to use')
    arg_parser.add_argument('--no-norm-symmetry',
                            dest='sym_norm',
                            action='store_false',
                            help='disable symmetric normalization')
    arg_parser.add_argument('-e',
                            '--epochs',
                            type=int,
                            default=NB_EPOCH,
                            help='the number of epochs to train for')
    arg_parser.add_argument('--patience',
                            type=int,
                            default=PATIENCE,
                            help='the patience for early-stopping')
    arg_parser.add_argument('--max-degree',
                            type=int,
                            default=MAX_DEGREE,
                            help='maximum polynomial degree')
    args = arg_parser.parse_args()

    # Get data
    X, A, y = load_data(dataset=args.dataset)
    y_train, y_val, y_test, train_mask, val_mask, test_mask = get_splits(y)

    # Normalize X
    X = np.diag(1 / np.array(X.sum(1)).flatten()).dot(X)

    if FILTER == 'localpool':
        # Local pooling filters
        # (see 'renormalization trick' in Kipf & Welling, arXiv 2016)
        print('Using local pooling filters...')
        A_ = preprocess_adj(A, args.sym_norm)
        support = 1
        graph = [X, A_]
        G = [Input(shape=tuple(A_.shape[1:]), sparse=True)]
    elif FILTER == 'chebyshev':
        # Chebyshev polynomial basis filters (Defferard et al., NIPS 2016)
        print('Using Chebyshev polynomial basis filters...')
        L = normalized_laplacian(A, args.sym_norm)
        L_scaled = rescale_laplacian(L)
        T_k = chebyshev_polynomial(L_scaled, args.max_degree)
        support = args.max_degree + 1
        graph = [X] + T_k
        G = [
            Input(shape=tuple(T_k.shape[i + 1]), sparse=True)
            for i in range(support)
        ]

    else:
        raise ValueError('Invalid filter type.')

    X_in = Input(shape=(X.shape[1], ))

    # Define model architecture
    H = Dropout(0.5)(X_in)
    H = GraphConvolution(16,
                         support,
                         activation='relu',
                         W_regularizer=l2(5e-4))([H] + G)
    H = Dropout(0.5)(H)
    Y = GraphConvolution(y.shape[1], support, activation='softmax')([H] + G)

    # Compile model
    model = Model(inputs=[X_in] + G, outputs=Y)
    model.compile(loss='categorical_crossentropy',
                  optimizer=Adam(lr=0.01),
                  metrics=[accuracy_metric])

    model.fit(graph,
              y_train,
              sample_weight=train_mask,
              validation_data=(graph, y_val, val_mask),
              batch_size=A.shape[0],
              epochs=args.epochs,
              shuffle=False,
              verbose=1)

    # Testing
    test_loss, test_acc = model.evaluate(graph,
                                         y_test,
                                         sample_weight=test_mask,
                                         batch_size=A.shape[0])
    print("Test set results:", "loss= {}".format(test_loss),
          "accuracy= {}".format(test_acc))
示例#5
0
def tkipf_training(X_, A_, y, y_train, y_val, y_test, idx_train, idx_val, idx_test, train_mask):
    # Define model architecture
    # NOTE: We pass arguments for graph convolutional layers as a list of tensors.
    # This is somewhat hacky, more elegant options would require rewriting the Layer base class.

    # Choosing filter
    if FILTER == 'localpool':
        """ Local pooling filters (see 'renormalization trick' in Kipf & Welling, arXiv 2016) """
        if args.log:
            print('\tUsing local pooling filters...')
        support = 1
        graph = [X_, A_]
        G = [Input(shape=(None, None), batch_shape=(None, None), sparse=True)]
    elif FILTER == 'chebyshev':
        """ Chebyshev polynomial basis filters (Defferard et al., NIPS 2016)  """
        #ATTENZIONE A globale e non preprocessata
        print('Using Chebyshev polynomial basis filters...')
        L = normalized_laplacian(A, SYM_NORM)
        L_scaled = rescale_laplacian(L)
        T_k = chebyshev_polynomial(L_scaled, MAX_DEGREE)
        support = MAX_DEGREE + 1
        graph = [X_] + T_k
        G = [Input(shape=(None, None), batch_shape=(None, None), sparse=True) for _ in range(support)]
    else:
        raise Exception('Invalid filter type.')

    # Model architecure
    X_in = Input(shape=(X_.shape[1],))
    H = Dropout(0.5)(X_in)
    H = GraphConvolution(16, support, activation='relu', kernel_regularizer=l2(5e-4))([H]+G)
    H = Dropout(0.5)(H)
    Y = GraphConvolution(y.shape[1], support, activation='softmax')([H]+G)
    model = Model(inputs=[X_in] + G, outputs=Y)
    model.compile(loss='categorical_crossentropy', optimizer=Adam(lr=0.01))

    # Helper variables for k_fold loop
    wait = 0
    preds = None
    best_val_loss = 99999
    t_fit = time.time()
    for epoch in range(1, NB_EPOCH + 1):

        # Log wall-clock time
        t = time.time()

        # Single training iteration (we mask nodes without labels for loss calculation)
        model.fit(graph, y_train, sample_weight=train_mask,
                  batch_size=A_.shape[0], epochs=1, shuffle=False, verbose=0)
        if epoch == 1 and args.log:
            print("tempo per fit [1° epoch] = "+ str(time.time()-t))
            print("Pesi iniziali [1° epoch]")
            print(model.get_weights()[0][0])

        # Predict on full dataset
        preds = model.predict(graph, batch_size=A_.shape[0])

        # Train / validation scores
        train_val_loss, train_val_acc = evaluate_preds(preds, [y_train, y_val],
                                                       [idx_train, idx_val])
        if args.log:
            print("Epoch: {:04d}".format(epoch),
                  "train_loss= {:.4f}".format(train_val_loss[0]),
                  "train_acc= {:.4f}".format(train_val_acc[0]),
                  "val_loss= {:.4f}".format(train_val_loss[1]),
                  "val_acc= {:.4f}".format(train_val_acc[1]),
                  "time= {:.4f}".format(time.time() - t))

        # Early stopping
        if train_val_loss[1] < best_val_loss:
            best_val_loss = train_val_loss[1]
            wait = 0
        else:
            if wait >= PATIENCE :
                if args.log:
                    print('\tEpoch {}: early stopping'.format(epoch))
                break
            wait += 1

    # Testing
    if args.log:
        print("Pesi finali [1° epoch]")
        print(model.get_weights()[0][0])
        print("time to complete fit : " + str(time.time() - t_fit))

    test_loss, test_acc = evaluate_preds(preds, [y_test], [idx_test])
    if args.log:
        print("\nTest set results:",
          "loss= {:.4f}".format(test_loss[0]),
          "accuracy= {:.4f}".format(test_acc[0]))
    clear_session() #Pulisco la sessione tensorflow --> fix per il tempo incrementale sul fit.
    return test_loss[0], test_acc[0]
示例#6
0
def main(dataset, filt, max_degree, sym_norm, nb_epoch, patience):
    # Get data
    X, A, y = load_data(dataset=dataset)
    y_train, y_val, y_test, idx_train, idx_val, idx_test, train_mask = get_splits(
        y, 0.35, 0.45)

    # Normalize X
    X /= X.sum(1).reshape(-1, 1)

    if filt == 'localpool':
        """ Local pooling filters (see 'renormalization trick' in Kipf & Welling, arXiv 2016) """
        print('Using local pooling filters...')
        A_ = preprocess_adj(A, sym_norm)
        support = 1
        graph = [X, A_]
        G = [Input(shape=(None, None), batch_shape=(None, None), sparse=True)]

    elif filt == 'chebyshev':
        """ Chebyshev polynomial basis filters (Defferard et al., NIPS 2016)  """
        print('Using Chebyshev polynomial basis filters...')
        L = normalized_laplacian(A, sym_norm)
        L_scaled = rescale_laplacian(L)
        T_k = chebyshev_polynomial(L_scaled, max_degree)
        support = max_degree + 1
        graph = [X] + T_k
        G = [
            Input(shape=(None, None), batch_shape=(None, None), sparse=True)
            for _ in range(support)
        ]

    else:
        raise Exception('Invalid filter type.')

    X_in = Input(shape=(X.shape[1], ))

    # Define model architecture
    # NOTE: We pass arguments for graph convolutional layers as a list of tensors.
    # This is somewhat hacky, more elegant options would require rewriting the Layer base class.
    H = Dropout(0.5)(X_in)
    H = GraphConvolution(16,
                         support,
                         activation='relu',
                         kernel_regularizer=l2(5e-4))([H] + G)
    H = Dropout(0.5)(H)
    Y = GraphConvolution(y.shape[1], support, activation='softmax')([H] + G)

    # Compile model
    model = Model(inputs=[X_in] + G, outputs=Y)
    model.compile(loss='categorical_crossentropy', optimizer=Adam(lr=0.01))

    # Helper variables for main training loop
    wait = 0
    preds = None
    best_val_loss = 99999

    # Fit
    for epoch in range(1, nb_epoch + 1):

        # Log wall-clock time
        t = time.time()

        # Single training iteration (we mask nodes without labels for loss calculation)
        model.fit(graph,
                  y_train,
                  sample_weight=train_mask,
                  batch_size=A.shape[0],
                  epochs=1,
                  shuffle=False,
                  verbose=0)

        # Predict on full dataset
        preds = model.predict(graph, batch_size=A.shape[0])

        # Train / validation scores
        train_val_loss, train_val_acc = evaluate_preds(preds, [y_train, y_val],
                                                       [idx_train, idx_val])
        print("Epoch: {:04d}".format(epoch),
              "train_loss= {:.4f}".format(train_val_loss[0]),
              "train_acc= {:.4f}".format(train_val_acc[0]),
              "val_loss= {:.4f}".format(train_val_loss[1]),
              "val_acc= {:.4f}".format(train_val_acc[1]),
              "time= {:.4f}".format(time.time() - t))

        # Early stopping
        if train_val_loss[1] < best_val_loss:
            best_val_loss = train_val_loss[1]
            wait = 0
        else:
            if wait >= patience:
                print('Epoch {}: early stopping'.format(epoch))
                break
            wait += 1


# Testing
    test_loss, test_acc = evaluate_preds(preds, [y_test], [idx_test])
    print("Test set results:", "loss= {:.4f}".format(test_loss[0]),
          "accuracy= {:.4f}".format(test_acc[0]))
示例#7
0
def run(param_dict):
    param_dict = keras_cmdline.fill_missing_defaults(augment_parser,
                                                     param_dict)
    optimizer = keras_cmdline.return_optimizer(param_dict)
    pprint(param_dict)

    EPOCHS = param_dict['epochs']
    FILTER = param_dict['filter']
    MAX_DEGREE = param_dict['max_degree']
    SYM_NORM = param_dict['sys_norm']
    DROPOUT = param_dict['dropout']
    NUNITS = param_dict['nunits']
    ACTIVATION = param_dict['activation']
    BATCH_SIZE = param_dict['batch_size']
    TIMEOUT = param_dict['timeout']

    #SHARE_WEIGHTS = param_dict['share_weights']
    # Define parameters
    DATASET = 'cora'
    #FILTER = 'localpool'  # 'chebyshev'
    #MAX_DEGREE = 2  # maximum polynomial degree
    #SYM_NORM = True  # symmetric (True) vs. left-only (False) normalization

    PATIENCE = 10  # early stopping patience

    # Get data
    timer.start('stage in')
    if param_dict['data_source']:
        data_source = param_dict['data_source']
    else:
        data_source = os.path.dirname(os.path.abspath(__file__))
        data_source = os.path.join(data_source, 'data/cora')

    paths = util.stage_in(['cora.content', 'cora.cites'],
                          source=data_source,
                          dest=param_dict['stage_in_destination'])
    path_content = paths['cora.content']
    path_cites = paths['cora.cites']

    idx_features_labels = np.genfromtxt(path_content, dtype=np.dtype(str))
    features = sp.csr_matrix(idx_features_labels[:, 1:-1], dtype=np.float32)
    labels = encode_onehot(idx_features_labels[:, -1])

    # build graph
    idx = np.array(idx_features_labels[:, 0], dtype=np.int32)
    idx_map = {j: i for i, j in enumerate(idx)}
    edges_unordered = np.genfromtxt(path_cites, dtype=np.int32)
    edges = np.array(list(map(idx_map.get, edges_unordered.flatten())),
                     dtype=np.int32).reshape(edges_unordered.shape)
    adj = sp.coo_matrix((np.ones(edges.shape[0]), (edges[:, 0], edges[:, 1])),
                        shape=(labels.shape[0], labels.shape[0]),
                        dtype=np.float32)

    # build symmetric adjacency matrix
    adj = adj + adj.T.multiply(adj.T > adj) - adj.multiply(adj.T > adj)

    print('Dataset has {} nodes, {} edges, {} features.'.format(
        adj.shape[0], edges.shape[0], features.shape[1]))
    X, A, y = features.todense(), adj, labels
    timer.end()

    timer.start('preprocessing')
    y_train, y_val, y_test, idx_train, idx_val, idx_test, train_mask = get_splits(
        y)

    # Normalize X
    X /= X.sum(1).reshape(-1, 1)

    if FILTER == 'localpool':
        """ Local pooling filters (see 'renormalization trick' in Kipf & Welling, arXiv 2016) """
        print('Using local pooling filters...')
        A_ = preprocess_adj(A, SYM_NORM)
        support = 1
        graph = [X, A_]
        G = [Input(shape=(None, None), batch_shape=(None, None), sparse=True)]
    elif FILTER == 'chebyshev':
        """ Chebyshev polynomial basis filters (Defferard et al., NIPS 2016)  """
        print('Using Chebyshev polynomial basis filters...')
        L = normalized_laplacian(A, SYM_NORM)
        L_scaled = rescale_laplacian(L)
        T_k = chebyshev_polynomial(L_scaled, MAX_DEGREE)
        support = MAX_DEGREE + 1
        graph = [X] + T_k
        G = [
            Input(shape=(None, None), batch_shape=(None, None), sparse=True)
            for _ in range(support)
        ]
    else:
        raise Exception('Invalid filter type.')

    model_path = param_dict['model_path']
    model_mda_path = None
    model = None
    initial_epoch = 0

    if model_path:
        custom_objects = {'GraphConvolution': GraphConvolution}
        savedModel = util.resume_from_disk(BNAME,
                                           param_dict,
                                           data_dir=model_path,
                                           custom_objects=custom_objects)
        model_mda_path = savedModel.model_mda_path
        model_path = savedModel.model_path
        model = savedModel.model
        initial_epoch = savedModel.initial_epoch

    if model is None:
        X_in = Input(shape=(X.shape[1], ))
        # Define model architecture
        # NOTE: We pass arguments for graph convolutional layers as a list of tensors.
        # This is somewhat hacky, more elegant options would require rewriting the Layer base class.
        H = Dropout(DROPOUT)(X_in)
        H = GraphConvolution(NUNITS,
                             support,
                             activation=ACTIVATION,
                             kernel_regularizer=l2(5e-4))([H] + G)
        H = Dropout(DROPOUT)(H)
        Y = GraphConvolution(y.shape[1], support,
                             activation='softmax')([H] + G)

        # Compile model
        model = Model(inputs=[X_in] + G, outputs=Y)
        model.compile(loss='categorical_crossentropy', optimizer=optimizer)

        # Helper variables for main training loop
        wait = 0
        preds = None
        best_val_loss = 99999
    timer.end()
    #earlystop = EarlyStopping(monitor='val_acc', min_delta=0.0001, patience=50, verbose=1, mode='auto')
    timeout_monitor = TerminateOnTimeOut(TIMEOUT)
    callbacks_list = [timeout_monitor]
    # Fit
    training_timer = util.Timer()
    training_timer.start('model training')
    prev_val_acc = 0
    count = 0
    patience = 50
    delta = 0.0001
    for epoch in range(initial_epoch, EPOCHS):
        # Log wall-clock time
        timer.start(f'epoch {epoch}')
        # Single training iteration (we mask nodes without labels for loss calculation)
        model.fit(graph,
                  y_train,
                  sample_weight=train_mask,
                  batch_size=A.shape[0],
                  epochs=1,
                  shuffle=False,
                  verbose=0)

        # Predict on full dataset
        preds = model.predict(graph, batch_size=A.shape[0])  #

        # Train / validation scores
        train_val_loss, train_val_acc = evaluate_preds(preds, [y_train, y_val],
                                                       [idx_train, idx_val])
        print("Epoch: {:04d}".format(epoch),
              "train_loss= {:.4f}".format(train_val_loss[0]),
              "train_acc= {:.4f}".format(train_val_acc[0]),
              "val_loss= {:.4f}".format(train_val_loss[1]),
              "val_acc= {:.4f}".format(train_val_acc[1]))
        timer.end()

        diff = abs(prev_val_acc - train_val_acc[1])
        #print(diff)
        if diff > delta:
            prev_val_acc = train_val_acc[1]
            count = 0
        else:
            count = count + 1

        if count >= patience:
            print('Early stopping')
            break

        elapsed = time.time() - training_timer.t0
        if elapsed >= TIMEOUT * 60:
            print(' - timeout: training time = %2.3fs/%2.3fs' %
                  (elapsed, TIMEOUT * 60))
            break
    training_timer.end()

    # Testing
    test_loss, test_acc = evaluate_preds(preds, [y_test], [idx_test])
    print("Test set results:", "loss= {:.4f}".format(test_loss[0]),
          "accuracy= {:.4f}".format(test_acc[0]))
    print('===Validation accuracy:', test_acc[0])
    print('OUTPUT:', -test_acc[0])

    if model_path:
        timer.start('model save')
        model.save(model_path)
        util.save_meta_data(param_dict, model_mda_path)
        timer.end()

    return -test_acc[0]