예제 #1
0
def run_net(data, params):
    #
    # UNPACK DATA
    #

    x_train, y_train, x_val, y_val, x_test, y_test = data['spectral'][
        'train_and_test']
    x_train_unlabeled, y_train_unlabeled, x_train_labeled, y_train_labeled = data[
        'spectral']['train_unlabeled_and_labeled']
    x_val_unlabeled, y_val_unlabeled, x_val_labeled, y_val_labeled = data[
        'spectral']['val_unlabeled_and_labeled']

    if 'siamese' in params['affinity']:
        pairs_train, dist_train, pairs_val, dist_val = data['siamese'][
            'train_and_test']

    x = np.concatenate((x_train, x_val, x_test), axis=0)
    y = np.concatenate((y_train, y_val, y_test), axis=0)

    if len(x_train_labeled):
        y_train_labeled_onehot = OneHotEncoder().fit_transform(
            y_train_labeled.reshape(-1, 1)).toarray()
    else:
        y_train_labeled_onehot = np.empty((0, len(np.unique(y))))

    #
    # SET UP INPUTS
    #

    # create true y placeholder (not used in unsupervised training)
    y_true = tf.placeholder(tf.float32,
                            shape=(None, params['n_clusters']),
                            name='y_true')

    batch_sizes = {
        'Unlabeled': params['batch_size'],
        'Labeled': params['batch_size'],
        'Orthonorm': params.get('batch_size_orthonorm', params['batch_size']),
    }

    input_shape = x.shape[1:]

    # spectralnet has three inputs -- they are defined here
    inputs = {
        'Unlabeled': Input(shape=input_shape, name='UnlabeledInput'),
        'Labeled': Input(shape=input_shape, name='LabeledInput'),
        'Orthonorm': Input(shape=input_shape, name='OrthonormInput'),
    }

    #
    # DEFINE AND TRAIN SIAMESE NET
    #

    # run only if we are using a siamese network
    if params['affinity'] == 'siamese':
        siamese_net = networks.SiameseNet(inputs, params['arch'],
                                          params.get('siam_reg'), y_true)

        history = siamese_net.train(pairs_train, dist_train, pairs_val,
                                    dist_val, params['siam_lr'],
                                    params['siam_drop'],
                                    params['siam_patience'], params['siam_ne'],
                                    params['siam_batch_size'])

    else:
        siamese_net = None

    #
    # DEFINE AND TRAIN SPECTRALNET
    #

    spectral_net = networks.SpectralNet(inputs, params['arch'],
                                        params.get('spec_reg'), y_true,
                                        y_train_labeled_onehot,
                                        params['n_clusters'],
                                        params['affinity'],
                                        params['scale_nbr'], params['n_nbrs'],
                                        batch_sizes, siamese_net, x_train,
                                        len(x_train_labeled))

    spectral_net.train(x_train_unlabeled, x_train_labeled, x_val_unlabeled,
                       params['spec_lr'], params['spec_drop'],
                       params['spec_patience'], params['spec_ne'])

    print("finished training")

    #
    # EVALUATE
    #

    # get final embeddings
    x_spectralnet = spectral_net.predict(x)

    # get accuracy and nmi
    kmeans_assignments, km = get_cluster_sols(x_spectralnet,
                                              ClusterClass=KMeans,
                                              n_clusters=params['n_clusters'],
                                              init_args={'n_init': 10})
    y_spectralnet, _ = get_y_preds(kmeans_assignments, y, params['n_clusters'])
    print_accuracy(kmeans_assignments, y, params['n_clusters'])
    from sklearn.metrics import normalized_mutual_info_score as nmi
    nmi_score = nmi(kmeans_assignments, y)
    print('NMI: ' + str(np.round(nmi_score, 3)))

    if params['generalization_metrics']:
        x_spectralnet_train = spectral_net.predict(x_train_unlabeled)
        x_spectralnet_test = spectral_net.predict(x_test)
        km_train = KMeans(
            n_clusters=params['n_clusters']).fit(x_spectralnet_train)
        from scipy.spatial.distance import cdist
        dist_mat = cdist(x_spectralnet_test, km_train.cluster_centers_)
        closest_cluster = np.argmin(dist_mat, axis=1)
        print_accuracy(closest_cluster, y_test, params['n_clusters'],
                       ' generalization')
        nmi_score = nmi(closest_cluster, y_test)
        print('generalization NMI: ' + str(np.round(nmi_score, 3)))

    return x_spectralnet, y_spectralnet
