code: def _construct_baseline(node, guide_site, downstream_cost):
      # XXX should the average baseline be in the param store as below?
  
      baseline = 0.0
      baseline_loss = 0.0
  
      (
          nn_baseline,
          nn_baseline_input,
          use_decaying_avg_baseline,
          baseline_beta,
          baseline_value,
      ) = _get_baseline_options(guide_site)
  
      use_nn_baseline = nn_baseline is not None
      use_baseline_value = baseline_value is not None
  
      use_baseline = (
          use_nn_baseline
          or use_decaying_avg_baseline
          or use_baseline_value
      )
  
      assert not (
          use_nn_baseline and use_baseline_value
      ), "cannot use baseline_value and nn_baseline simultaneously"
      if use_decaying_avg_baseline:
          dc_shape = downstream_cost.shape
          param_name = "__baseline_avg_downstream_cost_" + node
          with torch.no_grad():
              avg_downstream_cost_old = pyro.param(
                  param_name,
                  torch.zeros(
                      dc_shape, device=guide_site["value"].device
                  ),
              )
              avg_downstream_cost_new = (
                  (1 - baseline_beta) * downstream_cost
                  + baseline_beta * avg_downstream_cost_old
              )
          pyro.get_param_store()[param_name] = avg_downstream_cost_new
          baseline += avg_downstream_cost_old
      if use_nn_baseline:
          # block nn_baseline_input gradients except in baseline loss
          baseline += nn_baseline(detach(nn_baseline_input))
      elif use_baseline_value:
          # it's on the user to make sure baseline_value tape only points to baseline params
          baseline += baseline_value
      if use_nn_baseline or use_baseline_value:
          # accumulate baseline loss
          baseline_loss += torch.pow(
              downstream_cost.detach() - baseline, 2.0
          ).sum()
  
      if use_baseline:
          if downstream_cost.shape != baseline.shape:
              raise ValueError(
                  "Expected baseline at site {} to be {} instead got {}".format(
                      node, downstream_cost.shape, baseline.shape
                  )
              )
  
      return use_baseline, baseline_loss, baseline
  
imports: import weakref
  from collections import defaultdict
  from operator import itemgetter
  import torch
  import pyro
  import pyro.ops.jit
  from pyro.distributions.util import detach, is_identically_zero
  from pyro.infer import ELBO
  from pyro.infer.enum import get_importance_trace
  from pyro.infer.util import MultiFrameTensor, get_plate_stacks, is_validation_enabled, torch_backward, torch_item
  from pyro.ops.provenance import detach_provenance, get_provenance, track_provenance
  from pyro.poutine.messenger import Messenger
  from pyro.poutine.subsample_messenger import _Subsample
  from pyro.util import check_if_enumerated, warn_if_nan
label_desc: Use image node_id 2 for calling a global function with example usage: _construct_baseline(node, guide_site, downstream_cost) and returns: use_baseline,  baseline_loss,  baseline