class_docstr: Experiment runner.
  
  This class implements routines to train, evaluate and make predictions from models.
class_docstr_tok: ["Experiment","runner",".","This","class","implements","routines","to","train",",","evaluate","and","make","predictions","from","models","."]
code: def _run(
      run_type,
      model,
      dataset,
      criterion=None,
      optimizer=None,
      train=False,
      device=None,
      batch_size=32,
      batch_callback=None,
      epoch_callback=None,
      progress_style="bar",
      log_freq=5,
      sort_in_buckets=None,
      return_predictions=False,
      **kwargs,
  ):
      if device is None:
          device = "cuda" if torch.cuda.is_available() else "cpu"
      elif device == "gpu":
          device = "cuda"
  
      sort_in_buckets = train
      run_iter = MatchingIterator(
          dataset,
          model.meta,
          train,
          batch_size=batch_size,
          device=device,
          sort_in_buckets=sort_in_buckets,
      )
  
      model = model.to(device)
      if criterion:
          criterion = criterion.to(device)
  
      if train:
          model.train()
      else:
          model.eval()
  
      epoch = model.epoch
      datatime = 0
      runtime = 0
      cum_stats = Statistics()
      stats = Statistics()
      predictions = []
      id_attr = model.meta.id_field
      label_attr = model.meta.label_field
  
      if train and epoch == 0:
          print(
              "* Number of trainable parameters:",
              tally_parameters(model),
          )
  
      epoch_str = "Epoch {0:d}".format(epoch + 1)
      print("===> ", run_type, epoch_str)
      batch_end = time.time()
  
      # The tqdm-bar for Jupyter notebook is under development.
      if progress_style == "tqdm-bar":
          pbar = tqdm(
              total=len(run_iter) // log_freq,
              bar_format="{l_bar}{bar}{postfix}",
              file=sys.stdout,
          )
  
      # Use the pyprind bar as the default progress bar.
      if progress_style == "bar":
          pbar = pyprind.ProgBar(
              len(run_iter) // log_freq, bar_char="█", width=30
          )
  
      for batch_idx, batch in enumerate(run_iter):
          batch_start = time.time()
          datatime += batch_start - batch_end
  
          output = model(batch)
  
          # from torchviz import make_dot, make_dot_from_trace
          # dot = make_dot(output.mean(), params=dict(model.named_parameters()))
          # pdb.set_trace()
  
          loss = float("NaN")
          if criterion:
              loss = criterion(output, getattr(batch, label_attr))
  
          if hasattr(batch, label_attr):
              scores = Runner._compute_scores(
                  output, getattr(batch, label_attr)
              )
          else:
              scores = [0] * 4
  
          cum_stats.update(float(loss), *scores)
          stats.update(float(loss), *scores)
  
          if return_predictions:
              for idx, id in enumerate(getattr(batch, id_attr)):
                  predictions.append((id, float(output[idx, 1].exp())))
  
          if (batch_idx + 1) % log_freq == 0:
              if progress_style == "log":
                  Runner._print_stats(
                      run_type,
                      epoch + 1,
                      batch_idx + 1,
                      len(run_iter),
                      stats,
                      cum_stats,
                  )
              elif progress_style == "tqdm-bar":
                  pbar.update()
                  Runner._set_pbar_status(pbar, stats, cum_stats)
              elif progress_style == "bar":
                  pbar.update()
              stats = Statistics()
  
          if train:
              model.zero_grad()
              loss.backward()
  
              if not optimizer.params:
                  optimizer.set_parameters(model.named_parameters())
              optimizer.step()
  
          batch_end = time.time()
          runtime += batch_end - batch_start
  
      if progress_style == "tqdm-bar":
          pbar.close()
      elif progress_style == "bar":
          sys.stderr.flush()
  
      Runner._print_final_stats(epoch + 1, runtime, datatime, cum_stats)
  
      if return_predictions:
          return predictions
      else:
          return cum_stats.f1()
  
imports: import copy
  import logging
  import sys
  import time
  import warnings
  from collections import OrderedDict
  import pandas
  import pyprind
  import torch
  from tqdm import tqdm
  from .data import MatchingIterator
  from .optim import Optimizer, SoftNLLLoss
  from .utils import tally_parameters
label_desc: Use image node_id 5 for calling the Runner obj's underlying member method code with example usage: obj._run(run_type, model, dataset, criterion, optimizer, train, device, batch_size, batch_callback, epoch_callback, progress_style, log_freq, sort_in_buckets, return_predictions) and returns: predictions, cum_stats