Exemple #1
0
def main():

    dataset_path = "../../Datasets/"  # Specify the dataset path in the Local without the name
    dataset_name = "Vowel"  # Specify the Dataset name without extension (implicitly .mat extension is assumed)
    X_train, Y_train, X_test, Y_test, Q = importData(
        dataset_path,
        dataset_name)  # Imports the data with the no. of output classes
    num_nodes = 5
    #X_train_whole, Y_train_whole = split_training_set(X_train, Y_train, num_nodes)
    X_train_whole, Y_train_whole = split_data_uniform(X_train, Y_train,
                                                      num_nodes)
    # return    X_train_whole[0:4]  and  Y_train_whole[0:4]

    print("***************** Centralized Version *****************")
    pln_cent = train_centralized_networks(X_train, Y_train, X_test, Y_test, Q)
    predicted_lbl_test_cent = pln_cent.compute_test_outputs(X_test)

    print("***************** Decentralized Version *****************")
    pln_decent = train_decentralized_networks(X_train_whole, Y_train_whole,
                                              X_test, Y_test, Q)

    test_acc_consensus = []
    test_nme_consensus = []
    for i in range(num_nodes):
        predicted_lbl_test = pln_decent[i].compute_test_outputs(X_test)
        print("Network No.{}. Test Accuracy:{}\n".format(
            i, compute_accuracy(predicted_lbl_test, Y_test)))
        print("Network No.{}. Test NME:{}\n".format(
            i, compute_NME(predicted_lbl_test, Y_test)))
        test_acc_consensus.append(compute_accuracy(predicted_lbl_test, Y_test))
        test_nme_consensus.append(compute_NME(predicted_lbl_test, Y_test))

    print("**************** Final Results ************************")
    print("Test Accuracy:{}\n".format(
        compute_accuracy(predicted_lbl_test_cent, Y_test)))
    print("Test NME:{}\n".format(compute_NME(predicted_lbl_test_cent, Y_test)))

    print("**************** Final Results ************************")
    print("Mean Test Accuracy (Decentralised):{}".format(
        np.mean(np.array(test_acc_consensus))))
    print("Mean Test NME (Decentralised):{}".format(
        np.mean(np.array(test_nme_consensus))))

    return None
def main():

    ##########################################################################################
    # Dataset related parameters
    dataset_path = "../../Datasets/"  # Specify the dataset path in the Local without the name
    dataset_name = "Vowel"  # Specify the Dataset name without extension (implicitly .mat extension is assumed)
    dataset_1_name = "Vowel"  # Specify the Dataset name without extension (implicitly .mat extension is assumed)
    dataset_2_name = "ExtendedYaleB"

    # Importing parameters for the first Dataset (Old)
    X1_train, Y1_train, X1_test, Y1_test, Q1 = importData(
        dataset_path, dataset_1_name)
    # Importing parameters for the second Dataset (New)
    X2_train, Y2_train, X2_test, Y2_test, Q2 = importData(
        dataset_path, dataset_2_name)

    # Parameters for the First Dataset
    mu1 = 1e3  # For the given dataset
    lambda_ls1 = 1e2  # Given regularization parameter as used in the paper for the used Dataset

    # Parameters for the Second Dataset
    mu2 = 1e3  # For the given dataset
    lambda_ls2 = 1e4  # Given regularization parameter as used in the paper for the used Dataset
    ##########################################################################################

    ##########################################################################################
    # Parameters related to ADMM optimization
    max_iterations = 100  # For the ADMM Algorithm
    no_layers = 1
    ##########################################################################################

    ##########################################################################################

    # Run ADMM Optimization for the first dataset (no LwF)
    print("First Dataset, no LWF")
    PLN_first_dataset, final_test_acc_1, final_test_nme_1, PLN_no_layers_1, Wls_1 = PLN_with_ADMM(X1_train, Y1_train, X1_test, \
                                                                                           Y1_test, no_layers, max_iterations, lambda_ls1, mu1)

    predicted_lbl = compute_test_outputs(PLN_first_dataset, Wls_1, no_layers,
                                         X1_test)  # For the 1st dataset
    print("Final Test Accuracy for T1:{}".format(
        compute_accuracy(predicted_lbl, Y1_test)))

    # Run ADMM Optimization for the second half dataset (no LwF)
    print("Second Dataset, no LWF")
    PLN_second_dataset, final_test_acc_2, final_test_nme_2, PLN_no_layers_2, Wls_2 = PLN_with_ADMM(X2_train, Y2_train, X2_test, \
                                                                                        Y2_test, no_layers, max_iterations, lambda_ls2, mu2)

    predicted_lbl = compute_test_outputs(PLN_second_dataset, Wls_2, no_layers,
                                         X2_test)  # For the 2nd half
    print("Final Test Accuracy for T2:{}".format(
        compute_accuracy(predicted_lbl, Y2_test)))

    # Run ADMM optimizatin for the joint datasets (no LwF)
    X_joint_train, Y_joint_train = compute_joint_datasets(
        X1_train, X2_train, Y1_train, Y2_train)
    X_joint_test, Y_joint_test = compute_joint_datasets(
        X1_test, X2_test, Y1_test, Y2_test)

    mu_jt = 1e3
    lambda_jt = 1e3
    print("Joint Training for Datasets T1 and T2, without LwF")
    PLN_total_datasets, final_test_acc_jt, final_test_nme_jt, PLN_no_layers_jt, Wls_jt = PLN_with_ADMM(X_joint_train, Y_joint_train, X_joint_test, \
                                                                                        Y_joint_test, no_layers, max_iterations, lambda_jt, mu_jt)

    predicted_lbl = compute_test_outputs(PLN_total_datasets, Wls_jt, no_layers,
                                         X_joint_test)  # For the 2nd half
    print("Final Test Accuracy for T1 + T2 (joint):{}".format(
        compute_accuracy(predicted_lbl, Y_joint_test)))

    return None