예제 #2
0
    'Orthonorm': Input(shape=input_shape, name='OrthonormInput'),
}

y_true = tf.placeholder(tf.float32,
                        shape=(None, params['n_clusters']),
                        name='y_true')

# Load Siamese network
if params['affinity'] == 'siamese':
    siamese_input_shape = [params['n_clusters']]
    siamese_inputs = {
        'Unlabeled': Input(shape=siamese_input_shape, name='UnlabeledInput'),
        'Labeled': Input(shape=siamese_input_shape, name='LabeledInput'),
    }
    siamese_net = networks.SiameseNet(siamese_inputs, params['arch'],
                                      params.get('siam_reg'), y_true,
                                      params['siamese_model_path'])
else:
    siamese_net = None


y_train, x_train, p_train, \
y_test, x_test, \
y_val, x_val, p_val, \
y_train_labeled, x_train_labeled, \
y_val_labeled, x_val_labeled, \
y_train_unlabeled, x_train_unlabeled, \
y_val_unlabeled, x_val_unlabeled, \
train_val_split = get_common_data(params, load_base_data(params, params['dset']))

예제 #3
0
def run_net(data, params, train=True):
    # Unpack data
    x_train, y_train, x_val, y_val, x_test, y_test = data['spectral']['train_and_test']
    x_train_unlabeled, y_train_unlabeled, x_train_labeled, y_train_labeled = data['spectral'][
        'train_unlabeled_and_labeled']
    x_val_unlabeled, y_val_unlabeled, x_val_labeled, y_val_labeled = data['spectral']['val_unlabeled_and_labeled']

    x = concatenate([x_train, x_val, x_test])
    y = concatenate([y_train, y_val, y_test])

    if len(x_train_labeled):
        y_train_labeled_onehot = OneHotEncoder().fit_transform(y_train_labeled.reshape(-1, 1)).toarray()
    else:
        y_train_labeled_onehot = np.empty((0, len(np.unique(y))))

    # Set up inputs
    # create true y placeholder (not used in unsupervised training)
    y_true = tf.placeholder(tf.float32, shape=(None, params['n_clusters']), name='y_true')

    batch_sizes = {
        'Unlabeled': params['batch_size'],
        'Labeled': params['batch_size'],
        'Orthonorm': params.get('batch_size_orthonorm', params['batch_size']),
    }

    input_shape = x.shape[1:]

    # spectralnet has three inputs -- they are defined here
    inputs = {
        'Unlabeled': Input(shape=input_shape, name='UnlabeledInput'),
        'Labeled': Input(shape=input_shape, name='LabeledInput'),
        'Orthonorm': Input(shape=input_shape, name='OrthonormInput'),
    }

    # run only if we are using a siamese network
    if params['affinity'] == 'siamese':
        siamese_model_path = params['siamese_model_path']
        if not os.path.isfile(os.path.join(siamese_model_path, "model.h5")):
            raise Exception("siamese_model_path %s does not exist" % siamese_model_path)
        siamese_net = networks.SiameseNet(inputs, params['arch'], params.get('siam_reg'), y_true, siamese_model_path)
    else:
        siamese_net = None
    if train:
        K.set_learning_phase(1)
    # Define and train spectral net
    spectralnet_model_path = os.path.join(params['model_path'], 'spectral_net')
    spectral_net = networks.SpectralNet(inputs, params['arch'],
                                        params.get('spec_reg'), y_true, y_train_labeled_onehot,
                                        params['n_clusters'], params['affinity'], params['scale_nbr'],
                                        params['n_nbrs'], batch_sizes,
                                        spectralnet_model_path,
                                        siamese_net, True, x_train, len(x_train_labeled),
                                        )
    if train:
        spectral_net.train(
            x_train_unlabeled, x_train_labeled, x_val_unlabeled,
            params['spec_lr'], params['spec_drop'], params['spec_patience'],
            params['spec_ne'])

        print("finished training")
        if not os.path.isdir(spectralnet_model_path):
            os.makedirs(spectralnet_model_path)
        spectral_net.save_model()

        print("finished saving model")

    # Evaluate model
    # get final embeddings
    x_spectralnet = spectral_net.predict(x)

    clustering_algo = ClusteringAlgorithm(ClusterClass=KMeans, n_clusters=params['n_clusters'],
                                          init_args={'n_init': 10})
    clustering_algo.fit(x_spectralnet, y)

    # get accuracy and nmi
    joblib.dump(clustering_algo, os.path.join(params['model_path'], 'spectral_net', 'clustering_aglo.sav'))

    kmeans_assignments = clustering_algo.predict_cluster_assignments(x_spectralnet)
    y_spectralnet = clustering_algo.predict(x_spectralnet)
    print_accuracy(kmeans_assignments, y, params['n_clusters'])
    nmi_score = nmi(kmeans_assignments, y)
    print('NMI: ' + str(np.round(nmi_score, 3)))

    if params['generalization_metrics']:
        x_spectralnet_train = spectral_net.predict(x_train_unlabeled)
        x_spectralnet_test = spectral_net.predict(x_test)
        km_train = KMeans(n_clusters=params['n_clusters']).fit(x_spectralnet_train)
        from scipy.spatial.distance import cdist
        dist_mat = cdist(x_spectralnet_test, km_train.cluster_centers_)
        closest_cluster = np.argmin(dist_mat, axis=1)
        print_accuracy(closest_cluster, y_test, params['n_clusters'], ' generalization')
        nmi_score = nmi(closest_cluster, y_test)
        print('generalization NMI: ' + str(np.round(nmi_score, 3)))

    return x_spectralnet, y_spectralnet
