Beispiel #1
0
def build_predictor(method, n_unit, conv_layers, class_num):
    if method == 'nfp':
        print('Use NFP predictor...')
        predictor = GraphConvPredictor(
            NFP(out_dim=n_unit, hidden_dim=n_unit, n_layers=conv_layers),
            MLP(out_dim=class_num, hidden_dim=n_unit))
    elif method == 'ggnn':
        print('Use GGNN predictor...')
        predictor = GraphConvPredictor(
            GGNN(out_dim=n_unit, hidden_dim=n_unit, n_layers=conv_layers),
            MLP(out_dim=class_num, hidden_dim=n_unit))
    elif method == 'schnet':
        print('Use SchNet predictor...')
        predictor = SchNet(out_dim=class_num,
                           hidden_dim=n_unit,
                           n_layers=conv_layers,
                           readout_hidden_dim=n_unit)
    elif method == 'weavenet':
        print('Use WeaveNet predictor...')
        n_atom = 20
        n_sub_layer = 1
        weave_channels = [50] * conv_layers
        predictor = GraphConvPredictor(
            WeaveNet(weave_channels=weave_channels,
                     hidden_dim=n_unit,
                     n_sub_layer=n_sub_layer,
                     n_atom=n_atom), MLP(out_dim=class_num, hidden_dim=n_unit))
    else:
        raise ValueError('[ERROR] Invalid predictor: method={}'.format(method))
    return predictor
Beispiel #2
0
def set_up_predictor(method, n_unit, conv_layers, class_num, scaler):
    """Sets up the predictor, consisting of a graph convolution network and
    a multilayer perceptron.

    Args:
        method (str): Method name.
        n_unit (int): Number of hidden units.
        conv_layers (int): Number of convolutional layers for the graph
            convolution network.
        class_num (int): Number of output classes.
    Returns:
        predictor (chainer.Chain): An instance of the selected predictor.
    """
    mlp = MLP(out_dim=class_num, hidden_dim=n_unit)

    if method == 'nfp':
        print('Training an NFP predictor...')
        nfp = NFP(out_dim=n_unit, hidden_dim=n_unit, n_layers=conv_layers)
        predictor = GraphConvPredictor(nfp, mlp, scaler)
    elif method == 'ggnn':
        print('Training a GGNN predictor...')
        ggnn = GGNN(out_dim=n_unit, hidden_dim=n_unit, n_layers=conv_layers)
        predictor = GraphConvPredictor(ggnn, mlp, scaler)
    elif method == 'schnet':
        print('Training an SchNet predictor...')
        schnet = SchNet(out_dim=class_num,
                        hidden_dim=n_unit,
                        n_layers=conv_layers)
        predictor = GraphConvPredictor(schnet, None, scaler)
    elif method == 'weavenet':
        print('Training a WeaveNet predictor...')
        n_atom = 20
        n_sub_layer = 1
        weave_channels = [50] * conv_layers

        weavenet = WeaveNet(weave_channels=weave_channels,
                            hidden_dim=n_unit,
                            n_sub_layer=n_sub_layer,
                            n_atom=n_atom)
        predictor = GraphConvPredictor(weavenet, mlp, scaler)
    elif method == 'rsgcn':
        print('Training an RSGCN predictor...')
        rsgcn = RSGCN(out_dim=n_unit, hidden_dim=n_unit, n_layers=conv_layers)
        predictor = GraphConvPredictor(rsgcn, mlp, scaler)
    elif method == 'relgcn':
        print('Use Relational GCN predictor...')
        num_edge_type = 4
        relgcn = RelGCN(out_channels=n_unit,
                        num_edge_type=num_edge_type,
                        scale_adj=True)
        predictor = GraphConvPredictor(relgcn, mlp, scaler)
    elif method == 'relgat':
        print('Train Relational GAT predictor...')
        relgat = RelGAT(out_dim=n_unit,
                        hidden_dim=n_unit,
                        n_layers=conv_layers)
        predictor = GraphConvPredictor(relgat, mlp, scaler)
    else:
        raise ValueError('[ERROR] Invalid method: {}'.format(method))
    return predictor
Beispiel #3
0
def set_up_predictor(method,
                     fp_hidden_dim,
                     fp_out_dim,
                     conv_layers,
                     concat_hidden,
                     fp_dropout_rate,
                     net_hidden_dims,
                     class_num,
                     sim_method='mlp'):
    if sim_method == 'mlp':
        mlp = MLP(out_dim=class_num, hidden_dims=net_hidden_dims)
    elif sim_method == 'cosine':
        mlp = Cosine()
    else:
        raise ValueError(
            '[ERROR] Invalid similarity method: {}'.format(method))
    print('Using {} as similarity predictor with hidden_dims {}...'.format(
        sim_method, net_hidden_dims))

    if method == 'nfp':
        print('Training an NFP predictor...')
        nfp = NFP(out_dim=fp_out_dim,
                  hidden_dim=fp_hidden_dim,
                  n_layers=conv_layers,
                  concat_hidden=concat_hidden)
        predictor = GraphConvPredictorForPair(nfp, mlp)
    elif method == 'ggnn':
        print('Training a GGNN predictor...')
        ggnn = GGNN(out_dim=fp_out_dim,
                    hidden_dim=fp_hidden_dim,
                    n_layers=conv_layers,
                    concat_hidden=concat_hidden,
                    dropout_rate=fp_dropout_rate)
        predictor = GraphConvPredictorForPair(ggnn, mlp)
    elif method == 'schnet':
        print('Training an SchNet predictor...')
        schnet = SchNet(out_dim=class_num,
                        hidden_dim=fp_hidden_dim,
                        n_layers=conv_layers)
        predictor = GraphConvPredictorForPair(schnet, None)
    elif method == 'weavenet':
        print('Training a WeaveNet predictor...')
        n_atom = 20
        n_sub_layer = 1
        weave_channels = [50] * conv_layers

        weavenet = WeaveNet(weave_channels=weave_channels,
                            hidden_dim=fp_hidden_dim,
                            n_sub_layer=n_sub_layer,
                            n_atom=n_atom)
        predictor = GraphConvPredictorForPair(weavenet, mlp)
    elif method == 'rsgcn':
        print('Training an RSGCN predictor...')
        rsgcn = RSGCN(out_dim=fp_out_dim,
                      hidden_dim=fp_hidden_dim,
                      n_layers=conv_layers)
        predictor = GraphConvPredictorForPair(rsgcn, mlp)
    else:
        raise ValueError('[ERROR] Invalid method: {}'.format(method))
    return predictor
Beispiel #4
0
def set_up_predictor(method, n_unit, conv_layers, class_num):
    """Sets up the graph convolution network  predictor.

    Args:
        method: Method name. Currently, the supported ones are `nfp`, `ggnn`,
                `schnet`, `weavenet` and `rsgcn`.
        n_unit: Number of hidden units.
        conv_layers: Number of convolutional layers for the graph convolution
                     network.
        class_num: Number of output classes.

    Returns:
        An instance of the selected predictor.
    """

    predictor = None
    mlp = MLP(out_dim=class_num, hidden_dim=n_unit)

    if method == 'nfp':
        print('Training an NFP predictor...')
        nfp = NFP(out_dim=n_unit, hidden_dim=n_unit, n_layers=conv_layers)
        predictor = GraphConvPredictor(nfp, mlp)
    elif method == 'ggnn':
        print('Training a GGNN predictor...')
        ggnn = GGNN(out_dim=n_unit, hidden_dim=n_unit, n_layers=conv_layers)
        predictor = GraphConvPredictor(ggnn, mlp)
    elif method == 'schnet':
        print('Training an SchNet predictor...')
        schnet = SchNet(out_dim=class_num,
                        hidden_dim=n_unit,
                        n_layers=conv_layers)
        predictor = GraphConvPredictor(schnet, None)
    elif method == 'weavenet':
        print('Training a WeaveNet predictor...')
        n_atom = 20
        n_sub_layer = 1
        weave_channels = [50] * conv_layers

        weavenet = WeaveNet(weave_channels=weave_channels,
                            hidden_dim=n_unit,
                            n_sub_layer=n_sub_layer,
                            n_atom=n_atom)
        predictor = GraphConvPredictor(weavenet, mlp)
    elif method == 'rsgcn':
        print('Training an RSGCN predictor...')
        rsgcn = RSGCN(out_dim=n_unit, hidden_dim=n_unit, n_layers=conv_layers)
        predictor = GraphConvPredictor(rsgcn, mlp)
    elif method == 'relgcn':
        print('Training an RelGCN predictor...')
        num_edge_type = 4
        relgcn = RelGCN(out_channels=class_num,
                        num_edge_type=num_edge_type,
                        scale_adj=True)
        predictor = GraphConvPredictor(relgcn, None)
    else:
        raise ValueError('[ERROR] Invalid method: {}'.format(method))
    return predictor
