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
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