예제 #4
0
def run_net(data, params):
    #
    # UNPACK DATA
    #
    pairs_train, dist_train, pairs_val, dist_val = data['train_and_test']

    #
    # SET UP INPUTS
    #

    # create true y placeholder (not used in unsupervised training)
    y_true = tf.placeholder(tf.float32, shape=(None, params['n_clusters']), name='y_true')

    batch_sizes = {
        'Unlabeled': params['batch_size'],
        'Labeled': params['batch_size'],
        'Orthonorm': params.get('batch_size_orthonorm', params['batch_size']),
    }

    input_shape = pairs_train[0].shape[1:]

    inputs = {
        'Unlabeled': Input(shape=input_shape, name='UnlabeledInput'),
        'Labeled': Input(shape=input_shape, name='LabeledInput'),
    }

    #
    # DEFINE AND TRAIN SIAMESE NET
    #

    siamese_model_path = params['model_path']

    siamese_net = networks.SiameseNet(inputs, params['arch'], params.get('siam_reg'), y_true, siamese_model_path)

    siamese_net.train(pairs_train, dist_train, pairs_val, dist_val,
                      params['siam_lr'], params['siam_drop'], params['siam_patience'],
                      params['siam_ne'], params['siam_batch_size'])
    if not os.path.isdir(siamese_model_path):
        os.makedirs(siamese_model_path)
    siamese_net.save_model()

    # from time import time
    # import matplotlib.pyplot as plt
    # from sklearn import manifold
    # from applications.plot_embedding import plot_embedding
    # from core.data import get_common_data, load_base_data
    # y_train, x_train, p_train, \
    # y_test, x_test, \
    # y_val, x_val, p_val, \
    # y_train_labeled, x_train_labeled, \
    # y_val_labeled, x_val_labeled, \
    # y_train_unlabeled, x_train_unlabeled, \
    # y_val_unlabeled, x_val_unlabeled, \
    # train_val_split = get_common_data(params, load_base_data(params, params['dset']))
    #
    # sample_size = 1000
    # x_test = x_val[:sample_size, :]
    # y_test = y_val[:sample_size]
    # x_affinity = siamese_net.predict(x_test, batch_sizes)
    #
    # # ----------------------------------------------------------------------
    # # t-SNE embedding of the digits dataset
    # print("Computing t-SNE embedding")
    # tsne = manifold.TSNE(n_components=2, init='pca', random_state=0)
    # t0 = time()
    # X_tsne = tsne.fit_transform(x_test)
    # X_affinity_tsne = tsne.fit_transform(x_affinity)
    #
    # plot_embedding(X_tsne,
    #                y_test,
    #                "t-SNE embedding of the digits - original (time %.2fs)" %
    #                (time() - t0))
    # plot_embedding(X_affinity_tsne,
    #                y_test,
    #                "t-SNE embedding of the digits - siamese (time %.2fs)" %
    #                (time() - t0))
    # plt.show()