Beispiel #5
0
def build_predictor(method, n_unit, conv_layers, class_num):
    if method == 'nfp':
        print('Use NFP predictor...')
        predictor = GraphConvPredictor(
            NFP(out_dim=n_unit, hidden_dim=n_unit, n_layers=conv_layers),
            MLP(out_dim=class_num, hidden_dim=n_unit))
    elif method == 'ggnn':
        print('Use GGNN predictor...')
        predictor = GraphConvPredictor(
            GGNN(out_dim=n_unit, hidden_dim=n_unit, n_layers=conv_layers),
            MLP(out_dim=class_num, hidden_dim=n_unit))
    elif method == 'schnet':
        print('Use SchNet predictor...')
        # MLP layer is not necessary for SchNet
        predictor = GraphConvPredictor(
            SchNet(out_dim=class_num,
                   hidden_dim=n_unit,
                   n_layers=conv_layers,
                   readout_hidden_dim=n_unit), None)
    elif method == 'weavenet':
        print('Use WeaveNet predictor...')
        n_atom = 20
        n_sub_layer = 1
        weave_channels = [50] * conv_layers
        predictor = GraphConvPredictor(
            WeaveNet(weave_channels=weave_channels,
                     hidden_dim=n_unit,
                     n_sub_layer=n_sub_layer,
                     n_atom=n_atom), MLP(out_dim=class_num, hidden_dim=n_unit))
    elif method == 'rsgcn':
        print('Use RSGCN predictor...')
        predictor = GraphConvPredictor(
            RSGCN(out_dim=n_unit, hidden_dim=n_unit, n_layers=conv_layers),
            MLP(out_dim=class_num, hidden_dim=n_unit))
    elif method == 'relgcn':
        print('Use Relational GCN predictor...')
        num_edge_type = 4
        predictor = GraphConvPredictor(
            RelGCN(out_channels=n_unit,
                   num_edge_type=num_edge_type,
                   scale_adj=True), MLP(out_dim=class_num, hidden_dim=n_unit))
    elif method == 'relgat':
        print('Use GAT predictor...')
        predictor = GraphConvPredictor(
            RelGAT(out_dim=n_unit, hidden_dim=n_unit, n_layers=conv_layers),
            MLP(out_dim=class_num, hidden_dim=n_unit))
    else:
        raise ValueError('[ERROR] Invalid predictor: method={}'.format(method))
    return predictor
def main():
    """Launcher."""
    preprocessor = preprocess_method_dict["nfp"]()
    dataset = datasets.get_qm9(preprocessor, labels="h**o")
    cache_dir = "data/"
    if not (os.path.exists(cache_dir)):
        os.makedirs(cache_dir)
    NumpyTupleDataset.save(cache_dir + "data.npz", dataset)
    dataset = NumpyTupleDataset.load(cache_dir + 'data.npz')
    train_data_ratio = 0.7
    train_data_size = int(len(dataset) * train_data_ratio)
    train, validation = split_dataset_random(dataset, train_data_size, 777)
    print('train dataset size:', len(train))
    print('validation dataset size:', len(validation))

    n_unit = 16
    conv_layers = 4
    model = GraphConvPredictor(NFP(n_unit, n_unit, conv_layers),
                               MLP(n_unit, 1))
Beispiel #7
0
def main():
    # Supported preprocessing/network list
    method_list = ['nfp', 'ggnn', 'schnet', 'weavenet', 'rsgcn']
    scale_list = ['standardize', 'none']

    parser = argparse.ArgumentParser(
        description='Regression with own dataset.')
    parser.add_argument('--datafile', type=str, default='dataset.csv')
    parser.add_argument('--method',
                        '-m',
                        type=str,
                        choices=method_list,
                        default='nfp')
    parser.add_argument('--label',
                        '-l',
                        nargs='+',
                        default=['value1', 'value2'],
                        help='target label for regression')
    parser.add_argument('--scale',
                        type=str,
                        choices=scale_list,
                        default='standardize',
                        help='Label scaling method')
    parser.add_argument('--conv-layers', '-c', type=int, default=4)
    parser.add_argument('--batchsize', '-b', type=int, default=32)
    parser.add_argument('--gpu', '-g', type=int, default=-1)
    parser.add_argument('--out', '-o', type=str, default='result')
    parser.add_argument('--epoch', '-e', type=int, default=20)
    parser.add_argument('--unit-num', '-u', type=int, default=16)
    parser.add_argument('--seed', '-s', type=int, default=777)
    parser.add_argument('--train-data-ratio', '-t', type=float, default=0.7)
    parser.add_argument('--protocol', type=int, default=2)
    args = parser.parse_args()

    seed = args.seed
    train_data_ratio = args.train_data_ratio
    method = args.method
    if args.label:
        labels = args.label
        class_num = len(labels) if isinstance(labels, list) else 1
    else:
        sys.exit("Error: No target label is specified.")

    # Dataset preparation
    # Postprocess is required for regression task
    def postprocess_label(label_list):
        return numpy.asarray(label_list, dtype=numpy.float32)

    print('Preprocessing dataset...')
    preprocessor = preprocess_method_dict[method]()
    parser = CSVFileParser(preprocessor,
                           postprocess_label=postprocess_label,
                           labels=labels,
                           smiles_col='SMILES')
    dataset = parser.parse(args.datafile)["dataset"]

    if args.scale == 'standardize':
        # Standard Scaler for labels
        scaler = StandardScaler()
        labels = scaler.fit_transform(dataset.get_datasets()[-1])
        dataset = NumpyTupleDataset(*(dataset.get_datasets()[:-1] +
                                      (labels, )))
    else:
        # Not use scaler
        scaler = None

    train_data_size = int(len(dataset) * train_data_ratio)
    train, val = split_dataset_random(dataset, train_data_size, seed)

    # Network
    n_unit = args.unit_num
    conv_layers = args.conv_layers
    if method == 'nfp':
        print('Train NFP model...')
        model = GraphConvPredictor(
            NFP(out_dim=n_unit, hidden_dim=n_unit, n_layers=conv_layers),
            MLP(out_dim=class_num, hidden_dim=n_unit))
    elif method == 'ggnn':
        print('Train GGNN model...')
        model = GraphConvPredictor(
            GGNN(out_dim=n_unit, hidden_dim=n_unit, n_layers=conv_layers),
            MLP(out_dim=class_num, hidden_dim=n_unit))
    elif method == 'schnet':
        print('Train SchNet model...')
        model = GraphConvPredictor(
            SchNet(out_dim=class_num, hidden_dim=n_unit, n_layers=conv_layers),
            None)
    elif method == 'weavenet':
        print('Train WeaveNet model...')
        n_atom = 20
        n_sub_layer = 1
        weave_channels = [50] * conv_layers
        model = GraphConvPredictor(
            WeaveNet(weave_channels=weave_channels,
                     hidden_dim=n_unit,
                     n_sub_layer=n_sub_layer,
                     n_atom=n_atom), MLP(out_dim=class_num, hidden_dim=n_unit))
    elif method == 'rsgcn':
        print('Train RSGCN model...')
        model = GraphConvPredictor(
            RSGCN(out_dim=n_unit, hidden_dim=n_unit, n_layers=conv_layers),
            MLP(out_dim=class_num, hidden_dim=n_unit))
    else:
        raise ValueError('[ERROR] Invalid method {}'.format(method))

    train_iter = iterators.SerialIterator(train, args.batchsize)
    val_iter = iterators.SerialIterator(val,
                                        args.batchsize,
                                        repeat=False,
                                        shuffle=False)

    regressor = Regressor(
        model,
        lossfun=F.mean_squared_error,
        metrics_fun={'abs_error': ScaledAbsError(scaler=scaler)},
        device=args.gpu)

    optimizer = optimizers.Adam()
    optimizer.setup(regressor)

    updater = training.StandardUpdater(train_iter,
                                       optimizer,
                                       device=args.gpu,
                                       converter=concat_mols)
    trainer = training.Trainer(updater, (args.epoch, 'epoch'), out=args.out)
    trainer.extend(
        E.Evaluator(val_iter,
                    regressor,
                    device=args.gpu,
                    converter=concat_mols))
    trainer.extend(E.snapshot(), trigger=(args.epoch, 'epoch'))
    trainer.extend(E.LogReport())
    # Note that original scale absolute errors are reported in
    # (validation/)main/abs_error
    trainer.extend(
        E.PrintReport([
            'epoch', 'main/loss', 'main/abs_error', 'validation/main/loss',
            'validation/main/abs_error', 'elapsed_time'
        ]))
    trainer.extend(E.ProgressBar())
    trainer.run()

    # --- save regressor's parameters ---
    protocol = args.protocol
    model_path = os.path.join(args.out, 'model.npz')
    print('saving trained model to {}'.format(model_path))
    serializers.save_npz(model_path, regressor)
    if scaler is not None:
        with open(os.path.join(args.out, 'scaler.pkl'), mode='wb') as f:
            pickle.dump(scaler, f, protocol=protocol)

    # Example of prediction using trained model
    smiles = 'c1ccccc1'
    mol = Chem.MolFromSmiles(smiles)
    preprocessor = preprocess_method_dict[method]()
    standardized_smiles, mol = preprocessor.prepare_smiles_and_mol(mol)
    input_features = preprocessor.get_input_features(mol)
    atoms, adjs = concat_mols([input_features], device=args.gpu)
    prediction = model(atoms, adjs).data[0]
    if scaler is not None:
        prediction = scaler.inverse_transform(prediction)
    print('Prediction for {}:'.format(smiles))
    for i, label in enumerate(args.label):
        print('{}: {}'.format(label, prediction[i]))