Exemple #3
0
def main():

    ##########################################################################################
    # Dataset related parameters
    dataset_path = "../../Datasets/" # Specify the dataset path in the Local without the name
    dataset_1_name = "Vowel" # Specify the Dataset name without extension (implicitly .mat extension is assumed)
    dataset_2_name = "ExtendedYaleB"

    # Importing parameters for the first Dataset (Old)
    X1_train, Y1_train, X1_test, Y1_test, Q1 = importData(dataset_path, dataset_1_name) 
    # Importing parameters for the second Dataset (New)
    X2_train, Y2_train, X2_test, Y2_test, Q2 = importData(dataset_path, dataset_2_name) 
    
    # Parameters for the First Dataset
    mu1 = 1e3 # For the given dataset
    lambda_ls1 = 1e2 # Given regularization parameter as used in the paper for the used Dataset

    # Parameters for the Second Dataset
    mu2 = 1e3 # For the given dataset
    lambda_ls2 = 1e4 # Given regularization parameter as used in the paper for the used Dataset
    ##########################################################################################

    ##########################################################################################
    # Parameters related to ADMM optimization and initial values
    max_iterations = 100 # For the ADMM Algorithm   
    no_layers = 1
    lambda_jt_optimal = None
    ##########################################################################################
    
    ###############################################################################################
    # Compute Train and Test accuracy for a Regularized Least Squares Algorithm for the Old Dataset
    ###############################################################################################
    
    # Compute the Wls_1_parameter for the Old Dataset
    Wls_1 = compute_Wls(X1_train, Y1_train, lambda_ls1) 
    acc_train_1, acc_test_1, nme_test_1 = compute_LS_test_accuracy(Wls_1, X1_train, Y1_train, X1_test, Y1_test)
    print("Train and test accuracies for T_old are: {} and {}".format(acc_train_1, acc_test_1))
    print("NME Test for T_old:{}".format(nme_test_1))

    # Compute the Wls_2_parameter for the New Dataset
    Wls_2 = compute_Wls(X2_train, Y2_train, lambda_ls2) 
    acc_train_2, acc_test_2, nme_test_2 = compute_LS_test_accuracy(Wls_2, X2_train, Y2_train, X2_test, Y2_test)
    print("Train and test accuracies for T_new are: {} and {}".format(acc_train_2, acc_test_2))
    print("NME Test for T_new:{}".format(nme_test_2))

    # Performing Joint Training
    X_joint_train, Y_joint_train = compute_joint_datasets(X1_train, X2_train, Y1_train, Y2_train)
    X_joint_test, Y_joint_test = compute_joint_datasets(X1_test, X2_test, Y1_test, Y2_test)
    
    # Finding the optimal lambda 
    lambda_jt_optimal = param_tuning_for_LS(X_joint_train, Y_joint_train, X_joint_test, Y_joint_test)
    print("Chosen value of lambda for Wls for Joint Training:{}".format(lambda_jt_optimal))
    Wls_joint_train = compute_Wls(X_joint_train, Y_joint_train, lambda_jt_optimal) # Find the resulting Wls 
    acc_train_jt, acc_test_jt, nme_test_jt = compute_LS_test_accuracy(Wls_joint_train, X_joint_train, Y_joint_train, X_joint_test, Y_joint_test)
    print("For lambda = {}, Train and test accuracies for Joint Datasets are: {} and {}".format(lambda_jt_optimal, acc_train_jt, acc_test_jt))
    print("NME Test:{}".format(nme_test_jt))
   
    # Untwine the weights
    Wls_1_joint_train, Wls_2_joint_train = untwine_weights(Wls_joint_train, X1_train, Y1_train, X2_train, Y2_train)
     
    # Old task prediction after joint training
    acc_train_1_jt, acc_test_1_jt, nme_test_1_jt = compute_LS_test_accuracy(Wls_1_joint_train, X1_train, Y1_train, X1_test, Y1_test) 
    print("Train and test accuracies for Old task/dataset after Joint Training are: {} and {}".format(acc_train_1_jt, acc_test_1_jt))
    print("NME Test:{}".format(nme_test_1_jt))

    # New task prediction after joint training
    acc_train_2_jt, acc_test_2_jt, nme_test_2_jt = compute_LS_test_accuracy(Wls_2_joint_train, X2_train, Y2_train, X2_test, Y2_test) 
    print("Train and test accuracies for New task/dataset after Joint Training are: {} and {}".format(acc_train_2_jt, acc_test_2_jt))
    print("NME Test:{}".format(nme_test_2_jt))
    
    #################################################################################################
    # Define Params for the LwF based ADMM for Least Squares
    #################################################################################################
    
    ###############################################################################################
    # Compute Train and Test accuracy for a Regularized Least Squares Algorithm for the Old Dataset
    ###############################################################################################
    '''
    # Tuning lambda_o
    mu = 1e2 # Fixing mu  = 100
    lambda_o_vec = np.geomspace(1e-14, 1e14, 29)
    alpha = 2
    
    test_acc_vec = []
    for lambda_o in lambda_o_vec:

        epsilon_o_2 = alpha*np.sqrt(2*Y2_train.shape[0])
        epsilon_o = np.sqrt(lambda_o*np.linalg.norm(Wls_1, 'fro')**2 + (epsilon_o_2)**2) # Somewhat decided based on the norm of W_ls for Vowel and ExtendedYaleB individually, norm for Vowel is 0.3, YaleB is 0.06
        
        Wls_LwF_hat = LwF_based_ADMM_LS_Diff(X2_train, Y2_train, Wls_1, lambda_o, epsilon_o, mu)
        # Joint performance post LwF
        predict_train_total_LwF = np.dot(Wls_LwF_hat, X_joint_train)
        predict_test_total_LwF = np.dot(Wls_LwF_hat, X_joint_test)
        acc_train_jt_LwF = compute_accuracy(predict_train_total_LwF, Y_joint_train)
        acc_test_jt_LwF = compute_accuracy(predict_test_total_LwF, Y_joint_test)
        #nme_test_jt_LwF = compute_NME(predict_test_total_LwF, Y_joint_test)
        print("Train and test accuracies for Joint Datasets after LwF for lambda_o:{} are: {} and {}".format(lambda_o, acc_train_jt_LwF, acc_test_jt_LwF))
        #print("NME Test:{}".format(nme_test_jt_LwF))
        test_acc_vec.append(acc_test_jt_LwF)

    # Plotting the results of the param sweep
    title = "Plotting test accuracy for LwF for LS (Diff dataset)"
    plot_acc_vs_hyperparam(np.log10(lambda_o_vec), test_acc_vec, title)
    lambda_o_jt_optimal = lambda_o_vec[np.argmax(np.array(test_acc_vec))] # Choosing the mu value that gives maximum accuracy
    print("Chosen value of mu for Wls for LwF:{}".format(lambda_o_jt_optimal))
    Wls_LwF_hat = LwF_based_ADMM_LS_Diff(X2_train, Y2_train, Wls_1, lambda_o_jt_optimal, epsilon_o, mu) # Find the resulting Wls 
    predict_train_LwF_total = np.dot(Wls_LwF_hat, X_joint_train)
    predict_test_LwF_total = np.dot(Wls_LwF_hat, X_joint_test)
    acc_train_LwF = compute_accuracy(predict_train_LwF_total, Y_joint_train)
    acc_test_LwF = compute_accuracy(predict_test_LwF_total, Y_joint_test)
    nme_test_LwF = compute_NME(predict_test_LwF_total, Y_joint_test)
    print("For eps = {}, Train and test accuracies for Joint Dataset after LwF are: {} and {}".format(lambda_o_jt_optimal, acc_train_LwF, acc_test_LwF))
    print("NME Test for Joint Dataset after LwF:{}".format(nme_test_LwF))
    

    lambda_o = 1.0/100000 # Forgetting factor  (#TODO: Strange Result)
    alpha = 2
    epsilon_o_2 = alpha*np.sqrt(2*Y2_train.shape[0])
    epsilon_o = np.sqrt(lambda_o*np.linalg.norm(Wls_1, 'fro')**2 + (epsilon_o_2)**2) # Somewhat decided based on the norm of W_ls for Vowel and ExtendedYaleB individually, norm for Vowel is 0.3, YaleB is 0.06
    #mu = 1e6 # Somewhat similar for both datasets Vowel and Extended YaleB (individually) 10^-14 to 10^14
    mu_vec = np.geomspace(1e-14, 1e14, 29) # Sweeping over mu values to find the optimal solution
    test_acc_vec = [] # For LwF
    
    # Tuning mu
    for mu in mu_vec:
        
        Wls_LwF_hat = LwF_based_ADMM_LS_Diff(X2_train, Y2_train, Wls_1, lambda_o, epsilon_o, mu)
        # Joint performance post LwF
        predict_train_total_LwF = np.dot(Wls_LwF_hat, X_joint_train)
        predict_test_total_LwF = np.dot(Wls_LwF_hat, X_joint_test)
        acc_train_jt_LwF = compute_accuracy(predict_train_total_LwF, Y_joint_train)
        acc_test_jt_LwF = compute_accuracy(predict_test_total_LwF, Y_joint_test)
        #nme_test_jt_LwF = compute_NME(predict_test_total_LwF, Y_joint_test)
        print("Train and test accuracies for Joint Datasets after LwF for mu:{} are: {} and {}".format(mu, acc_train_jt_LwF, acc_test_jt_LwF))
        #print("NME Test:{}".format(nme_test_jt_LwF))
        test_acc_vec.append(acc_test_jt_LwF)

    # Plotting the results of the param sweep
    title = "Plotting test accuracy for LwF for LS (Diff dataset)"
    plot_acc_vs_hyperparam(np.log10(mu_vec), test_acc_vec, title)
    
    mu_jt_optimal = mu_vec[np.argmax(np.array(test_acc_vec))] # Choosing the mu value that gives maximum accuracy
    print("Chosen value of mu for Wls for LwF:{}".format(mu_jt_optimal))
    Wls_LwF_hat = LwF_based_ADMM_LS_Diff(X2_train, Y2_train, Wls_1, lambda_o, epsilon_o, mu_jt_optimal) # Find the resulting Wls 
    predict_train_joint_train_total = np.dot(Wls_LwF_hat, X_joint_train)
    predict_test_joint_train_total = np.dot(Wls_LwF_hat, X_joint_test)
    acc_train_jt = compute_accuracy(predict_train_joint_train_total, Y_joint_train)
    acc_test_jt = compute_accuracy(predict_test_joint_train_total, Y_joint_test)
    nme_test_jt = compute_NME(predict_test_joint_train_total, Y_joint_test)
    print("For mu = {}, Train and test accuracies for Joint Dataset after LwF are: {} and {}".format(mu_jt_optimal, acc_train_jt, acc_test_jt))
    print("NME Test for Joint Dataset after LwF:{}".format(nme_test_jt))

    # Untwine weights
    Wls_1_LwF, Wls_2_LwF = untwine_weights(Wls_LwF_hat, X1_train, Y1_train, X2_train, Y2_train)
    Wls_1_LwF = Wls_1_LwF * (1/np.sqrt(lambda_o))

    # Old task prediction after LwF
    
    X1_train_padded = np.concatenate((X1_train, np.zeros((int(X2_train.shape[0] - X1_train.shape[0]), X1_train.shape[1]))),axis=0)
    X1_test_padded = np.concatenate((X1_test, np.zeros((int(X2_train.shape[0] - X1_test.shape[0]), X1_test.shape[1]))),axis=0)
    Y1_train_padded = np.concatenate((Y1_train, np.zeros((int(Y2_train.shape[0]), Y1_train.shape[1]))),axis=0)
    Y1_test_padded = np.concatenate((Y1_test, np.zeros((int(Y2_test.shape[0]), Y1_test.shape[1]))),axis=0)
    
    predict_train_LwF_1 = np.dot(Wls_LwF_hat, X1_train_padded)
    predict_test_LwF_1 = np.dot(Wls_LwF_hat, X1_test_padded)
    acc_train_1_LwF = compute_accuracy(predict_train_LwF_1, Y1_train_padded)
    acc_test_1_LwF = compute_accuracy(predict_test_LwF_1, Y1_test_padded)
    nme_test_1_LwF = compute_NME(predict_test_LwF_1, Y1_test_padded)
    print("Train and test accuracies for Old task/dataset after LwF are: {} and {}".format(acc_train_1_LwF, acc_test_1_LwF))
    print("NME Test:{}".format(nme_test_1_LwF))
    
    
    predict_train_LwF_1 = np.dot(Wls_1_LwF, X1_train)
    predict_test_LwF_1 = np.dot(Wls_1_LwF, X1_test)
    acc_train_1_LwF = compute_accuracy(predict_train_LwF_1, Y1_train)
    acc_test_1_LwF = compute_accuracy(predict_test_LwF_1, Y1_test)
    nme_test_1_LwF = compute_NME(predict_test_LwF_1, Y1_test)
    print("Train and test accuracies for Old task/dataset after LwF are: {} and {}".format(acc_train_1_LwF, acc_test_1_LwF))
    print("NME Test:{}".format(nme_test_1_LwF))

    # New task prediction after LwF
    
    #X2_train_padded = np.concatenate((np.zeros((int(X2_train.shape[0] - X1_train.shape[0]), X1_train.shape[1])), X2_train),axis=0)
    #X2_test_padded = np.concatenate((X1_test, np.zeros((int(X2_train.shape[0] - X1_test.shape[0]), X1_test.shape[1]))),axis=0)
    Y2_train_padded = np.concatenate((np.zeros((int(Y1_train.shape[0]), Y2_train.shape[1])), Y2_train),axis=0)
    Y2_test_padded = np.concatenate((np.zeros((int(Y1_test.shape[0]), Y2_test.shape[1])), Y2_test),axis=0)

    predict_train_LwF_2 = np.dot(Wls_LwF_hat, X2_train)
    predict_test_LwF_2 = np.dot(Wls_LwF_hat, X2_test)
    acc_train_2_LwF = compute_accuracy(predict_train_LwF_2, Y2_train_padded)
    acc_test_2_LwF = compute_accuracy(predict_test_LwF_2, Y2_test_padded)
    nme_test_2_LwF = compute_NME(predict_test_LwF_2, Y2_test_padded)
    print("Train and test accuracies for New task/dataset after LwF are: {} and {}".format(acc_train_2_LwF, acc_test_2_LwF))
    print("NME Test:{}".format(nme_test_2_LwF))
    
    predict_train_LwF_2 = np.dot(Wls_2_LwF, X2_train)
    predict_test_LwF_2 = np.dot(Wls_2_LwF, X2_test)
    acc_train_2_LwF = compute_accuracy(predict_train_LwF_2, Y2_train)
    acc_test_2_LwF = compute_accuracy(predict_test_LwF_2, Y2_test)
    nme_test_2_LwF = compute_NME(predict_test_LwF_2, Y2_test)
    print("Train and test accuracies for Old task/dataset after LwF are: {} and {}".format(acc_train_2_LwF, acc_test_2_LwF))
    print("NME Test:{}".format(nme_test_2_LwF))

    
    # Tuning epsilon_o
    mu = 1e3
    epsilon_o_vec = np.geomspace(1e-6, 3, 100)
    test_acc_vec = []
    for epsilon_o in epsilon_o_vec:
        
        Wls_LwF_hat = LwF_based_ADMM_LS_Diff(X2_train, Y2_train, Wls_1, lambda_o, epsilon_o, mu)
        # Joint performance post LwF
        predict_train_total_LwF = np.dot(Wls_LwF_hat, X_joint_train)
        predict_test_total_LwF = np.dot(Wls_LwF_hat, X_joint_test)
        acc_train_jt_LwF = compute_accuracy(predict_train_total_LwF, Y_joint_train)
        acc_test_jt_LwF = compute_accuracy(predict_test_total_LwF, Y_joint_test)
        #nme_test_jt_LwF = compute_NME(predict_test_total_LwF, Y_joint_test)
        print("Train and test accuracies for Joint Datasets after LwF for eps:{} are: {} and {}".format(epsilon_o, acc_train_jt_LwF, acc_test_jt_LwF))
        #print("NME Test:{}".format(nme_test_jt_LwF))
        test_acc_vec.append(acc_test_jt_LwF)

    # Plotting the results of the param sweep
    title = "Plotting test accuracy for LwF for LS (Diff dataset)"
    plot_acc_vs_hyperparam(np.log10(epsilon_o_vec), test_acc_vec, title)
    epsilon_o_jt_optimal = epsilon_o_vec[np.argmax(np.array(test_acc_vec))] # Choosing the mu value that gives maximum accuracy
    print("Chosen value of mu for Wls for LwF:{}".format(epsilon_o_jt_optimal))
    Wls_LwF_hat = LwF_based_ADMM_LS_Diff(X2_train, Y2_train, Wls_1, lambda_o, epsilon_o_jt_optimal, mu) # Find the resulting Wls 
    predict_train_joint_train_total = np.dot(Wls_LwF_hat, X_joint_train)
    predict_test_joint_train_total = np.dot(Wls_LwF_hat, X_joint_test)
    acc_train_jt = compute_accuracy(predict_train_joint_train_total, Y_joint_train)
    acc_test_jt = compute_accuracy(predict_test_joint_train_total, Y_joint_test)
    nme_test_jt = compute_NME(predict_test_joint_train_total, Y_joint_test)
    print("For eps = {}, Train and test accuracies for Joint Dataset after LwF are: {} and {}".format(epsilon_o_jt_optimal, acc_train_jt, acc_test_jt))
    print("NME Test for Joint Dataset after LwF:{}".format(nme_test_jt))
    '''
    
    return None
