示例#1
0
def run_epoch(data_loader, train_model, model, gen, optimizer, step, args):
    '''
    Train model for one pass of train data, and return loss, acccuracy
    '''
    eval_model = not train_model
    data_iter = data_loader.__iter__()

    losses = []
    obj_losses = []
    k_selection_losses = []
    k_continuity_losses = []
    preds = []
    probas = []
    golds = []
    losses = []
    texts = []
    rationales = []

    if train_model:
        model.train()
        gen.train()
    else:
        gen.eval()
        model.eval()

    num_batches_per_epoch = len(data_iter)
    if train_model:
        num_batches_per_epoch = min(len(data_iter), 10000)

    for _ in tqdm.tqdm(range(num_batches_per_epoch)):
        batch = data_iter.next()
        if train_model:
            step += 1
            if step % 100 == 0 or args.debug_mode:
                args.gumbel_temprature = max(
                    np.exp((step + 1) * -1 * args.gumbel_decay), .05)

        x_indx = learn.get_x_indx(batch, args, eval_model)
        text = batch['text']
        y = autograd.Variable(batch['y'], volatile=eval_model)

        if args.cuda:
            x_indx, y = x_indx.cuda(), y.cuda()

        if train_model:
            optimizer.zero_grad()

        if args.get_rationales:
            mask, z = gen(x_indx)
        else:
            mask = None

        logit, _ = model(x_indx, mask=mask)

        if args.use_as_tagger:
            logit = logit.view(-1, 2)
            y = y.view(-1)

        loss = get_loss(logit, y, args)
        obj_loss = loss

        if args.get_rationales:
            selection_cost, continuity_cost = gen.loss(mask, x_indx)
            loss += args.selection_lambda * selection_cost
            loss += args.continuity_lambda * continuity_cost

        if train_model:
            loss.backward()
            optimizer.step()

        if args.get_rationales:
            k_selection_losses.append(generic.tensor_to_numpy(selection_cost))
            k_continuity_losses.append(
                generic.tensor_to_numpy(continuity_cost))

        obj_losses.append(generic.tensor_to_numpy(obj_loss))
        losses.append(generic.tensor_to_numpy(loss))
        batch_softmax = F.softmax(logit, dim=-1).cpu()
        max_preds = torch.max(batch_softmax, 1)
        probas.extend(max_preds[0].view(y.size()).data.numpy())
        preds.extend(max_preds[1].view(y.size()).data.numpy())

        texts.extend(text)
        rationales.extend(learn.get_rationales(mask, text))

        if args.use_as_tagger:
            golds.extend(batch['y'].view(-1).numpy())
        else:
            golds.extend(batch['y'].numpy())

    epoch_metrics = metrics.get_metrics(preds, golds, args)

    epoch_stat = {'loss': np.mean(losses), 'obj_loss': np.mean(obj_losses)}

    for metric_k in epoch_metrics.keys():
        epoch_stat[metric_k] = epoch_metrics[metric_k]

    if args.get_rationales:
        epoch_stat['k_selection_loss'] = np.mean(k_selection_losses)
        epoch_stat['k_continuity_loss'] = np.mean(k_continuity_losses)

    return epoch_stat, step, losses, preds, golds, rationales, probas
示例#2
0
def run_epoch(data_loader, train_model, model, gen, optimizer, step, args):
    '''
    Train model for one pass of train data, and return loss, acccuracy
    '''
    eval_model = not train_model
    data_iter = data_loader.__iter__()

    losses = []
    obj_losses = []
    k_selection_losses = []
    k_continuity_losses = []
    preds = []
    golds = []
    losses = []

    if train_model:
        model.train()
        gen.train()
    else:
        gen.eval()
        model.eval()

    num_batches_per_epoch = len(data_iter)
    if train_model:
        num_batches_per_epoch = min(len(data_iter), 10000)

    for _ in tqdm.tqdm(range(num_batches_per_epoch)):
        batch = data_iter.next()
        if train_model:
            step += 1
            if  step % 100 == 0 or args.debug_mode:
                args.gumbel_temprature = max( np.exp((step+1) *-1* args.gumbel_decay), .05)

        x_indx = utils.get_x_indx(batch, args, eval_model)
        text = batch['text']
        indices = batch['i']
        y = autograd.Variable(batch['y'], volatile=eval_model)

        if args.cuda:
            x_indx, y = x_indx.cuda(), y.cuda()

        if train_model:
            optimizer.zero_grad()

        if args.get_rationales:
            mask, z = gen(x_indx)
        else:
            mask = None

        logit, _ = model(x_indx, mask=mask)


        loss = get_loss(logit, y, args)
        obj_loss = loss

        if args.get_rationales:
            selection_cost, continuity_cost = gen.loss(mask, x_indx)

            loss += args.selection_lambda* selection_cost
            loss += args.continuity_lambda* continuity_cost

        if train_model:
            loss.backward()
            optimizer.step()

        if args.get_rationales:
            k_selection_losses.append( generic.tensor_to_numpy(selection_cost))
            k_continuity_losses.append( generic.tensor_to_numpy(continuity_cost))

        obj_losses.append(generic.tensor_to_numpy(obj_loss))
        losses.append( generic.tensor_to_numpy(loss) )
        preds.extend(
            torch.max(logit.data,
                      1)[1].view(y.size()).cpu().numpy())  # Record predictions
        golds.extend(batch['y'].numpy())


    if args.objective  in ['cross_entropy', 'margin']:
        metric = sklearn.metrics.accuracy_score(y_true=golds, y_pred=preds)
        confusion_matrix = sklearn.metrics.confusion_matrix(y_true=golds,y_pred=preds)
    elif args.objective == 'mse':
        metric = sklearn.metrics.mean_squared_error(y_true=golds, y_pred=preds)
        confusion_matrix = "NA"

    epoch_stat = {
        'loss' : np.mean(losses),
        'obj_loss': np.mean(obj_losses),
        'metric':metric,
        'confusion_matrix': confusion_matrix 
    }

    if args.get_rationales:
        epoch_stat['k_selection_loss'] = np.mean(k_selection_losses)
        epoch_stat['k_continuity_loss'] = np.mean(k_continuity_losses)

    return epoch_stat, step,  losses, preds, golds