code: def _lfire_loss(
      model_marginal,
      model_conditional,
      h,
      observation_labels,
      target_labels,
  ):
      """LFIRE loss: to evaluate directly use `lfire_eig` setting `num_steps=0`."""
  
      def loss_fn(design, num_particles, evaluation=False, **kwargs):
          try:
              pyro.module("h", h)
          except AssertionError:
              pass
  
          expanded_design = lexpand(design, num_particles)
          model_conditional_trace = poutine.trace(
              model_conditional
          ).get_trace(expanded_design)
  
          if not evaluation:
              model_marginal_trace = poutine.trace(
                  model_marginal
              ).get_trace(expanded_design)
  
              h_joint = h(
                  expanded_design,
                  model_conditional_trace,
                  observation_labels,
                  target_labels,
              )
              h_independent = h(
                  expanded_design,
                  model_marginal_trace,
                  observation_labels,
                  target_labels,
              )
  
              terms = torch.nn.functional.softplus(
                  -h_joint
              ) + torch.nn.functional.softplus(h_independent)
              return _safe_mean_terms(terms)
  
          else:
              h_joint = h(
                  expanded_design,
                  model_conditional_trace,
                  observation_labels,
                  target_labels,
              )
              return _safe_mean_terms(h_joint)
  
      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 20 for calling a global function with example usage: _lfire_loss(model_marginal, model_conditional, h, observation_labels, target_labels) and returns: loss_fn, _safe_mean_terms, _safe_mean_terms