Exemple #4
0
def main():

    ##########################################################################################
    # Dataset related parameters
    dataset_path = "../Datasets/" # Specify the dataset path in the Local without the name
    dataset_name = "Vowel" # Specify the Dataset name without extension (implicitly .mat extension is assumed)
    X_train, Y_train, X_test, Y_test, Q = importData(dataset_path, dataset_name) # Imports the data with the no. of output classes
    
    mu = 1e3 # For the given dataset
    lambda_ls = 1e2 # Given regularization parameter as used in the paper for the used Dataset
    ##########################################################################################

    ##########################################################################################
    # Parameters related to ADMM optimization
    max_iterations = 100 # For the ADMM Algorithm
    ##########################################################################################

    ##########################################################################################
    # Compute Train and Test accuracy for a Regularized Least Squares Algorithm
    ##########################################################################################
    Wls = compute_Wls(X_train, Y_train, lambda_ls) 
    predict_train = np.dot(Wls, X_train)
    predict_test = np.dot(Wls, X_test)
    acc_train = compute_accuracy(predict_train, Y_train)
    acc_test = compute_accuracy(predict_test, Y_test)
    nme_test = compute_NME(predict_test, Y_test)
    print("Train and test accuracies are: {} and {}".format(acc_train, acc_test))
    print("NME Test:{}".format(nme_test))

    ##########################################################################################
    # Creating a list of PLN Objects
    ##########################################################################################
    
    PLN_objects = [] # The network is to be stored as a list of objects, with each object 
                     # representing a network layer
    no_layers = 20 # Total number of layers to be used

    # Creating a 1 layer Network
    
    num_class = Y_train.shape[0] # Number of classes in the given network
    num_node = 2*num_class + 1000 # Number of nodes in every layer (fixed in this case)
    layer_no = 0 # Layer Number/Index (0 to L-1)

    # Create an object of PLN Class
    pln_l1 = PLN(Q, X_train, layer_no, num_node, W_ls = Wls) 
    
    # Compute the top part of the Composite Weight Matrix
    W_top = np.dot(np.dot(pln_l1 .V_Q, Wls), X_train)

    # Compute the Bottom part of the Composite Weight Matrix and inner product with input, along with including normalization
    W_bottom = pln_l1.normalization(np.dot(pln_l1.R_l, X_train)) # Normalization performed is for the random matrix

    # Concatenating the outputs to form W*X 
    pln_l1_Z_l = np.concatenate((W_top, W_bottom), axis=0)

    # Then applying the activation function g(.)
    pln_l1.Y_l = pln_l1.activation_function(pln_l1_Z_l) 

    # Computing the Output Matrix by using 100 iterations of ADMM
    print("ADMM for Layer No:{}".format(1))
    pln_l1.O_l = compute_ol(pln_l1.Y_l, Y_train, mu, max_iterations)

    # Appending the creating object for every layer to a list, which constitutes the 'network' 
    PLN_objects.append(pln_l1)
    
    predicted_lbl_test = compute_test_outputs(PLN_objects, Wls, 1, X_test)
    predicted_lbl_train = compute_test_outputs(PLN_objects, Wls, 1, X_train)
    print("Training Accuracy:{}".format(compute_accuracy(predicted_lbl_train, Y_train)))
    print("Test Accuracy:{}".format(compute_accuracy(predicted_lbl_test, Y_test)))
    print("Traning NME:{}".format(compute_NME(predicted_lbl_train, Y_train)))
    print("Test NME:{}".format(compute_NME(predicted_lbl_test, Y_test)))

    # ADMM Training for all the remaining layers using the training Data
    # Also involves subsequent testing on the test data
    
    for i in range(1, no_layers):

        print("************** ADMM for Layer No:{} **************".format(i+1))

        X = PLN_objects[i-1].Y_l # Input is the Output g(WX) for the previous layer
        num_node = 2*Q + 1000 # No. of nodes fixed for every layer
        pln = PLN(Q, X, i, num_node, W_ls=None) # Creating the PLN Object for the new layer

        # Compute the top part of the Composite Weight Matrix
        W_top = np.dot(np.dot(pln.V_Q,PLN_objects[i-1].O_l), X)

        # Compute the bottom part of the Composite Weight Matrix
        W_bottom = pln.normalization(np.dot(pln.R_l, X))

        # Concatenate the top and bottom part of the matrix
        pln_Z_l = np.concatenate((W_top, W_bottom), axis=0)

        # Apply the activation function
        pln.Y_l = pln.activation_function(pln_Z_l) 

        # Compute the output matrix using ADMM for specified no. of iterations
        pln.O_l = compute_ol(pln.Y_l, Y_train, mu, max_iterations)

        # Add the new layer to the 'Network' list
        PLN_objects.append(pln)

        # Compute training, test accuracy, NME for new appended networks
        predicted_lbl_test = compute_test_outputs(PLN_objects, Wls, i+1, X_test)
        predicted_lbl_train = compute_test_outputs(PLN_objects, Wls, i+1, X_train)
        print("Training Accuracy:{}\n".format(compute_accuracy(predicted_lbl_train, Y_train)))
        print("Test Accuracy:{}\n".format(compute_accuracy(predicted_lbl_test, Y_test)))
        print("Traning NME:{}\n".format(compute_NME(predicted_lbl_train, Y_train)))
        print("Test NME:{}\n".format(compute_NME(predicted_lbl_test, Y_test)))
        
    #predicted_lbl = compute_test_outputs(PLN_objects, Wls, no_layers, X_test)
    #print("Test Accuracy:{}".format(compute_accuracy(predicted_lbl, Y_test)))
    return None
