Example #1
0
def main(index_exp=0):

    dirName = '%s_%s_data%d_%s' % (args.ext_model, args.rgr_model,
                                   args.data_cate, args.append_name)
    fileName = '%s_exp%d' % (dirName, index_exp)

    # Create folder for results of this model
    if not os.path.exists('./results/%s' % (dirName)):
        os.makedirs('./results/%s' % (dirName))

    print('Extraction model: %s' % (args.ext_model))
    print('Regression model: %s' % (args.rgr_model))

    if args.ext_model == 'vgg16':
        net = tv_models.vgg16(pretrained=True).to(device=device)
        set_parameter_requires_grad(net, True)
        net.classifier[6] = Identity()
    elif args.ext_model == 'resnet50':
        net = tv_models.resnet50(pretrained=True).to(device=device)
        set_parameter_requires_grad(net, True)
        net.fc = Identity()

    # Get dataset
    batchSize = 64
    input_size = 224
    # Load Data
    data_transforms = {
        'train': transforms.Compose([ndl.Rescale(input_size),
                                     ndl.ToTensor()]),
        'test': transforms.Compose([ndl.Rescale(input_size),
                                    ndl.ToTensor()])
    }

    print("Initializing Datasets and Dataloaders...")

    # Create training and testing datasets
    image_datasets = {
        x: ndl.TopoplotLoader(args.image_folder,
                              x,
                              transform=data_transforms[x],
                              index_exp=index_exp)
        for x in ['train', 'test']
    }

    # Create training and testing dataloaders
    dataloaders_dict = {
        'train':
        Data.DataLoader(image_datasets['train'],
                        batch_size=batchSize,
                        shuffle=False,
                        num_workers=4),
        'test':
        Data.DataLoader(image_datasets['test'],
                        batch_size=batchSize,
                        shuffle=False,
                        num_workers=4)
    }

    # Extract features by VGG16
    net.eval()  # Disable batchnorm, dropout
    X_train, Y_train = extract_layer(dataloaders_dict['train'], net)
    X_test, Y_test = extract_layer(dataloaders_dict['test'], net)

    # Standardize data before PCA
    if args.scale:
        X_train, X_test = preprocessing.scale(X_train, X_test, mode=args.scale)

    # Apply PCA to reduce dimension
    if args.n_components > 1:
        args.n_components = int(args.n_components)
    pca = PCA(n_components=args.n_components, svd_solver='full')
    pca.fit(X_train)

    X_train = pca.transform(X_train)
    X_test = pca.transform(X_test)
    print('(X) Number of features after PCA: %d' % (X_train.shape[1]))
    print('(X) Explained variance ratio: %.3f' %
          (np.sum(pca.explained_variance_ratio_)))

    # Add conditional entropy
    if args.add_CE and args.data_cate == 2:
        print('Add conditional entropy as additional features...')

        with open(
                './raw_data/CE_sub%d_channel21_exp%d_train.data' %
            (args.subject_ID, index_exp), 'rb') as fp:
            CE_train = pickle.load(fp)
        with open(
                './raw_data/CE_sub%d_channel21_exp%d_test.data' %
            (args.subject_ID, index_exp), 'rb') as fp:
            CE_test = pickle.load(fp)

        # Scale CE
        CE_train, CE_test = preprocessing.scale(CE_train, CE_test)

        # Apply PCA
        pca = PCA(n_components=30, svd_solver='full')
        pca.fit(CE_train)
        CE_train = pca.transform(CE_train)
        CE_test = pca.transform(CE_test)

        print('(CE) Number of features after PCA: %d' % (CE_train.shape[1]))
        print('(CE) Explained variance ratio: %.3f' %
              (np.sum(pca.explained_variance_ratio_)))

        # Concatentate with X
        X_train = np.concatenate((X_train, CE_train), axis=1)
        X_test = np.concatenate((X_test, CE_test), axis=1)

    # Regression to predict solution latency
    X_train_Reg = X_train
    X_test_Reg = X_test
    if args.rgr_model == 'LR':
        rgr = linear_model.LinearRegression()
    elif args.rgr_model == 'Ridge':
        rgr = linear_model.Ridge(alpha=1)
    elif args.rgr_model == 'GPR':
        kernel = RBF(10, (1e-2, 1e2)) + ConstantKernel(10, (1e-2, 1e2))
        rgr = GaussianProcessRegressor(kernel=kernel, random_state=0)
    elif args.rgr_model == 'ELMK':
        rgr = elm.ELMKernel()
    elif args.rgr_model == 'ELMR':
        params = ["sigmoid", 1, 500, False]
        rgr = elm.ELMRandom(params)

    if args.rgr_model not in ['ELMK', 'ELMR']:
        rgr.fit(X_train_Reg, Y_train)
        pred_train = rgr.predict(X_train_Reg)
        pred_test = rgr.predict(X_test_Reg)
    else:
        # Scale target into -1~1
        if args.scale_target == 2:

            scaler = TargetScaler(num_step=10)
            scaler.fit(Y_train)
            Y_train, Y_test = scaler.transform(Y_train), scaler.transform(
                Y_test)
        elif args.scale_target == 1:

            Y_train, Y_test = (Y_train - 30) / 30, (Y_test - 30) / 30

        # Concatenate data for extreme learning machine
        train_data = np.concatenate((Y_train[:, np.newaxis], X_train), axis=1)
        test_data = np.concatenate((Y_test[:, np.newaxis], X_test), axis=1)

        rgr.search_param(train_data, cv="kfold", of="rmse", eval=10)

        pred_train = rgr.train(train_data).predicted_targets
        pred_test = rgr.test(test_data).predicted_targets

        # Scale target back to 0~60
        if args.scale_target == 2:

            [Y_train, Y_test, pred_train, pred_test] = [scaler.transform(x, mode='inverse') for x in \
                                           [Y_train, Y_test, pred_train, pred_test]]
        elif args.scale_target == 1:

            [Y_train, Y_test, pred_train, pred_test] = [x*30+30 for x in \
                                           [Y_train, Y_test, pred_train, pred_test]]

    evaluate_result.plot_scatter(Y_test, pred_test, dirName, fileName)

    print('Train std: %.3f' % (mean_squared_error(Y_train, pred_train)**0.5))
    print('Test std: %.3f' % (mean_squared_error(Y_test, pred_test)**0.5))

    # Save targets and predictions
    dict_target = {}
    dict_target['target'], dict_target['pred'] = Y_test, pred_test
    with open('./results/%s/%s.data' % (dirName, fileName), 'wb') as fp:
        pickle.dump(dict_target, fp)

    return