Beispiel #8
0
def set_up_predictor(method, n_unit, conv_layers, class_num):
    """Sets up the predictor, consisting of a graph convolution network and
    a multilayer perceptron.
    Args:
        method: Method name. See `parse_arguments`.
        n_unit: Number of hidden units.
        conv_layers: Number of convolutional layers for the graph convolution
                     network.
        class_num: Number of output classes.
    Returns:
        An instance of the selected predictor.
    """

    mlp = MLP(out_dim=class_num, hidden_dim=n_unit)

    if method == 'nfp':
        print('Training an NFP predictor...')
        nfp = NFP(out_dim=n_unit, hidden_dim=n_unit, n_layers=conv_layers)
        return GraphConvPredictor(nfp, mlp)
    elif method == 'nfp_gwm':
        print('Training an NFP+GWM predictor...')
        nfp_gwm = NFP_GWM(out_dim=n_unit,
                          hidden_dim=n_unit,
                          hidden_dim_super=n_unit,
                          n_layers=conv_layers,
                          dropout_ratio=0.5)
        return GraphConvPredictorForGWM(nfp_gwm, mlp)
    elif method == 'ggnn':
        print('Training a GGNN predictor...')
        ggnn = GGNN(out_dim=n_unit, hidden_dim=n_unit, n_layers=conv_layers)
        return GraphConvPredictor(ggnn, mlp)
    elif method == 'ggnn_gwm':
        print('Train GGNN+GWM model...')
        ggnn_gwm = GGNN_GWM(out_dim=n_unit,
                            hidden_dim=n_unit,
                            hidden_dim_super=n_unit,
                            n_layers=conv_layers,
                            dropout_ratio=0.5,
                            weight_tying=True)
        return GraphConvPredictorForGWM(ggnn_gwm, mlp)
    elif method == 'schnet':
        print('Training an SchNet predictor...')
        schnet = SchNet(out_dim=class_num,
                        hidden_dim=n_unit,
                        n_layers=conv_layers)
        return GraphConvPredictor(schnet, None)
    elif method == 'weavenet':
        print('Training a WeaveNet predictor...')
        n_atom = 20
        n_sub_layer = 1
        weave_channels = [50] * conv_layers

        weavenet = WeaveNet(weave_channels=weave_channels,
                            hidden_dim=n_unit,
                            n_sub_layer=n_sub_layer,
                            n_atom=n_atom)
        return GraphConvPredictor(weavenet, mlp)
    elif method == 'rsgcn':
        print('Training an RSGCN predictor...')
        rsgcn = RSGCN(out_dim=n_unit, hidden_dim=n_unit, n_layers=conv_layers)
        return GraphConvPredictor(rsgcn, mlp)
    elif method == 'rsgcn_gwm':
        print('Training an RSGCN+GWM predictor...')
        rsgcn_gwm = RSGCN_GWM(out_dim=n_unit,
                              hidden_dim=n_unit,
                              hidden_dim_super=n_unit,
                              n_layers=conv_layers,
                              dropout_ratio=0.5)
        return GraphConvPredictorForGWM(rsgcn_gwm, mlp)
    elif method == 'relgcn':
        print('Training an RelGCN predictor...')
        num_edge_type = 4
        relgcn = RelGCN(out_channels=n_unit,
                        num_edge_type=num_edge_type,
                        scale_adj=True)
        return GraphConvPredictor(relgcn, mlp)
    elif method == 'relgat':
        print('Train Relational GAT model...')
        relgat = RelGAT(out_dim=n_unit,
                        hidden_dim=n_unit,
                        n_layers=conv_layers)
        return GraphConvPredictor(relgat, mlp)
    elif method == 'gin':
        print('Training a GIN predictor...')
        gin = GIN(out_dim=n_unit, hidden_dim=n_unit, n_layers=conv_layers)
        return GraphConvPredictor(gin, mlp)
    elif method == 'gin_gwm':
        print('Training a GIN+GWM predictor...')
        gin_gwm = GIN_GWM(out_dim=n_unit,
                          hidden_dim=n_unit,
                          hidden_dim_super=n_unit,
                          n_layers=conv_layers,
                          dropout_ratio=0.5,
                          weight_tying=True)
        return GraphConvPredictorForGWM(gin_gwm, mlp)
    raise ValueError('[ERROR] Invalid method: {}'.format(method))
