Beispiel #1
0
def make_training_step_method(classifier,
                              num_positive_regions,
                              positive_fraction,
                              lr=1e-3,
                              l2=0,
                              method='GE-binomial',
                              pi=0,
                              slack=-1,
                              autoencoder=0):
    import topaz.methods as methods

    criteria = nn.BCEWithLogitsLoss()
    optim = torch.optim.Adam

    # pi sets the expected fraction of positives
    # but during training, we iterate over unlabeled data with labeled positives removed
    # therefore, we expected the fraction of positives in the unlabeled data
    # to be pi - fraction of labeled positives
    # if we are using the 'GE-KL' or 'GE-binomial' loss functions
    p_observed = positive_fraction
    if pi <= p_observed and method in ['GE-KL', 'GE-binomial']:
        # if pi <= p_observed, then we think the unlabeled data is all negatives
        # report this to the user and switch method to 'PN' if it isn't already
        print(
            'WARNING: pi={} but the observed fraction of positives is {} and method is set to {}.'
            .format(pi, p_observed, method),
            file=sys.stderr)
        print('WARNING: setting method to PN with pi={} instead.'.format(
            p_observed),
              file=sys.stderr)
        print('WARNING: if you meant to use {}, please set pi > {}.'.format(
            method, p_observed),
              file=sys.stderr)
        pi = p_observed
        method = 'PN'
    elif method in ['GE-KL', 'GE-binomial']:
        pi = pi - p_observed

    split = 'pn'
    if method == 'PN':
        optim = optim(classifier.parameters(), lr=lr)
        trainer = methods.PN(classifier,
                             optim,
                             criteria,
                             pi=pi,
                             l2=l2,
                             autoencoder=autoencoder)

    elif method == 'GE-KL':
        if slack < 0:
            slack = 10
        optim = optim(classifier.parameters(), lr=lr)
        trainer = methods.GE_KL(classifier,
                                optim,
                                criteria,
                                pi,
                                l2=l2,
                                slack=slack)

    elif method == 'GE-binomial':
        if slack < 0:
            slack = 1
        optim = optim(classifier.parameters(), lr=lr)
        trainer = methods.GE_binomial(classifier,
                                      optim,
                                      criteria,
                                      pi,
                                      l2=l2,
                                      slack=slack,
                                      autoencoder=autoencoder)

    elif method == 'PU':
        split = 'pu'
        optim = optim(classifier.parameters(), lr=lr)
        trainer = methods.PU(classifier,
                             optim,
                             criteria,
                             pi,
                             l2=l2,
                             autoencoder=autoencoder)

    else:
        raise Exception('Invalid method: ' + method)

    return trainer, criteria, split
Beispiel #2
0
def make_training_step_method(classifier, num_positive_regions,
                              positive_fraction, args):
    import topaz.methods as methods

    criteria = nn.BCEWithLogitsLoss()
    optim = torch.optim.Adam
    lr = args.learning_rate
    l2 = args.l2
    pi = args.pi
    slack = args.slack
    split = 'pn'

    if args.method == 'PN':
        optim = optim(classifier.parameters(), lr=lr)
        trainer = methods.PN(classifier,
                             optim,
                             criteria,
                             pi=pi,
                             l2=l2,
                             autoencoder=args.autoencoder)

    elif args.method == 'GE-KL':
        #split = 'pu'
        if slack < 0:
            slack = 10 * num_positive_regions
        assert positive_fraction <= pi
        pi = pi - positive_fraction
        optim = optim(classifier.parameters(), lr=lr)
        trainer = methods.GE_KL(classifier,
                                optim,
                                criteria,
                                pi,
                                l2=l2,
                                slack=slack)

    elif args.method == 'GE-binomial':
        #split = 'pu'
        if slack < 0:
            slack = 1
        assert positive_fraction <= pi
        pi = pi - positive_fraction
        optim = optim(classifier.parameters(), lr=lr)
        trainer = methods.GE_binomial(classifier,
                                      optim,
                                      criteria,
                                      pi,
                                      l2=l2,
                                      slack=slack,
                                      autoencoder=args.autoencoder)

    elif args.method == 'PU':
        split = 'pu'
        optim = optim(classifier.parameters(), lr=lr)
        trainer = methods.PU(classifier,
                             optim,
                             criteria,
                             pi,
                             l2=l2,
                             autoencoder=args.autoencoder)

    else:
        raise Exception('Invalid method: ' + args.method)

    return trainer, criteria, split