Exemple #5
0
def main():

    dataset_path = ""  # Specify the dataset path in the Local without the name
    dataset_name = "Vowel"  # Specify the Dataset name without extension (implicitly .mat extension is assumed)
    X_train, Y_train, X_test, Y_test, Q = importData(
        dataset_path,
        dataset_name)  # Imports the data with the no. of output classes
    num_nodes = 5
    X_train_old, X_train_new, Y_train_old, Y_train_new = train_test_split(
        X_train.T, Y_train.T, train_size=1.0 / 2)
    X_train_old = X_train_old.T
    X_train_new = X_train_new.T
    Y_train_old = Y_train_old.T
    Y_train_new = Y_train_new.T
    #X_train_whole = []
    X_train_whole, Y_train_whole = split_training_set(X_train, Y_train,
                                                      num_nodes)
    #X_train_whole, Y_train_whole = split_data_uniform(X_train, Y_train, num_nodes)
    X_train_old_whole, Y_train_old_whole = split_data_uniform(
        X_train_old, Y_train_old, num_nodes)
    X_train_new_whole, Y_train_new_whole = split_data_uniform(
        X_train_new, Y_train_new, num_nodes)

    # return    X_train_whole[0:4]  and  Y_train_whole[0:4]
    ## split the dataset into old and new
    #data_old_list, data_new_list,label_old_list,label_new_list = split_data_old_new(X_train_whole,Y_train_whole)
    num_class = Y_train.shape[0]
    forgetting_factor = 1
    mu = 1e-1
    print("***************** Centralized Version *****************")
    pln_cent = train_centralized_networks(X_train, Y_train, X_test, Y_test, Q)
    predicted_lbl_test_cent = pln_cent.compute_test_outputs(X_test)

    test_acc_consensus = []
    test_nme_consensus = []
    print("***************** Decentralized Version *****************")
    ########################################################## the first line is for joint training
    pln_decent = train_decentralized_networks(X_train_whole, Y_train_whole,
                                              X_test, Y_test, Q)
    for i in range(num_nodes):
        predicted_lbl_test = pln_decent[i].compute_test_outputs(X_test)
        print("Network No.{}. Test Accuracy:{}\n".format(
            i, compute_accuracy(predicted_lbl_test, Y_test)))
        print("Network No.{}. Test NME:{}\n".format(
            i, compute_NME(predicted_lbl_test, Y_test)))
        test_acc_consensus.append(compute_accuracy(predicted_lbl_test, Y_test))
        test_nme_consensus.append(compute_NME(predicted_lbl_test, Y_test))
    ########################################################## the second line is for old dataset
    pln_decent_lwf_old = train_decentralized_networks(X_train_old_whole,
                                                      Y_train_old_whole,
                                                      X_test, Y_test, Q)
    ##################### parameter tunning
    mu_vec = np.geomspace(1e-14, 1e14, 29)
    test_acc_consensus_lwf_old = []
    test_nme_consensus_lwf_old = []
    test_acc_new_mu = np.zeros((1, 29))
    test_acc_old_mu = np.zeros((1, 29))
    count = 0
    mu_ls = 1e-1
    for mu in mu_vec:
        pln_decent_lwf_new = train_decentralized_networks_lwf(
            forgetting_factor, mu_ls, mu, pln_decent_lwf_old,
            X_train_new_whole, Y_train_new_whole, X_test, Y_test, Q)
        test_acc_consensus_lwf_new = []
        test_nme_consensus_lwf_new = []
        ### for lwf new
        for i in range(num_nodes):
            predicted_lbl_test_lwf_new = pln_decent_lwf_new[
                i].compute_test_outputs(X_test)
            print("Network No.{}. Test Accuracy:{}\n".format(
                i, compute_accuracy(predicted_lbl_test_lwf_new, Y_test)))
            print("Network No.{}. Test NME:{}\n".format(
                i, compute_NME(predicted_lbl_test_lwf_new, Y_test)))
            test_acc_consensus_lwf_new.append(
                compute_accuracy(predicted_lbl_test_lwf_new, Y_test))
            test_nme_consensus_lwf_new.append(
                compute_NME(predicted_lbl_test_lwf_new, Y_test))
            ### for lwf old
            predicted_lbl_test_lwf_old = pln_decent_lwf_old[
                i].compute_test_outputs(X_test)
            print("Network No.{}. Test Accuracy:{}\n".format(
                i, compute_accuracy(predicted_lbl_test_lwf_old, Y_test)))
            print("Network No.{}. Test NME:{}\n".format(
                i, compute_NME(predicted_lbl_test_lwf_old, Y_test)))
            test_acc_consensus_lwf_old.append(
                compute_accuracy(predicted_lbl_test_lwf_old, Y_test))
            test_nme_consensus_lwf_old.append(
                compute_NME(predicted_lbl_test_lwf_old, Y_test))
        print("**************** Final Results ************************")
        print("Test Accuracy:{}\n".format(
            compute_accuracy(predicted_lbl_test_cent, Y_test)))
        print("Test NME:{}\n".format(
            compute_NME(predicted_lbl_test_cent, Y_test)))

        print("**************** Final Results ************************")
        print("Mean Test Accuracy (Decentralised):{}".format(
            np.mean(np.array(test_acc_consensus))))
        print("Mean Test NME (Decentralised):{}".format(
            np.mean(np.array(test_nme_consensus))))
        print("Mean Test Accuracy (Decentralised_lwf_new):{}".format(
            np.mean(np.array(test_acc_consensus_lwf_new))))
        print("Mean Test NME (Decentralised_lwf_new):{}".format(
            np.mean(np.array(test_nme_consensus_lwf_new))))
        print("Mean Test Accuracy (Decentralised_lwf_old):{}".format(
            np.mean(np.array(test_acc_consensus_lwf_old))))
        print("Mean Test NME (Decentralised_lwf_old):{}".format(
            np.mean(np.array(test_nme_consensus_lwf_old))))
        test_acc_new_mu[0,
                        count] = np.mean(np.array(test_acc_consensus_lwf_new))
        test_acc_old_mu[0,
                        count] = np.mean(np.array(test_acc_consensus_lwf_old))
        count += 1
    test_acc_new_mu_pd = pd.DataFrame(test_acc_new_mu)
    test_acc_new_mu_pd.to_csv('tess_acc_new_mu.csv', index=None)
    position = np.argmax(test_acc_new_mu, axis=1)
    max_value = np.max(test_acc_new_mu, axis=1)
    print('the maximum accuracy after lwf is:')
    print(max_value)
    print('the maximum position is:')
    print(mu_vec[position])
    #test_acc_old_mu_pd = pd.DataFrame(test_acc_old_mu)
    #test_acc_old_mu_pd.to_csv('tess_acc_old_mu.csv',index=None)
    return None