def main():
    # Supported preprocessing/network list
    method_list = ['nfp', 'ggnn', 'schnet', 'weavenet', 'rsgcn']
    label_names = [
        'A', 'B', 'C', 'mu', 'alpha', 'h**o', 'lumo', 'gap', 'r2', 'zpve',
        'U0', 'U', 'H', 'G', 'Cv'
    ]
    scale_list = ['standardize', 'none']

    parser = argparse.ArgumentParser(description='Regression with QM9.')
    parser.add_argument('--method',
                        '-m',
                        type=str,
                        choices=method_list,
                        default='nfp')
    parser.add_argument('--label',
                        '-l',
                        type=str,
                        choices=label_names,
                        default='',
                        help='target label for regression, '
                        'empty string means to predict all '
                        'property at once')
    parser.add_argument('--scale',
                        type=str,
                        choices=scale_list,
                        default='standardize',
                        help='Label scaling method')
    parser.add_argument('--conv-layers', '-c', type=int, default=4)
    parser.add_argument('--batchsize', '-b', type=int, default=32)
    parser.add_argument('--gpu', '-g', type=int, default=-1)
    parser.add_argument('--out', '-o', type=str, default='result')
    parser.add_argument('--epoch', '-e', type=int, default=20)
    parser.add_argument('--unit-num', '-u', type=int, default=16)
    parser.add_argument('--seed', '-s', type=int, default=777)
    parser.add_argument('--train-data-ratio', '-t', type=float, default=0.7)
    args = parser.parse_args()

    seed = args.seed
    train_data_ratio = args.train_data_ratio
    method = args.method
    if args.label:
        labels = args.label
        cache_dir = os.path.join('input', '{}_{}'.format(method, labels))
        class_num = len(labels) if isinstance(labels, list) else 1
    else:
        labels = None
        cache_dir = os.path.join('input', '{}_all'.format(method))
        class_num = len(D.get_qm9_label_names())

    # Dataset preparation
    dataset = None

    if os.path.exists(cache_dir):
        print('load from cache {}'.format(cache_dir))
        dataset = NumpyTupleDataset.load(os.path.join(cache_dir, 'data.npz'))
    if dataset is None:
        print('preprocessing dataset...')
        preprocessor = preprocess_method_dict[method]()
        dataset = D.get_qm9(preprocessor, labels=labels)
        os.makedirs(cache_dir)
        NumpyTupleDataset.save(os.path.join(cache_dir, 'data.npz'), dataset)

    if args.scale == 'standardize':
        # Standard Scaler for labels
        ss = StandardScaler()
        labels = ss.fit_transform(dataset.get_datasets()[-1])
        dataset = NumpyTupleDataset(*dataset.get_datasets()[:-1], labels)

    train_data_size = int(len(dataset) * train_data_ratio)
    train, val = split_dataset_random(dataset, train_data_size, seed)

    # Network
    n_unit = args.unit_num
    conv_layers = args.conv_layers
    if method == 'nfp':
        print('Train NFP model...')
        model = GraphConvPredictor(
            NFP(out_dim=n_unit, hidden_dim=n_unit, n_layers=conv_layers),
            MLP(out_dim=class_num, hidden_dim=n_unit))
    elif method == 'ggnn':
        print('Train GGNN model...')
        model = GraphConvPredictor(
            GGNN(out_dim=n_unit, hidden_dim=n_unit, n_layers=conv_layers),
            MLP(out_dim=class_num, hidden_dim=n_unit))
    elif method == 'schnet':
        print('Train SchNet model...')
        model = GraphConvPredictor(
            SchNet(out_dim=class_num, hidden_dim=n_unit, n_layers=conv_layers),
            None)
    elif method == 'weavenet':
        print('Train WeaveNet model...')
        n_atom = 20
        n_sub_layer = 1
        weave_channels = [50] * conv_layers
        model = GraphConvPredictor(
            WeaveNet(weave_channels=weave_channels,
                     hidden_dim=n_unit,
                     n_sub_layer=n_sub_layer,
                     n_atom=n_atom), MLP(out_dim=class_num, hidden_dim=n_unit))
    elif method == 'rsgcn':
        print('Train RSGCN model...')
        model = GraphConvPredictor(
            RSGCN(out_dim=n_unit, hidden_dim=n_unit, n_layers=conv_layers),
            MLP(out_dim=class_num, hidden_dim=n_unit))
    else:
        raise ValueError('[ERROR] Invalid method {}'.format(method))

    train_iter = I.SerialIterator(train, args.batchsize)
    val_iter = I.SerialIterator(val,
                                args.batchsize,
                                repeat=False,
                                shuffle=False)

    def scaled_abs_error(x0, x1):
        if isinstance(x0, Variable):
            x0 = cuda.to_cpu(x0.data)
        if isinstance(x1, Variable):
            x1 = cuda.to_cpu(x1.data)
        if args.scale == 'standardize':
            scaled_x0 = ss.inverse_transform(cuda.to_cpu(x0))
            scaled_x1 = ss.inverse_transform(cuda.to_cpu(x1))
            diff = scaled_x0 - scaled_x1
        elif args.scale == 'none':
            diff = cuda.to_cpu(x0) - cuda.to_cpu(x1)
        return numpy.mean(numpy.absolute(diff), axis=0)[0]

    classifier = L.Classifier(model,
                              lossfun=F.mean_squared_error,
                              accfun=scaled_abs_error)

    if args.gpu >= 0:
        chainer.cuda.get_device_from_id(args.gpu).use()
        classifier.to_gpu()

    optimizer = O.Adam()
    optimizer.setup(classifier)

    updater = training.StandardUpdater(train_iter,
                                       optimizer,
                                       device=args.gpu,
                                       converter=concat_mols)
    trainer = training.Trainer(updater, (args.epoch, 'epoch'), out=args.out)
    trainer.extend(
        E.Evaluator(val_iter,
                    classifier,
                    device=args.gpu,
                    converter=concat_mols))
    trainer.extend(E.snapshot(), trigger=(args.epoch, 'epoch'))
    trainer.extend(E.LogReport())
    trainer.extend(
        E.PrintReport([
            'epoch', 'main/loss', 'main/accuracy', 'validation/main/loss',
            'validation/main/accuracy', 'elapsed_time'
        ]))
    trainer.extend(E.ProgressBar())
    trainer.run()