예제 #5
0
def run_net(data_list, config, save=True):

    # network input shapes stored as view-list
    MvSCN_input_shape = []
    SiameseNet_input_shape = []

    # training and testing data stored as view-list
    x_train_list = []
    x_test_list = []

    # get the labels
    _, y_train, _, y_test = data_list[0]['spectral']

    batch_sizes = {
        'Embedding': config['batch_size'],
        'Orthogonal': config['batch_size_orthogonal'],
    }

    for i in range(config['view_size']):
        data_i = data_list[i]
        x_train_i, y_train_i, x_test_i, y_test_i = data_i['spectral']
        x = x_train_i

        x_test_list.append(x_test_i)
        x_train_list.append(x_train_i)

        # SiameseNet training pairs
        pairs_train, dist_train = data_i['siamese']

        # input shape
        input_shape = x.shape[1:]
        inputs = {
            'Embedding':
            Input(shape=input_shape, name='EmbeddingInput' + 'view' + str(i)),
            'Orthogonal':
            Input(shape=input_shape, name='OrthogonalInput' + 'view' + str(i)),
        }
        MvSCN_input_shape.append(inputs)

        print('******** SiameseNet ' + 'view' + str(i + 1) + ' ********')
        siamese_net = networks.SiameseNet(name=config['dset'] + '_' + 'view' +
                                          str(i + 1),
                                          inputs=inputs,
                                          arch=config['arch'],
                                          siam_reg=config['siam_reg'])
        history = siamese_net.train(pairs_train=pairs_train,
                                    dist_train=dist_train,
                                    lr=config['siam_lr'],
                                    drop=config['siam_drop'],
                                    patience=config['siam_patience'],
                                    num_epochs=config['siam_epoch'],
                                    batch_size=config['siam_batch_size'],
                                    pre_train=config['siam_pre_train'])

        SiameseNet_input_shape.append(siamese_net)

    # MvSCN
    mvscn = networks.MvSCN(input_list=MvSCN_input_shape,
                           arch=config['arch'],
                           spec_reg=config['spectral_reg'],
                           n_clusters=config['n_clusters'],
                           scale_nbr=config['scale_nbr'],
                           n_nbrs=config['n_nbrs'],
                           batch_sizes=batch_sizes,
                           view_size=config['view_size'],
                           siamese_list=SiameseNet_input_shape,
                           x_train_siam=x_train_list,
                           lamb=config['lamb'])

    # training
    print('********', 'Training', '********')
    mvscn.train(x_train=x_train_list,
                lr=config['spectral_lr'],
                drop=config['spectral_drop'],
                patience=config['spectral_patience'],
                num_epochs=config['spectral_epoch'])

    print("Training finished ")

    print('********', 'Prediction', '********')
    print('Testing data')
    # get final testing embeddings
    x_test_final_list = mvscn.predict(x_test_list)
    print(
        'Learned representations for testing (view size, nsamples, dimension)',
        x_test_final_list.shape)

    # clustering
    y_preds, scores = Clustering.Clustering(x_test_final_list, y_test)

    return x_test_final_list, scores
