code: def _marginal_loss(model, guide, observation_labels, target_labels):
      """Marginal loss: to evaluate directly use `marginal_eig` setting `num_steps=0`."""
  
      def loss_fn(design, num_particles, evaluation=False, **kwargs):
          expanded_design = lexpand(design, num_particles)
  
          # Sample from p(y | d)
          trace = poutine.trace(model).get_trace(expanded_design)
          y_dict = {
              l: trace.nodes[l]["value"] for l in observation_labels
          }
  
          # Run through q(y | d)
          conditional_guide = pyro.condition(guide, data=y_dict)
          cond_trace = poutine.trace(conditional_guide).get_trace(
              expanded_design, observation_labels, target_labels
          )
          cond_trace.compute_log_prob()
  
          terms = -sum(
              cond_trace.nodes[l]["log_prob"]
              for l in observation_labels
          )
  
          # At eval time, add p(y | theta, d) terms
          if evaluation:
              trace.compute_log_prob()
              terms += sum(
                  trace.nodes[l]["log_prob"] for l in observation_labels
              )
  
          return _safe_mean_terms(terms)
  
      return loss_fn
  
imports: import math
  import warnings
  import torch
  import pyro
  from pyro import poutine
  from pyro.contrib.oed.search import Search
  from pyro.contrib.util import lexpand
  from pyro.infer import SVI, EmpiricalMarginal, Importance
  from pyro.infer.autoguide.utils import mean_field_entropy
  from pyro.util import torch_isinf, torch_isnan
label_desc: Use image node_id 18 for calling a global function with example usage: _marginal_loss(model, guide, observation_labels, target_labels) and returns: loss_fn, _safe_mean_terms