Beispiel #10
0
def main():
    # Supported preprocessing/network list
    method_list = ['nfp', 'ggnn', 'schnet', 'weavenet', 'rsgcn']
    label_names = [
        'A', 'B', 'C', 'mu', 'alpha', 'h**o', 'lumo', 'gap', 'r2', 'zpve',
        'U0', 'U', 'H', 'G', 'Cv'
    ]
    scale_list = ['standardize', 'none']

    parser = argparse.ArgumentParser(description='Regression with QM9.')
    parser.add_argument('--method',
                        '-m',
                        type=str,
                        choices=method_list,
                        default='nfp')
    parser.add_argument('--label',
                        '-l',
                        type=str,
                        choices=label_names,
                        default='',
                        help='target label for regression, '
                        'empty string means to predict all '
                        'property at once')
    parser.add_argument('--scale',
                        type=str,
                        choices=scale_list,
                        default='standardize',
                        help='Label scaling method')
    parser.add_argument('--conv-layers', '-c', type=int, default=4)
    parser.add_argument('--batchsize', '-b', type=int, default=32)
    parser.add_argument('--gpu', '-g', type=int, default=-1)
    parser.add_argument('--out', '-o', type=str, default='result')
    parser.add_argument('--epoch', '-e', type=int, default=20)
    parser.add_argument('--unit-num', '-u', type=int, default=16)
    parser.add_argument('--seed', '-s', type=int, default=777)
    parser.add_argument('--train-data-ratio', '-t', type=float, default=0.7)
    parser.add_argument('--protocol', type=int, default=2)
    parser.add_argument('--model-filename', type=str, default='regressor.pkl')
    parser.add_argument('--num-data',
                        type=int,
                        default=-1,
                        help='Number of data to be parsed from parser.'
                        '-1 indicates to parse all data.')
    args = parser.parse_args()

    seed = args.seed
    train_data_ratio = args.train_data_ratio
    method = args.method
    if args.label:
        labels = args.label
        cache_dir = os.path.join('input', '{}_{}'.format(method, labels))
        class_num = len(labels) if isinstance(labels, list) else 1
    else:
        labels = None
        cache_dir = os.path.join('input', '{}_all'.format(method))
        class_num = len(D.get_qm9_label_names())

    # Dataset preparation
    dataset = None

    num_data = args.num_data
    if num_data >= 0:
        dataset_filename = 'data_{}.npz'.format(num_data)
    else:
        dataset_filename = 'data.npz'
    dataset_cache_path = os.path.join(cache_dir, dataset_filename)
    if os.path.exists(dataset_cache_path):
        print('load from cache {}'.format(dataset_cache_path))
        dataset = NumpyTupleDataset.load(dataset_cache_path)
    if dataset is None:
        print('preprocessing dataset...')
        preprocessor = preprocess_method_dict[method]()
        if num_data >= 0:
            # only use first 100 for debug
            target_index = numpy.arange(num_data)
            dataset = D.get_qm9(preprocessor,
                                labels=labels,
                                target_index=target_index)
        else:
            dataset = D.get_qm9(preprocessor, labels=labels)
        os.makedirs(cache_dir)
        NumpyTupleDataset.save(dataset_cache_path, dataset)

    if args.scale == 'standardize':
        # Standard Scaler for labels
        ss = StandardScaler()
        labels = ss.fit_transform(dataset.get_datasets()[-1])
    else:
        ss = None
    dataset = NumpyTupleDataset(*(dataset.get_datasets()[:-1] + (labels, )))

    train_data_size = int(len(dataset) * train_data_ratio)
    train, val = split_dataset_random(dataset, train_data_size, seed)

    # Network
    n_unit = args.unit_num
    conv_layers = args.conv_layers
    if method == 'nfp':
        print('Train NFP model...')
        model = GraphConvPredictor(
            NFP(out_dim=n_unit, hidden_dim=n_unit, n_layers=conv_layers),
            MLP(out_dim=class_num, hidden_dim=n_unit))
    elif method == 'ggnn':
        print('Train GGNN model...')
        model = GraphConvPredictor(
            GGNN(out_dim=n_unit, hidden_dim=n_unit, n_layers=conv_layers),
            MLP(out_dim=class_num, hidden_dim=n_unit))
    elif method == 'schnet':
        print('Train SchNet model...')
        model = GraphConvPredictor(
            SchNet(out_dim=class_num, hidden_dim=n_unit, n_layers=conv_layers),
            None)
    elif method == 'weavenet':
        print('Train WeaveNet model...')
        n_atom = 20
        n_sub_layer = 1
        weave_channels = [50] * conv_layers
        model = GraphConvPredictor(
            WeaveNet(weave_channels=weave_channels,
                     hidden_dim=n_unit,
                     n_sub_layer=n_sub_layer,
                     n_atom=n_atom), MLP(out_dim=class_num, hidden_dim=n_unit))
    elif method == 'rsgcn':
        print('Train RSGCN model...')
        model = GraphConvPredictor(
            RSGCN(out_dim=n_unit, hidden_dim=n_unit, n_layers=conv_layers),
            MLP(out_dim=class_num, hidden_dim=n_unit))
    else:
        raise ValueError('[ERROR] Invalid method {}'.format(method))

    train_iter = I.SerialIterator(train, args.batchsize)
    val_iter = I.SerialIterator(val,
                                args.batchsize,
                                repeat=False,
                                shuffle=False)

    regressor = Regressor(
        model,
        lossfun=F.mean_squared_error,
        metrics_fun={'abs_error': ScaledAbsError(scale=args.scale, ss=ss)},
        device=args.gpu)

    optimizer = O.Adam()
    optimizer.setup(regressor)

    updater = training.StandardUpdater(train_iter,
                                       optimizer,
                                       device=args.gpu,
                                       converter=concat_mols)
    trainer = training.Trainer(updater, (args.epoch, 'epoch'), out=args.out)
    trainer.extend(
        E.Evaluator(val_iter,
                    regressor,
                    device=args.gpu,
                    converter=concat_mols))
    trainer.extend(E.snapshot(), trigger=(args.epoch, 'epoch'))
    trainer.extend(E.LogReport())
    trainer.extend(
        E.PrintReport([
            'epoch', 'main/loss', 'main/abs_error', 'validation/main/loss',
            'validation/main/abs_error', 'elapsed_time'
        ]))
    trainer.extend(E.ProgressBar())
    trainer.run()

    # --- save regressor & standardscaler ---
    protocol = args.protocol
    regressor.save_pickle(os.path.join(args.out, args.model_filename),
                          protocol=protocol)
    if args.scale == 'standardize':
        with open(os.path.join(args.out, 'ss.pkl'), mode='wb') as f:
            pickle.dump(ss, f, protocol=protocol)
Beispiel #11
0
    val_sampler = SubsetRandomSampler(val_indices)
    loader = DataLoader(generator_train,
                        batch_size=BATCH_SIZE,
                        sampler=train_sampler)
    loader_val = DataLoader(generator_train,
                            batch_size=BATCH_SIZE,
                            sampler=val_sampler)
    loader_test = DataLoader(generator_test, batch_size=BATCH_SIZE)

#create models
if model_name == "baseline":
    model = BaselineModel(input_len, drop_rate=dropout)
elif model_name == 'nfp':
    print('Training an NFP predictor...')
    mlp = MLP(out_dim=class_num, hidden_dim=n_unit)
    nfp = NFP(out_dim=n_unit, hidden_dim=n_unit, n_layers=conv_layers)
    model = GraphConvPredictor(nfp, mlp)
elif model_name == 'ggnn':
    print('Training a GGNN predictor...')
    mlp = MLP(out_dim=class_num, hidden_dim=n_unit)
    ggnn = GGNN(out_dim=n_unit, hidden_dim=n_unit, n_layers=conv_layers)
    model = GraphConvPredictor(ggnn, mlp)
elif model_name == 'schnet':
    print('Training an SchNet predictor...')
    mlp = MLP(out_dim=class_num, hidden_dim=n_unit)
    schnet = SchNet(out_dim=class_num, hidden_dim=n_unit, n_layers=conv_layers)
    model = GraphConvPredictor(schnet, None)
elif model_name == 'weavenet':
    print('Training a WeaveNet predictor...')
    mlp = MLP(out_dim=class_num, hidden_dim=n_unit)
    n_atom = 20