예제 #6
0
def run_predict(params):
    K.set_learning_phase(0)
    input_shape = x.shape[1:]

    y_labeled_onehot = np.empty((0, params['n_clusters']))

    # spectralnet has three inputs -- they are defined here
    inputs = {
        'Unlabeled': Input(shape=input_shape, name='UnlabeledInput'),
        'Labeled': Input(shape=input_shape, name='LabeledInput'),
        'Orthonorm': Input(shape=input_shape, name='OrthonormInput'),
    }
    y_true = tf.placeholder(tf.float32,
                            shape=(None, params['n_clusters']),
                            name='y_true')

    # Load Siamese network
    if params['affinity'] == 'siamese':
        siamese_input_shape = [params['n_clusters']]
        siamese_inputs = {
            'Unlabeled': Input(shape=siamese_input_shape,
                               name='UnlabeledInput'),
            'Labeled': Input(shape=siamese_input_shape, name='LabeledInput'),
        }
        siamese_net = networks.SiameseNet(siamese_inputs, params['arch'],
                                          params.get('siam_reg'), y_true,
                                          params['siamese_model_path'])

    else:
        siamese_net = None

    # Load Spectral net
    spectralnet_model_path = os.path.join(params['model_path'], 'spectral_net')
    spectral_net = networks.SpectralNet(inputs,
                                        params['arch'],
                                        params.get('spec_reg'),
                                        y_true,
                                        y_labeled_onehot,
                                        params['n_clusters'],
                                        params['affinity'],
                                        params['scale_nbr'],
                                        params['n_nbrs'],
                                        batch_sizes,
                                        spectralnet_model_path,
                                        siamese_net,
                                        train=False)
    # get final embeddings
    W_tensor = costs.knn_affinity(siamese_net.outputs['A'],
                                  params['n_nbrs'],
                                  scale=None,
                                  scale_nbr=params['scale_nbr'])

    x_spectralnet = spectral_net.predict_unlabelled(x)
    W = spectral_net.run_tensor(x, W_tensor)
    print('x_spectralnet', x_spectralnet.shape)
    clustering_algo = joblib.load(
        os.path.join(params['model_path'], 'spectral_net',
                     'clustering_aglo.sav'))

    kmeans_assignments = clustering_algo.predict_cluster_assignments(
        x_spectralnet)
    y_spectralnet = clustering_algo.predict(x_spectralnet)
    print_accuracy(kmeans_assignments, y, params['n_clusters'])
    # x_dec = decode_data(x, params, params['dset'])
    return x_spectralnet, y_spectralnet, x_spectralnet, W