def main():

    ##########################################################################################
    # Dataset related parameters
    dataset_path = "../../Datasets/"  # Specify the dataset path in the Local without the name
    dataset_1_name = "Vowel"  # Specify the Dataset name without extension (implicitly .mat extension is assumed)
    dataset_2_name = "ExtendedYaleB"

    X_train, Y_train, X_test, Y_test, Q = importData(dataset_path,
                                                     dataset_1_name)

    X1_Y1_train_indices = np.argmax(Y_train, axis=0) < int(
        Y_train.shape[0] / 2)
    X2_Y2_train_indices = ~X1_Y1_train_indices

    X1_train = X_train[:, X1_Y1_train_indices]
    Y1_train = Y_train[:, X1_Y1_train_indices]

    X2_train = X_train[:, X2_Y2_train_indices]
    Y2_train = Y_train[:, X2_Y2_train_indices]

    X1_Y1_test_indices = np.argmax(Y_test, axis=0) < int(Y_test.shape[0] / 2)
    X2_Y2_test_indices = ~X1_Y1_test_indices

    X1_test = X_test[:, X1_Y1_test_indices]
    Y1_test = Y_test[:, X1_Y1_test_indices]

    X2_test = X_test[:, X2_Y2_test_indices]
    Y2_test = Y_test[:, X2_Y2_test_indices]

    Q1 = Y1_train.shape[0]
    Q2 = Y2_train.shape[0]

    # Importing parameters for the first Dataset (Old)
    #X1_train, Y1_train, X1_test, Y1_test, Q1 = importData(dataset_path, dataset_1_name)
    # Importing parameters for the second Dataset (New)
    #X2_train, Y2_train, X2_test, Y2_test, Q2 = importData(dataset_path, dataset_2_name)

    # Parameters for the First Dataset
    #mu1 = 1e3 # For the given dataset
    #lambda_ls1 = 1e2 # Given regularization parameter as used in the paper for the used Dataset

    # Parameters for the Second Dataset
    #mu2 = 1e3 # For the given dataset
    #lambda_ls2 = 1e4 # Given regularization parameter as used in the paper for the used Dataset

    mu1 = 1e3  # For the given dataset
    lambda_ls1 = 1e2  # Given regularization parameter as used in the paper for the used Dataset
    mu2 = 1e3  # For the given dataset
    lambda_ls2 = 1e2  # Given regularization parameter as used in the paper for the used Dataset
    ##########################################################################################

    ##########################################################################################
    # Parameters related to ADMM optimization and initial values
    max_iterations = 100  # For the ADMM Algorithm
    no_layers = 20
    alpha = 2
    ###############################################################################################
    # Compute Train and Test accuracy for an ADMM based Algorithm for the Old Dataset
    ###############################################################################################

    # Run ADMM Optimization for the first dataset (no LwF)
    print("First Dataset, no LWF")
    PLN_first_dataset, final_test_acc_1, final_test_nme_1, Wls_1 = PLN_with_ADMM(X1_train, Y1_train, X1_test, Y1_test, \
                                                                                                  no_layers, max_iterations, lambda_ls1, mu1, LwF_flag=False,\
                                                                                                  O_l_prev_array=None, W_ls_prev=None, mu_layers_LwF=None)
    eps1_Wls = np.linalg.norm(Wls_1, ord='fro')**2
    print("Eps_1 for Least Squares for first dataset: {}".format(eps1_Wls))
    #eps1_o = np.linalg.norm(PLN_first_dataset[0].O_l, ord='fro')**2
    eps1_o = (
        alpha * np.sqrt(2 * Q1)
    )**2  # Actually squared here, because Square root is applied in ADMM projection for LwF
    print("Eps_1 for Layers for first dataset: {}".format(eps1_o))
    predicted_lbl = compute_test_outputs(PLN_first_dataset, Wls_1, no_layers,
                                         X1_test)  # For the 1st dataset
    print("Final Test Accuracy for T1:{}".format(
        compute_accuracy(predicted_lbl, Y1_test)))

    # Run ADMM Optimization for the second half dataset (no LwF)
    print("Second Dataset, no LWF")
    PLN_second_dataset, final_test_acc_2, final_test_nme_2, Wls_2 = PLN_with_ADMM(X2_train, Y2_train, X2_test, Y2_test, \
                                                                                                  no_layers, max_iterations, lambda_ls2, mu2, LwF_flag=False,\
                                                                                                  O_l_prev_array=None, W_ls_prev=None, mu_layers_LwF=None)
    eps2_Wls = np.linalg.norm(Wls_2, ord='fro')**2
    print("Eps_2 for Least Squares for second dataset: {}".format(eps2_Wls))
    #eps2_o = np.linalg.norm(PLN_second_dataset[0].O_l, ord='fro')**2
    eps2_o = (
        alpha * np.sqrt(2 * Q2)
    )**2  # Actually squared here, because Square root is applied in ADMM projection for LwF
    print("Eps_2 for Layers for second dataset: {}".format(eps2_o))
    predicted_lbl = compute_test_outputs(PLN_second_dataset, Wls_2, no_layers,
                                         X2_test)  # For the 1st dataset
    print("Final Test Accuracy for T2:{}".format(
        compute_accuracy(predicted_lbl, Y2_test)))

    # Run ADMM optimizatin for the joint datasets (no LwF)

    global X_joint_train, X_joint_test, Y_joint_train, Y_joint_test

    X_joint_train, Y_joint_train = compute_joint_datasets(
        X1_train, X2_train, Y1_train, Y2_train)
    X_joint_test, Y_joint_test = compute_joint_datasets(
        X1_test, X2_test, Y1_test, Y2_test)

    mu_jt = None
    lambda_jt = None
    print("Joint Training for Datasets T1 and T2, without LwF")
    PLN_total_datasets, final_test_acc_jt, final_test_nme_jt, Wls_jt = PLN_with_ADMM(X_joint_train, Y_joint_train, X_joint_test, \
                                                                                        Y_joint_test, no_layers, max_iterations, lambda_jt, mu_jt, \
                                                                                        LwF_flag=False, O_l_prev_array=None, W_ls_prev=None, mu_layers_LwF=None)

    predicted_lbl = compute_test_outputs(PLN_total_datasets, Wls_jt, no_layers,
                                         X_joint_test)  # For the 2nd half
    print("Final Test Accuracy for T1 + T2 (joint):{}".format(
        compute_accuracy(predicted_lbl, Y_joint_test)))

    # Run ADMM Optimization for the first dataset (no LwF)
    print("First Dataset, no LWF, after joint training")
    P = max(X1_test.shape[0], X2_test.shape[0])
    Q = predicted_lbl.shape[0]

    #global X1_test_append, Y1_test_append, X2_test_append, Y2_test_append

    if X1_test.shape[0] < P:
        X1_test_append = np.concatenate(
            (X1_test, np.zeros((P - X1_test.shape[0], X1_test.shape[1]))),
            axis=0)
        X1_test_append = np.concatenate(
            (X1_test_append,
             np.zeros((X1_test_append.shape[0], X2_test.shape[1]))),
            axis=1)
    else:
        X1_test_append = copy.deepcopy(X1_test)
        X1_test_append = np.concatenate(
            (X1_test_append,
             np.zeros((X1_test_append.shape[0], X2_test.shape[1]))),
            axis=1)

    predicted_lbl_1 = compute_test_outputs(
        PLN_total_datasets, Wls_jt, no_layers,
        X1_test_append)  # For the Old dataset

    if Y1_test.shape[0] <= (Q // 2):
        Y1_test_append = np.concatenate(
            (Y1_test, np.zeros((Q - Y1_test.shape[0], Y1_test.shape[1]))),
            axis=0)
        Y1_test_append = np.concatenate(
            (Y1_test_append,
             np.zeros((Y1_test_append.shape[0], Y2_test.shape[1]))),
            axis=1)
    else:
        Y1_test_append = np.concatenate((np.zeros(
            (Q - Y1_test.shape[0], Y1_test.shape[1])), Y1_test),
                                        axis=0)
        Y1_test_append = np.concatenate((np.zeros(
            (Y1_test_append.shape[0], Y2_test.shape[1])), Y1_test_append),
                                        axis=1)

    print("Final Test Accuracy for T1 (after joint):{}".format(
        compute_accuracy(predicted_lbl_1, Y1_test_append)))

    # Run ADMM Optimization for the second half dataset (no LwF)
    print("Second Dataset, no LWF, after joint training")

    if X2_test.shape[0] < P:
        X2_test_append = np.concatenate(
            (X2_test, np.zeros((P - X2_test.shape[0], X2_test.shape[1]))),
            axis=0)
        X2_test_append = np.concatenate((np.zeros(
            (X2_test_append.shape[0], X1_test.shape[1])), X2_test_append),
                                        axis=1)
    else:
        X2_test_append = copy.deepcopy(X2_test)
        X2_test_append = np.concatenate((np.zeros(
            (X2_test_append.shape[0], X1_test.shape[1])), X2_test_append),
                                        axis=1)

    predicted_lbl_2 = compute_test_outputs(
        PLN_total_datasets, Wls_jt, no_layers,
        X2_test_append)  # For the New dataset

    if Y2_test.shape[0] < (Q // 2):
        Y2_test_append = np.concatenate(
            (Y2_test, np.zeros((Q - Y2_test.shape[0], Y2_test.shape[1]))),
            axis=0)
        Y2_test_append = np.concatenate(
            (Y2_test_append,
             np.zeros((Y2_test_append.shape[0], Y1_test.shape[1]))),
            axis=1)
    else:
        Y2_test_append = np.concatenate((np.zeros(
            (Q - Y2_test.shape[0], Y2_test.shape[1])), Y2_test),
                                        axis=0)
        Y2_test_append = np.concatenate((np.zeros(
            (Y2_test_append.shape[0], Y1_test.shape[1])), Y2_test_append),
                                        axis=1)

    print("Final Test Accuracy for T2 (after joint):{}".format(
        compute_accuracy(predicted_lbl_2, Y2_test_append)))

    #################################### Applying LwF ######################################

    print("Joint Training for Datasets T1 and T2, after LwF")
    lambda_o = 1  # Initial Guess for Lambda
    lambda_jt_LwF = None
    mu_jt_LwF = None
    epsilon_o_Wls = lambda_o * eps1_Wls + eps2_Wls  # Epsilon value for LS
    print("Eps for LS for T1+T2:{}".format(epsilon_o_Wls))
    epsilon_o = lambda_o * eps1_o + eps2_o  # Epsilon value for O1
    print("Eps for O_l for T1+T2:{}".format(epsilon_o))
    PLN_total_datasets_LwF, final_test_acc_jt_LwF, final_test_nme_jt_LwF, Wls_jt_LwF, lambda_o, lambda_ls =  PLN_with_ADMM(X2_train, Y2_train, X2_test, Y2_test, no_layers,\
                                                                                                      max_iterations, lambda_jt_LwF, mu_jt_LwF, LwF_flag=True,\
                                                                                                      O_l_prev_array=PLN_first_dataset, W_ls_prev=Wls_1, \
                                                                                                      mu_layers_LwF=None, eps_Wls=epsilon_o_Wls, eps_o=epsilon_o, \
                                                                                                      eps_o_1 = eps1_o, eps_o_2 = eps2_o, eps_Wls_1 = eps1_Wls, eps_Wls_2 = eps2_Wls)
    # Check the Joint test accuracy after LwF (baseline : Joint training + joint testing)
    predicted_lbl = compute_test_outputs(PLN_total_datasets_LwF, Wls_jt_LwF,
                                         no_layers,
                                         X_joint_test)  # For the 2nd half
    print("Final Test Accuracy for T1 + T2 (after LwF):{}".format(
        compute_accuracy(predicted_lbl, Y_joint_test)))

    # Check the individual accuracy after LwF of Old Dataset (baseline: Individual testing without LwF?)
    print("First Dataset, after LwF")
    predicted_lbl_1_LwF = compute_test_outputs(
        PLN_total_datasets_LwF, Wls_jt_LwF, no_layers,
        X1_test_append)  # For the Old dataset
    print("Final Test Accuracy for T1 (after joint):{}".format(
        compute_accuracy(predicted_lbl_1_LwF, Y1_test_append)))

    # Check the individual accuracy after LwF of Second Dataset (baseline: Individual testing without LwF?)
    print("Second Dataset, no LWF, after joint training")
    predicted_lbl_2_LwF = compute_test_outputs(
        PLN_total_datasets_LwF, Wls_jt_LwF, no_layers,
        X2_test_append)  # For the New dataset
    print("Final Test Accuracy for T2 (after joint):{}".format(
        compute_accuracy(predicted_lbl_2_LwF, Y2_test_append)))

    return None
def main():

    ##########################################################################################
    # Dataset related parameters
    dataset_path = "../../Datasets/"  # Specify the dataset path in the Local without the name
    dataset_name = "Vowel"  # Specify the Dataset name without extension (implicitly .mat extension is assumed)
    X_train, Y_train, X_test, Y_test, Q = importData(
        dataset_path,
        dataset_name)  # Imports the data with the no. of output classes

    mu = 1e3  # For the given dataset
    lambda_ls = 1e2  # Given regularization parameter as used in the paper for the used Dataset
    no_layers = 20  # Total number of layers to be used (fixed by default)
    print("Dataset Used: {}, No. of layers:{}".format(dataset_name, no_layers))

    ##########################################################################################
    # Splits the data randomly into two disjoint datasets (by default random_split% = 0.5)
    X_train_1, X_train_2, Y_train_1, Y_train_2 = splitdatarandom(
        X_train,
        Y_train)  # Dataset T_old: X_train_1, Y_train_1, X_test_1, Y_test_1
    X_test_1, X_test_2, Y_test_1, Y_test_2 = splitdatarandom(
        X_test,
        Y_test)  # Dataset T_new: X_train_2, Y_train_2, X_test_2, Y_test_2
    print("Data has been split")

    ##########################################################################################
    # Parameters related to ADMM optimization
    max_iterations = 100  # For the ADMM Algorithm
    ##########################################################################################

    ##########################################################################################
    # Run ADMM Optimization for the whole dataset to get a baseline
    print("Baseline : Total Dataset")
    PLN_total_dataset, final_test_acc_bl, final_test_nme_bl, PLN_no_layers, Wls_total_dataset = PLN_with_ADMM(X_train, Y_train, X_test, \
                                                                                           Y_test,  no_layers, max_iterations, lambda_ls, mu)
    predicted_lbl = compute_test_outputs(PLN_total_dataset, Wls_total_dataset,
                                         no_layers,
                                         X_test)  # For the entire network
    print("Final Test Accuracy on T1 + T2:{}".format(
        compute_accuracy(predicted_lbl, Y_test)))

    #for _ in range(10):

    # Run ADMM Optimization for the first half dataset (no LwF)
    print("First Dataset, no LWF")
    PLN_first_dataset, final_test_acc_1, final_test_nme_1, PLN_no_layers_1, Wls_1 = PLN_with_ADMM(X_train_1, Y_train_1, X_test_1, \
                                                                                           Y_test_1, no_layers, max_iterations, lambda_ls, mu)

    predicted_lbl = compute_test_outputs(PLN_first_dataset, Wls_1, no_layers,
                                         X_test_1)  # For the 1st half
    print("Final Test Accuracy for T1:{}".format(
        compute_accuracy(predicted_lbl, Y_test_1)))

    # Run ADMM Optimization for the second half dataset (no LwF)
    print("Second Dataset, no LWF")
    PLN_second_dataset, final_test_acc_2, final_test_nme_2, PLN_no_layers_2, Wls_2 = PLN_with_ADMM(X_train_2, Y_train_2, X_test_2, \
                                                                                        Y_test_2, no_layers, max_iterations, lambda_ls, mu)

    predicted_lbl = compute_test_outputs(PLN_second_dataset, Wls_2, no_layers,
                                         X_test_2)  # For the 2nd half
    print("Final Test Accuracy for T2:{}".format(
        compute_accuracy(predicted_lbl, Y_test_2)))

    # Run ADMM Optimization for the second half dataset (no LwF)
    print("Implemeting LWF on Second Dataset, learned First Dataset")
    PLN_LwF_dataset, final_test_acc_LwF, final_test_nme_LwF, PLN_no_layers_LwF, Wls_LWF = PLN_with_ADMM(X_train_2, Y_train_2, X_test_2, Y_test_2,\
                                                            no_layers, max_iterations, lambda_ls, mu, O_prev_array=PLN_first_dataset,\
                                                            flag=True, W_ls_prev=Wls_1, Sweep=True, mu_Layers_LwF=None)

    predicted_lbl_2 = compute_test_outputs(PLN_LwF_dataset, Wls_LWF, no_layers,
                                           X_test_2)  # For the 2nd half
    print("Final Test Accuracy for T2:{}".format(
        compute_accuracy(predicted_lbl_2, Y_test_2)))

    predicted_lbl_1 = compute_test_outputs(PLN_LwF_dataset, Wls_LWF, no_layers,
                                           X_test_1)  # For the 1st half
    print("Final Test Accuracy for T1:{}".format(
        compute_accuracy(predicted_lbl_1, Y_test_1)))

    predicted_lbl = compute_test_outputs(PLN_LwF_dataset, Wls_LWF, no_layers,
                                         X_test)  # For the Complete Dataset
    print("Final Test Accuracy on T1 + T2:{}".format(
        compute_accuracy(predicted_lbl, Y_test)))

    return None