def set_up_predictor(method, fp_hidden_dim, fp_out_dim, conv_layers, concat_hidden, layer_aggregator,
                     fp_dropout_rate, fp_batch_normalization,
                     net_hidden_dims, class_num,
                     sim_method='mlp', fp_attention=False, weight_typing=True, attention_tying=True,
                     update_attention=False,
                     context=False, context_layers=1, context_dropout=0.,
                     message_function='matrix_multiply', readout_function='graph_level',
                     num_timesteps=3, num_output_hidden_layers=0, output_hidden_dim=16,
                     output_activation=functions.relu,
                     symmetric=None,
                     ):
    if sim_method == 'mlp':
        logging.info('Using multi-layer perceptron for the learning of composite representation')
        mlp = MLP(out_dim=class_num, hidden_dims=net_hidden_dims)
    elif sim_method == 'ntn':
        logging.info('Using neural tensor network for the learning of composite representation')
        ntn_out_dim = 8
        logging.info('NTN out dim is {}'.format(ntn_out_dim))
        mlp = NTN(left_dim=fp_out_dim, right_dim=fp_out_dim, out_dim=class_num,
                  ntn_out_dim=ntn_out_dim, hidden_dims=net_hidden_dims)
    elif sim_method == 'symmlp':
        logging.info('Using symmetric multi-layer perceptron for the learning of composite representation')
        mlp = MLP(out_dim=class_num, hidden_dims=net_hidden_dims)
    elif sim_method == 'hole':
        logging.info('Using holegraphic embedding for the learning of composite representation')
        mlp = HolE(out_dim=class_num, hidden_dims=net_hidden_dims)
    elif sim_method == 'dist-mult':
        logging.info('Using DistMult embedding for the learning of composite representation')
        dm_out_dim = 8
        mlp = DistMult(left_dim=fp_out_dim, right_dim=fp_out_dim, out_dim=class_num,
                       dm_out_dim=dm_out_dim, hidden_dims=net_hidden_dims)
    else:
        raise ValueError('[ERROR] Invalid similarity method: {}'.format(method))
    logging.info('Using {} as similarity predictor with hidden_dims {}...'.format(sim_method, net_hidden_dims))

    encoder = None
    if method == 'ggnn':
        logging.info('Training a GGNN predictor...')
        if fp_attention:
            logging.info('Self-attention mechanism is utilized...')
            if attention_tying:
                logging.info('Self-attention is tying...')
            else:
                logging.info('Self-attention is not tying...')
        if update_attention:
            logging.info('Self-attention mechanism is utilized in update...')
            if attention_tying:
                logging.info('Self-attention is tying...')
            else:
                logging.info('Self-attention is not tying...')
        if not weight_typing:
            logging.info('Weight is not tying...')
        if fp_dropout_rate != 0.0:
            logging.info('Using dropout whose rate is {}...'.format(fp_dropout_rate))
        if fp_batch_normalization:
            logging.info('Using batch normalization in dynamic fingerprint...')
        if concat_hidden:
            logging.info('Incorporating layer aggregation via concatenation after readout...')
        if layer_aggregator:
            logging.info('Incorporating layer aggregation via {} before readout...'.format(layer_aggregator))
        if context:
            logging.info('Context embedding is utilized...')
            logging.info('Number of context layers is {}...'.format(context_layers))
            logging.info('Dropout rate of context layers is {:.2f}'.format(context_dropout))
        logging.info('Message function is {}'.format(message_function))
        logging.info('Readout function is {}'.format(readout_function))
        logging.info('Num_timesteps = {}, num_output_hidden_layers={}, output_hidden_dim={}'.format(
            num_timesteps, num_output_hidden_layers, output_hidden_dim
        ))
        # num_timesteps=3, num_output_hidden_layers=0, output_hidden_dim=16, output_activation=functions.relu,
        encoder = GGNN(out_dim=fp_out_dim, hidden_dim=fp_hidden_dim, n_layers=conv_layers, concat_hidden=concat_hidden,
                    layer_aggregator=layer_aggregator,
                    dropout_rate=fp_dropout_rate, batch_normalization=fp_batch_normalization,
                    use_attention=fp_attention, weight_tying=weight_typing, attention_tying=attention_tying,
                    context=context, message_function=message_function, readout_function=readout_function,
                    num_timesteps=num_timesteps, num_output_hidden_layers=num_output_hidden_layers,
                    output_hidden_dim=output_hidden_dim, output_activation=output_activation)

    elif method == 'nfp':
        fp_max_degree = 6
        logging.info('Training an NFP predictor...')
        logging.info('Max degree is {}'.format(fp_max_degree))
        encoder = NFP(out_dim=fp_out_dim, hidden_dim=fp_hidden_dim, n_layers=conv_layers, concat_hidden=concat_hidden,
                  max_degree=fp_max_degree)

    elif method == 'schnet':
        logging.info('Training an SchNet predictor...')
        schnet = SchNet(out_dim=class_num, hidden_dim=fp_hidden_dim,
                        n_layers=conv_layers)
        encoder = schnet

    elif method == 'weavenet':
        logging.info('Training a WeaveNet predictor...')
        n_atom = 20
        n_sub_layer = 1
        weave_channels = [50] * conv_layers

        encoder = WeaveNet(weave_channels=weave_channels, hidden_dim=fp_hidden_dim,
                            n_sub_layer=n_sub_layer, n_atom=n_atom)

    elif method == 'rsgcn':
        logging.info('Training an RSGCN predictor...')
        use_batch_norm = True
        dropout_ratio = 0.5
        if use_batch_norm:
            logging.info('Using batch normalization...')
        logging.info('Dropout ratio is {:.1f}'.format(dropout_ratio))
        encoder = RSGCN(out_dim=fp_out_dim, hidden_dim=fp_hidden_dim, n_layers=conv_layers, use_batch_norm=use_batch_norm, dropout_ratio=dropout_ratio)

    elif method == 'gin':
        encoder = GIN(out_dim=fp_out_dim, hidden_dim=fp_hidden_dim, n_layers=conv_layers,
                      dropout_ratio=0.5, concat_hidden=True)
    else:
        raise ValueError('[ERROR] Invalid method: {}'.format(method))

    predictor = GraphConvPredictorForPair(encoder, mlp, symmetric=symmetric)
    return predictor
Beispiel #13
0
def main():
    method_list = ['nfp', 'ggnn', 'schnet', 'weavenet', 'rsgcn']
    dataset_names = list(molnet_default_config.keys())

    parser = argparse.ArgumentParser(description='molnet example')
    parser.add_argument('--method',
                        '-m',
                        type=str,
                        choices=method_list,
                        default='nfp')
    parser.add_argument('--label',
                        '-l',
                        type=str,
                        default='',
                        help='target label for regression, empty string means '
                        'to predict all property at once')
    parser.add_argument('--conv-layers', '-c', type=int, default=4)
    parser.add_argument('--batchsize', '-b', type=int, default=32)
    parser.add_argument('--gpu', '-g', type=int, default=-1)
    parser.add_argument('--out', '-o', type=str, default='result')
    parser.add_argument('--epoch', '-e', type=int, default=20)
    parser.add_argument('--unit-num', '-u', type=int, default=16)
    parser.add_argument('--dataset',
                        '-d',
                        type=str,
                        choices=dataset_names,
                        default='bbbp')
    parser.add_argument('--protocol', type=int, default=2)
    parser.add_argument('--model-filename', type=str, default='regressor.pkl')
    parser.add_argument('--num-data',
                        type=int,
                        default=-1,
                        help='Number of data to be parsed from parser.'
                        '-1 indicates to parse all data.')
    args = parser.parse_args()
    dataset_name = args.dataset
    method = args.method
    num_data = args.num_data
    n_unit = args.unit_num
    conv_layers = args.conv_layers
    print('Use {} dataset'.format(dataset_name))

    if args.label:
        labels = args.label
        cache_dir = os.path.join(
            'input', '{}_{}_{}'.format(dataset_name, method, labels))
        class_num = len(labels) if isinstance(labels, list) else 1
    else:
        labels = None
        cache_dir = os.path.join('input',
                                 '{}_{}_all'.format(dataset_name, method))
        class_num = len(molnet_default_config[args.dataset]['tasks'])

    # Dataset preparation
    def get_dataset_paths(cache_dir, num_data):
        filepaths = []
        for filetype in ['train', 'valid', 'test']:
            filename = filetype + '_data'
            if num_data >= 0:
                filename += '_' + str(num_data)
            filename += '.npz'
            filepath = os.path.join(cache_dir, filename)
            filepaths.append(filepath)
        return filepaths

    filepaths = get_dataset_paths(cache_dir, num_data)
    if all([os.path.exists(fpath) for fpath in filepaths]):
        datasets = []
        for fpath in filepaths:
            print('load from cache {}'.format(fpath))
            datasets.append(NumpyTupleDataset.load(fpath))
    else:
        print('preprocessing dataset...')
        preprocessor = preprocess_method_dict[method]()
        # only use first 100 for debug if num_data >= 0
        target_index = numpy.arange(num_data) if num_data >= 0 else None
        datasets = D.molnet.get_molnet_dataset(dataset_name,
                                               preprocessor,
                                               labels=labels,
                                               target_index=target_index)
        if not os.path.exists(cache_dir):
            os.makedirs(cache_dir)
        datasets = datasets['dataset']
        for i, fpath in enumerate(filepaths):
            NumpyTupleDataset.save(fpath, datasets[i])

    train, val, _ = datasets

    # Network
    if method == 'nfp':
        print('Train NFP model...')
        predictor = GraphConvPredictor(
            NFP(out_dim=n_unit, hidden_dim=n_unit, n_layers=conv_layers),
            MLP(out_dim=class_num, hidden_dim=n_unit))
    elif method == 'ggnn':
        print('Train GGNN model...')
        predictor = GraphConvPredictor(
            GGNN(out_dim=n_unit, hidden_dim=n_unit, n_layers=conv_layers),
            MLP(out_dim=class_num, hidden_dim=n_unit))
    elif method == 'schnet':
        print('Train SchNet model...')
        predictor = GraphConvPredictor(
            SchNet(out_dim=class_num, hidden_dim=n_unit, n_layers=conv_layers),
            None)
    elif method == 'weavenet':
        print('Train WeaveNet model...')
        n_atom = 20
        n_sub_layer = 1
        weave_channels = [50] * conv_layers
        predictor = GraphConvPredictor(
            WeaveNet(weave_channels=weave_channels,
                     hidden_dim=n_unit,
                     n_sub_layer=n_sub_layer,
                     n_atom=n_atom), MLP(out_dim=class_num, hidden_dim=n_unit))
    elif method == 'rsgcn':
        print('Train RSGCN model...')
        predictor = GraphConvPredictor(
            RSGCN(out_dim=n_unit, hidden_dim=n_unit, n_layers=conv_layers),
            MLP(out_dim=class_num, hidden_dim=n_unit))
    else:
        raise ValueError('[ERROR] Invalid method {}'.format(method))

    train_iter = iterators.SerialIterator(train, args.batchsize)
    val_iter = iterators.SerialIterator(val,
                                        args.batchsize,
                                        repeat=False,
                                        shuffle=False)

    metrics_fun = molnet_default_config[dataset_name]['metrics']
    loss_fun = molnet_default_config[dataset_name]['loss']
    task_type = molnet_default_config[dataset_name]['task_type']
    if task_type == 'regression':
        model = Regressor(predictor,
                          lossfun=loss_fun,
                          metrics_fun=metrics_fun,
                          device=args.gpu)
        # TODO(nakago): Use standard scaler for regression task
    elif task_type == 'classification':
        model = Classifier(predictor,
                           lossfun=loss_fun,
                           metrics_fun=metrics_fun,
                           device=args.gpu)
    else:
        raise NotImplementedError(
            'Not implemented task_type = {}'.format(task_type))

    optimizer = optimizers.Adam()
    optimizer.setup(model)

    updater = training.StandardUpdater(train_iter,
                                       optimizer,
                                       device=args.gpu,
                                       converter=concat_mols)
    trainer = training.Trainer(updater, (args.epoch, 'epoch'), out=args.out)
    trainer.extend(
        E.Evaluator(val_iter, model, device=args.gpu, converter=concat_mols))
    trainer.extend(E.snapshot(), trigger=(args.epoch, 'epoch'))
    trainer.extend(E.LogReport())
    print_report_targets = ['epoch', 'main/loss', 'validation/main/loss']
    if metrics_fun is not None and type(metrics_fun) == dict:
        for m_k in metrics_fun.keys():
            print_report_targets.append('main/' + m_k)
            print_report_targets.append('validation/main/' + m_k)
    if task_type == 'classification':
        # Evaluation for train data takes time, skip for now.
        # trainer.extend(ROCAUCEvaluator(
        #     train_iter, model, device=args.gpu, eval_func=predictor,
        #     converter=concat_mols, name='train', raise_value_error=False))
        # print_report_targets.append('train/main/roc_auc')
        trainer.extend(
            ROCAUCEvaluator(val_iter,
                            model,
                            device=args.gpu,
                            eval_func=predictor,
                            converter=concat_mols,
                            name='val',
                            raise_value_error=False))
        print_report_targets.append('val/main/roc_auc')
    print_report_targets.append('elapsed_time')
    trainer.extend(E.PrintReport(print_report_targets))
    trainer.extend(E.ProgressBar())
    trainer.run()

    # --- save model ---
    protocol = args.protocol
    model.save_pickle(os.path.join(args.out, args.model_filename),
                      protocol=protocol)