예제 #7
0
def run_net(data, params):
    #
    # UNPACK DATA
    #

    pairs_train, dist_train, pairs_val, dist_val = data['siamese']['train_and_test']
    extra_distances_train = data['siamese']['differences'][0]
    extra_distances_val = data['siamese']['differences'][1]

    #
    # SET UP INPUTS
    #

    # create true y placeholder (not used in unsupervised training)
    y_true = tf.placeholder(tf.float32, shape=(None, params['n_clusters']), name='y_true')

    batch_sizes = {
            'Unlabeled': params['batch_size'],
            'Labeled': params['batch_size'],
            'Orthonorm': params.get('batch_size_orthonorm', params['batch_size']),
            }

    input_shape = [pairs_train.shape[2]]

    # spectralnet has three inputs -- they are defined here
    inputs = {
            'Unlabeled': Input(shape=input_shape,name='UnlabeledInput'),
            'Labeled': Input(shape=input_shape,name='LabeledInput'),
            'Orthonorm': Input(shape=input_shape,name='OrthonormInput'),
            }


    extra_distances = Input(shape=[1],name='ExtraDistances')

    #
    # DEFINE AND TRAIN SIAMESE NET
    #

    # run only if we are using a siamese network
    siamese_net = networks.SiameseNet(inputs, extra_distances, y_true, params)
    if params['model_in'] is None:
        print('Training...')
        history = siamese_net.train(
                pairs_train, dist_train, extra_distances_train,
                pairs_val, dist_val, extra_distances_val,
                params['siam_lr'], params['siam_drop'], params['siam_patience'],
                params['siam_ne'], params['siam_batch_size'])
        print("finished training")
        if params['model_out'] is not None:
            siamese_net.net.save_weights(params['model_out'])
    else:
        # siamese_net.net.load_weights(params['model_in'])
        print('Loaded weights from checkpoint.')

    #
    # EVALUATE
    #

    all_x_sim = []
    all_z_sim = []
    all_y = []
    for idx in range(0, pairs_val.shape[0]):

      x = pairs_val[idx, :, :]
      
      z = siamese_net.predict(x, batch_sizes)

      x_sim = np.linalg.norm(x[0,:] - x[1,:])
      z_sim = np.linalg.norm(z[0,:] - z[1,:])

      all_x_sim.append(x_sim)
      all_z_sim.append(z_sim)
      all_y.append(dist_val[idx])

      # orig_sim = np.linalg.norm(x[0,:] - x[1,:])
  
    model1 = sklearn.linear_model.LogisticRegression()
    model1.fit(np.array(all_x_sim).reshape(-1, 1), np.array(all_y))
    score = model1.score(np.array(all_x_sim).reshape(-1, 1), np.array(all_y))
    print('Score with original space: ' + str(score))

    score = np.sum(np.array(all_y) == 1) / float(len(all_y))
    print('Score with predict 1: ' + str(score))

    score = np.sum(np.array(all_y) == 0) / float(len(all_y))
    print('Score with predict 0: ' + str(score))

    preds = np.array(all_z_sim) > 0.09
    preds = preds.astype(int)
    score = np.sum(np.array(all_y) == preds) / float(len(all_y))
    print('Score with predict z > 0.09 as 1: ' + str(score))

    preds = np.array(all_z_sim) > 1
    preds = preds.astype(int)
    score = np.sum(np.array(all_y) == preds) / float(len(all_y))
    print('Score with predict z > 1 as 1: ' + str(score))

    model2 = sklearn.linear_model.LogisticRegression()
    model2.fit(np.array(all_z_sim).reshape(-1, 1), np.array(all_y))
    score = model2.score(np.array(all_z_sim).reshape(-1, 1), np.array(all_y))
    print('Score with transformed space: ' + str(score))

    # xx = np.mgrid[0:0.15:0.005].reshape(-1, 1)
    # probs = model2.predict_proba(xx)[:, 1].reshape(xx.shape)
      
    plt.figure(1)
    plt.scatter(all_x_sim, all_z_sim, s=10, c=all_y) 
    # for i in range(len(probs)):
      # plt.axhline(y=xx[i])    

    plt.show()
