code: def run_train(train_iter, valid_iter, model, tree_lstm, V):
      opt_struct = torch.optim.Adadelta(
          list(model.parameters()), lr=config["lr_struct"]
      )
      opt_params = torch.optim.Adadelta(
          list(tree_lstm.parameters()), lr=config["lr_params"]
      )
  
      model.train()
      tree_lstm.train()
      losses = []
      Dist = TreeCRF
      step = 0
      trees = None
      for epoch in range(100):
          print("Epoch", epoch)
  
          for i, ex in enumerate(train_iter):
              step += 1
              words, lengths = ex.word
              label = ex.label
              batch = label.shape[0]
              _, N = words.shape
              words = words.cuda()
  
              def tree_reward(spans, K):
                  new_spans = expand_spans(spans, words, K, V)
                  g, labels, indices, topo = TreeLSTM.spans_to_dgl(
                      new_spans
                  )
                  ret = tree_lstm(
                      g,
                      labels,
                      indices,
                      topo,
                      torch.cat([lengths for _ in range(K)]),
                  )
                  ret = ret.view(K, batch, -1)
                  return -ret[:, torch.arange(batch), label].view(
                      K, batch
                  )
  
              sc = SelfCritical(tree_reward)
              phi = model(words, lengths)
              dist = Dist(phi)
              structs, rewards, score, max_score = sc.forward(
                  dist, K=config["RL_K"]
              )
  
              if config["train_model"]:
                  opt_params.zero_grad()
                  score.mean().backward()
                  clip(tree_lstm.parameters())
                  opt_params.step()
                  opt_params.zero_grad()
  
              if config["method"] == "reinforce":
                  opt_struct.zero_grad()
                  entropy = dist.entropy
                  r = dist.log_prob(structs)
                  obj = rewards.mul(r).mean(-1).mean(-1)
                  policy = (
                      obj
                      - config["entropy"]
                      * entropy.div(lengths.float().cuda()).mean()
                  )
                  policy.backward()
                  clip(model.parameters())
                  opt_struct.step()
              losses.append(-max_score.mean().detach())
  
              # DEBUG
              if i % 50 == 9:
                  print(torch.tensor(losses).mean(), words.shape)
                  print("Round")
                  print("Entropy", entropy.mean().item())
                  print("Reward", rewards.mean().item())
                  if i % 1000 == 9:
                      valid_loss = valid_sup(
                          valid_iter, model, tree_lstm, V
                      )
                      fname = "/tmp/checkpoint.%s.%0d.%0d.%s" % (
                          NAME,
                          epoch,
                          i,
                          valid_loss,
                      )
                      torch.save((model, tree_lstm), fname)
                      wandb.save(fname)
                      trees = valid_show(valid_iter, model)
                  else:
                      print(valid_loss)
  
                  wandb.log(
                      {
                          "entropy": entropy.mean(),
                          "valid_loss": valid_loss,
                          "reward": rewards.mean(),
                          "step": step,
                          "tree": trees,
                          "reward_var": rewards.var(),
                          "loss": torch.tensor(losses).mean(),
                      }
                  )
                  losses = []
  
file_path: pytorch-struct/examples/tree.py
imports: from torch_struct import TreeCRF, SelfCritical
  import torchtext.data
  from torch_struct.data import ListOpsDataset, TokenBucket
  from torch_struct.networks import TreeLSTM, SpanLSTM
  import torch
  import torch.nn
  import wandb
label_desc: Use image node_id 4 for calling a global function with example usage: run_train(train_iter, valid_iter, model, tree_lstm, V) and returns: unknown