class_docstr: A class to wrap training code.
docstr: Train the language model for 400 steps of minibatches of 64
  examples.
  
  Args:
      max_step: Used to run extra training steps as a warm-up.
      dag: If not None, is used instead of calling sample().
  
  BPTT is truncated at 35 timesteps.
  
  For each weight update, gradients are estimated by sampling M models
  from the fixed controller policy, and averaging their gradients
  computed on a batch of training data.
code: def train_shared(self, max_step=None, dag=None):
      """Train the language model for 400 steps of minibatches of 64
      examples.
  
      Args:
          max_step: Used to run extra training steps as a warm-up.
          dag: If not None, is used instead of calling sample().
  
      BPTT is truncated at 35 timesteps.
  
      For each weight update, gradients are estimated by sampling M models
      from the fixed controller policy, and averaging their gradients
      computed on a batch of training data.
      """
      model = self.shared
      model.train()
      self.controller.eval()
  
      hidden = self.shared.init_hidden(self.args.batch_size)
  
      if max_step is None:
          max_step = self.args.shared_max_step
      else:
          max_step = min(self.args.shared_max_step, max_step)
  
      abs_max_grad = 0
      abs_max_hidden_norm = 0
      step = 0
      raw_total_loss = 0
      total_loss = 0
      train_idx = 0
      # TODO(brendan): Why - 1 - 1?
      while train_idx < self.train_data.size(0) - 1 - 1:
          if step > max_step:
              break
  
          dags = (
              dag
              if dag
              else self.controller.sample(self.args.shared_num_sample)
          )
          inputs, targets = self.get_batch(
              self.train_data, train_idx, self.max_length
          )
  
          loss, hidden, extra_out = self.get_loss(
              inputs, targets, hidden, dags
          )
          hidden.detach_()
          raw_total_loss += loss.data
  
          loss += _apply_penalties(extra_out, self.args)
  
          # update
          self.shared_optim.zero_grad()
          loss.backward()
  
          h1tohT = extra_out["hiddens"]
          new_abs_max_hidden_norm = utils.to_item(
              h1tohT.norm(dim=-1).data.max()
          )
          if new_abs_max_hidden_norm > abs_max_hidden_norm:
              abs_max_hidden_norm = new_abs_max_hidden_norm
              logger.info(f"max hidden {abs_max_hidden_norm}")
          abs_max_grad = _check_abs_max_grad(abs_max_grad, model)
          torch.nn.utils.clip_grad_norm(
              model.parameters(), self.args.shared_grad_clip
          )
          self.shared_optim.step()
  
          total_loss += loss.data
  
          if ((step % self.args.log_step) == 0) and (step > 0):
              self._summarize_shared_train(total_loss, raw_total_loss)
              raw_total_loss = 0
              total_loss = 0
  
          step += 1
          self.shared_step += 1
          train_idx += self.max_length
  
imports: import contextlib
  import glob
  import math
  import os
  import numpy
  import scipy.signal
  from tensorboard import TensorBoard
  import torch
  from torch import nn
  import torch.nn.parallel
  from torch.autograd import Variable
  import models
  import utils
label_desc: Use image node_id 5 for calling the Trainer obj's underlying member method code with example usage: obj.train_shared(max_step, dag) without return types