Beispiel #14
0
def set_up_predictor(method,
                     fp_hidden_dim,
                     fp_out_dim,
                     conv_layers,
                     concat_hidden,
                     fp_dropout_rate,
                     fp_batch_normalization,
                     net_hidden_dims,
                     class_num,
                     weight_typing=True,
                     sim_method='mlp',
                     symmetric=None,
                     attn_model=None):

    sim_method_dict = {
        'mlp': 'multi-layered perceptron',
        'ntn': 'bilinear transform',
        'symmlp': 'symmetric perceptron',
        'hole': 'holographic embedding',
        'dist-mult': 'dist-mult',
    }

    method_dict = {
        'ggnn': 'GGNN',
        'nfp': 'NFP',
    }

    logging.info('Graph Embedding: {}'.format(method_dict.get(method, None)))
    logging.info('Link Prediction: {}'.format(
        sim_method_dict.get(sim_method, None)))

    lp = None
    if sim_method == 'mlp':
        lp = MLP(out_dim=class_num, hidden_dims=net_hidden_dims)

    elif sim_method == 'ntn':
        ntn_out_dim = 8
        lp = NTN(left_dim=fp_out_dim,
                 right_dim=fp_out_dim,
                 out_dim=class_num,
                 ntn_out_dim=ntn_out_dim,
                 hidden_dims=net_hidden_dims)

    elif sim_method == 'symmlp':
        lp = MLP(out_dim=class_num, hidden_dims=net_hidden_dims)

    elif sim_method == 'hole':
        lp = HolE(out_dim=class_num, hidden_dims=net_hidden_dims)

    elif sim_method == 'dist-mult':
        dm_out_dim = 8
        lp = DistMult(left_dim=fp_out_dim,
                      right_dim=fp_out_dim,
                      out_dim=class_num,
                      dm_out_dim=dm_out_dim,
                      hidden_dims=net_hidden_dims)
    else:
        raise ValueError(
            '[ERROR] Invalid link prediction model: {}'.format(method))

    attn = None
    scorer = 'bilinear'
    if attn_model == 'alter':
        attn_weight_tying = True
        logging.info('Using alternating co-attention')
        if attn_weight_tying:
            logging.info('Weight is tying')
        attn = AlternatingCoattention(hidden_dim=fp_hidden_dim,
                                      out_dim=fp_out_dim,
                                      head=8,
                                      weight_tying=True)
    elif attn_model == 'para':
        attn_weight_tying = True
        logging.info('Using parallel co-attention')
        logging.info('Scorer is {}'.format(scorer))
        if attn_weight_tying:
            logging.info('Weight is tying')
        attn = ParallelCoattention(hidden_dim=fp_hidden_dim,
                                   out_dim=fp_out_dim,
                                   head=1,
                                   activation=F.tanh,
                                   weight_tying=attn_weight_tying)
    elif attn_model == 'circ':
        logging.info('Using circular based parallel co-attention')
        attn = CircularParallelCoattention(hidden_dim=fp_hidden_dim,
                                           out_dim=fp_out_dim,
                                           activation=F.tanh)

    elif attn_model == 'vqa':
        logging.info('Using vqa fine-grained co-attention')
        attn = VQAParallelCoattention(hidden_dim=fp_hidden_dim * 2,
                                      out_dim=fp_out_dim,
                                      head=8)

    elif attn_model == 'pool':
        logging.info('Using pool fine-graind co-attention')
        attn = PoolingFineCoattention(hidden_dim=fp_hidden_dim * 2,
                                      out_dim=fp_out_dim)

    elif attn_model == 'lt':
        logging.info('Using lt fine-grained co-attention')
        attn = LinearTransformFineCoattention(hidden_dim=fp_hidden_dim * 2,
                                              out_dim=fp_out_dim)

    elif attn_model == 'nie':
        logging.info('Using nie fine-grained co-attention')
        logging.info('Using activation function tanh')
        # multiplied by 2 for concat
        attn = NieFineCoattention(hidden_dim=fp_hidden_dim * 2,
                                  out_dim=fp_out_dim,
                                  head=8,
                                  activation=F.tanh)

    elif attn_model == 'bimpm':
        logging.info('Using bimpm matching strategy')
        attn = BiMPM(hidden_dim=fp_hidden_dim,
                     out_dim=fp_out_dim,
                     head=fp_out_dim,
                     with_max_pool=True,
                     with_att_mean=True,
                     with_att_max=True,
                     aggr=F.sum)

    elif attn_model == 'global':
        logging.info('Using global coattention')
        attn = GlobalCoattention(hidden_dim=fp_hidden_dim,
                                 out_dim=fp_out_dim,
                                 weight_tying=True)

    elif attn_model == 'neural':
        logging.info('Using neural coattention')
        attn = NeuralCoattention(hidden_dim=fp_hidden_dim,
                                 out_dim=fp_out_dim,
                                 weight_tying=True)

    else:
        raise ValueError('[ERROR] Invalid Co-Attention Method.')

    siamese = True
    if not siamese:
        encoder_1, encoder_2 = None, None
    else:
        encoder = None
    if method == 'ggnn':
        if not weight_typing:
            logging.info('Weight is not tying')
        if fp_dropout_rate != 0.0:
            logging.info('Forward propagation dropout rate is {:.1f}'.format(
                fp_dropout_rate))
        if fp_batch_normalization:
            logging.info('Using batch normalization')
        if concat_hidden:
            logging.info('Using concatenation between layers')
        if not siamese:
            encoder_1 = GGNN(out_dim=fp_out_dim,
                             hidden_dim=fp_hidden_dim,
                             n_layers=conv_layers,
                             concat_hidden=concat_hidden,
                             weight_tying=weight_typing)
            encoder_2 = GGNN(out_dim=fp_out_dim,
                             hidden_dim=fp_hidden_dim,
                             n_layers=conv_layers,
                             concat_hidden=concat_hidden,
                             weight_tying=weight_typing)
        else:
            encoder = GGNN(out_dim=fp_out_dim,
                           hidden_dim=fp_hidden_dim,
                           n_layers=conv_layers,
                           concat_hidden=concat_hidden,
                           weight_tying=weight_typing)
    elif method == 'nfp':
        print('Training an NFP predictor...')
        encoder = NFP(out_dim=fp_out_dim,
                      hidden_dim=fp_hidden_dim,
                      n_layers=conv_layers,
                      concat_hidden=concat_hidden)

    else:
        raise ValueError('[ERROR] Invalid graph embedding encoder.')

    if siamese:
        predictor = GraphConvPredictorForPair(encoder,
                                              attn,
                                              lp,
                                              symmetric=symmetric,
                                              siamese=siamese,
                                              use_s_lstm=True,
                                              use_i_lstm=True)
    else:
        predictor = GraphConvPredictorForPair(encoder_1,
                                              attn,
                                              lp,
                                              symmetric=symmetric,
                                              siamese=siamese,
                                              another_graph_conv=encoder_2)
    return predictor