예제 #8
0
def run_net(data, params):
    #
    # UNPACK DATA
    #

    x_train, y_train, x_val, y_val, x_test, y_test = data['spectral'][
        'train_and_test']
    x_train_unlabeled, y_train_unlabeled, x_train_labeled, y_train_labeled = data[
        'spectral']['train_unlabeled_and_labeled']
    x_val_unlabeled, y_val_unlabeled, x_val_labeled, y_val_labeled = data[
        'spectral']['val_unlabeled_and_labeled']

    if 'siamese' in params['affinity']:
        pairs_train, dist_train, pairs_val, dist_val = data['siamese'][
            'train_and_test']

    x = np.concatenate((x_train, x_val, x_test), axis=0)
    y = np.concatenate((y_train, y_val, y_test), axis=0)

    X = x
    n_samples, n_features = X.shape

    def plot_embedding(X, title=None):
        x_min, x_max = np.min(X, 0), np.max(X, 0)
        X = (X - x_min) / (x_max - x_min)
        plt.figure(figsize=(12, 12))
        ax = plt.subplot(111)
        for i in range(X.shape[0]):
            plt.text(X[i, 0],
                     X[i, 1],
                     '.',
                     color=plt.cm.Set1(1),
                     fontdict={
                         'weight': 'bold',
                         'size': 20
                     })
        plt.xticks([]), plt.yticks([])
        if title is not None:
            plt.title(title)

    from sklearn import manifold

    tsne = manifold.TSNE(n_components=2, init='pca', random_state=0)
    start_time = time.time()
    X_tsne = tsne.fit_transform(X)

    plot_embedding(X_tsne)
    plt.show()

    if len(x_train_labeled):
        y_train_labeled_onehot = OneHotEncoder().fit_transform(
            y_train_labeled.reshape(-1, 1)).toarray()
    else:
        y_train_labeled_onehot = np.empty((0, len(np.unique(y))))

    #
    # SET UP INPUTS
    #

    # create true y placeholder (not used in unsupervised training)
    y_true = tf.placeholder(tf.float32,
                            shape=(None, params['n_clusters']),
                            name='y_true')

    batch_sizes = {
        'Unlabeled': params['batch_size'],
        'Labeled': params['batch_size'],
        'Orthonorm': params.get('batch_size_orthonorm', params['batch_size']),
    }

    input_shape = x.shape[1:]

    # spectralnet has three inputs -- they are defined here
    inputs = {
        'Unlabeled': Input(shape=input_shape, name='UnlabeledInput'),
        'Labeled': Input(shape=input_shape, name='LabeledInput'),
        'Orthonorm': Input(shape=input_shape, name='OrthonormInput'),
    }

    #
    # DEFINE AND TRAIN SIAMESE NET
    #

    # run only if we are using a siamese network
    if params['affinity'] == 'siamese':
        siamese_net = networks.SiameseNet(inputs, params['arch'],
                                          params.get('siam_reg'), y_true)

        history = siamese_net.train(pairs_train, dist_train, pairs_val,
                                    dist_val, params['siam_lr'],
                                    params['siam_drop'],
                                    params['siam_patience'], params['siam_ne'],
                                    params['siam_batch_size'])

    else:
        siamese_net = None

    spectral_net = networks.SpectralNet(inputs, params['arch'],
                                        params.get('spec_reg'), y_true,
                                        y_train_labeled_onehot,
                                        params['n_clusters'],
                                        params['affinity'],
                                        params['scale_nbr'], params['n_nbrs'],
                                        batch_sizes, siamese_net, x_train,
                                        len(x_train_labeled))

    spectral_net.train(x_train_unlabeled, x_train_labeled, x_val_unlabeled,
                       params['spec_lr'], params['spec_drop'],
                       params['spec_patience'], params['spec_ne'])

    print("finished training")
    #
    # EVALUATE
    #

    # get final embeddings
    x_spectralnet = spectral_net.predict(x)

    # get accuracy and nmi
    kmeans_assignments, km = get_cluster_sols(x_spectralnet,
                                              ClusterClass=KMeans,
                                              n_clusters=params['n_clusters'],
                                              init_args={'n_init': 10})
    y_spectralnet, _, _1 = get_y_preds(kmeans_assignments, y,
                                       params['n_clusters'])
    print_accuracy(kmeans_assignments, y, params['n_clusters'])

    from sklearn.metrics import normalized_mutual_info_score as nmi
    nmi_score = nmi(kmeans_assignments, y)
    print('NMI: ' + str(np.round(nmi_score, 3)))

    if params['generalization_metrics']:
        x_spectralnet_train = spectral_net.predict(x_train_unlabeled)
        x_spectralnet_test = spectral_net.predict(x_test)
        km_train = KMeans(
            n_clusters=params['n_clusters']).fit(x_spectralnet_train)
        from scipy.spatial.distance import cdist
        dist_mat = cdist(x_spectralnet_test, km_train.cluster_centers_)
        closest_cluster = np.argmin(dist_mat, axis=1)
        print_accuracy(closest_cluster, y_test, params['n_clusters'],
                       ' generalization')
        nmi_score = nmi(closest_cluster, y_test)
        print('generalization NMI: ' + str(np.round(nmi_score, 3)))

    return x_spectralnet, y_spectralnet