Beispiel #15
0
def main():
    # Supported preprocessing/network list
    method_list = ['nfp', 'ggnn', 'schnet', 'weavenet', 'rsgcn']
    scale_list = ['standardize', 'none']

    parser = argparse.ArgumentParser(
        description='Regression with own dataset.')
    parser.add_argument('datafile', type=str)
    parser.add_argument('--method', '-m', type=str, choices=method_list,
                        default='nfp')
    parser.add_argument('--label', '-l', nargs='+',
                        help='target label for regression')
    parser.add_argument('--scale', type=str, choices=scale_list,
                        default='standardize', help='Label scaling method')
    parser.add_argument('--conv-layers', '-c', type=int, default=4)
    parser.add_argument('--batchsize', '-b', type=int, default=32)
    parser.add_argument('--gpu', '-g', type=int, default=-1)
    parser.add_argument('--out', '-o', type=str, default='result')
    parser.add_argument('--epoch', '-e', type=int, default=20)
    parser.add_argument('--unit-num', '-u', type=int, default=16)
    parser.add_argument('--seed', '-s', type=int, default=777)
    parser.add_argument('--train-data-ratio', '-t', type=float, default=0.7)
    args = parser.parse_args()

    seed = args.seed
    train_data_ratio = args.train_data_ratio
    method = args.method
    if args.label:
        labels = args.label
        class_num = len(labels) if isinstance(labels, list) else 1
    else:
        sys.exit("Error: No target label is specified.")

    # Dataset preparation
    # Postprocess is required for regression task
    def postprocess_label(label_list):
        return numpy.asarray(label_list, dtype=numpy.float32)

    print('Preprocessing dataset...')
    preprocessor = preprocess_method_dict[method]()
    parser = CSVFileParser(preprocessor,
                           postprocess_label=postprocess_label,
                           labels=labels, smiles_col='SMILES')
    dataset = parser.parse(args.datafile)["dataset"]

    if args.scale == 'standardize':
        # Standard Scaler for labels
        ss = StandardScaler()
        labels = ss.fit_transform(dataset.get_datasets()[-1])
        dataset = NumpyTupleDataset(*(dataset.get_datasets()[:-1] + (labels,)))

    train_data_size = int(len(dataset) * train_data_ratio)
    train, val = split_dataset_random(dataset, train_data_size, seed)

    # Network
    n_unit = args.unit_num
    conv_layers = args.conv_layers
    if method == 'nfp':
        print('Train NFP model...')
        model = GraphConvPredictor(NFP(out_dim=n_unit, hidden_dim=n_unit,
                                       n_layers=conv_layers),
                                   MLP(out_dim=class_num, hidden_dim=n_unit))
    elif method == 'ggnn':
        print('Train GGNN model...')
        model = GraphConvPredictor(GGNN(out_dim=n_unit, hidden_dim=n_unit,
                                        n_layers=conv_layers),
                                   MLP(out_dim=class_num, hidden_dim=n_unit))
    elif method == 'schnet':
        print('Train SchNet model...')
        model = GraphConvPredictor(
            SchNet(out_dim=class_num, hidden_dim=n_unit, n_layers=conv_layers),
            None)
    elif method == 'weavenet':
        print('Train WeaveNet model...')
        n_atom = 20
        n_sub_layer = 1
        weave_channels = [50] * conv_layers
        model = GraphConvPredictor(
            WeaveNet(weave_channels=weave_channels, hidden_dim=n_unit,
                     n_sub_layer=n_sub_layer, n_atom=n_atom),
            MLP(out_dim=class_num, hidden_dim=n_unit))
    elif method == 'rsgcn':
        print('Train RSGCN model...')
        model = GraphConvPredictor(
            RSGCN(out_dim=n_unit, hidden_dim=n_unit, n_layers=conv_layers),
            MLP(out_dim=class_num, hidden_dim=n_unit))
    else:
        raise ValueError('[ERROR] Invalid method {}'.format(method))

    train_iter = I.SerialIterator(train, args.batchsize)
    val_iter = I.SerialIterator(val, args.batchsize,
                                repeat=False, shuffle=False)

    def scaled_abs_error(x0, x1):
        if isinstance(x0, Variable):
            x0 = cuda.to_cpu(x0.data)
        if isinstance(x1, Variable):
            x1 = cuda.to_cpu(x1.data)
        if args.scale == 'standardize':
            scaled_x0 = ss.inverse_transform(cuda.to_cpu(x0))
            scaled_x1 = ss.inverse_transform(cuda.to_cpu(x1))
            diff = scaled_x0 - scaled_x1
        elif args.scale == 'none':
            diff = cuda.to_cpu(x0) - cuda.to_cpu(x1)
        return numpy.mean(numpy.absolute(diff), axis=0)[0]

    classifier = L.Classifier(model, lossfun=F.mean_squared_error,
                              accfun=scaled_abs_error)

    if args.gpu >= 0:
        chainer.cuda.get_device_from_id(args.gpu).use()
        classifier.to_gpu()

    optimizer = O.Adam()
    optimizer.setup(classifier)

    updater = training.StandardUpdater(train_iter, optimizer, device=args.gpu,
                                       converter=concat_mols)
    trainer = training.Trainer(updater, (args.epoch, 'epoch'), out=args.out)
    trainer.extend(E.Evaluator(val_iter, classifier, device=args.gpu,
                               converter=concat_mols))
    trainer.extend(E.snapshot(), trigger=(args.epoch, 'epoch'))
    trainer.extend(E.LogReport())
    # Note that scaled errors are reported as (validation/)main/accuracy
    trainer.extend(E.PrintReport(['epoch', 'main/loss', 'main/accuracy',
                                  'validation/main/loss',
                                  'validation/main/accuracy',
                                  'elapsed_time']))
    trainer.extend(E.ProgressBar())
    trainer.run()

    # Example of prediction using trained model
    smiles = 'c1ccccc1'
    mol = Chem.MolFromSmiles(smiles)
    preprocessor = preprocess_method_dict[method]()
    standardized_smiles, mol = preprocessor.prepare_smiles_and_mol(mol)
    input_features = preprocessor.get_input_features(mol)
    atoms, adjs = concat_mols([input_features], device=args.gpu)
    prediction = model(atoms, adjs).data[0]
    print('Prediction for {}:'.format(smiles))
    for i, label in enumerate(args.label):
        print('{}: {}'.format(label, prediction[i]))