class_docstr: MCMC that computes required statistics in a streaming fashion. For this class no samples are retained
  but only aggregated statistics. This is useful for running memory expensive models where we care only
  about specific statistics (especially useful in a memory constrained environments like GPU).
  
  For available streaming ops please see :mod:`~pyro.ops.streaming`.
class_docstr_tok: ["MCMC","that","computes","required","statistics","in","a","streaming","fashion",".","For","this","class","no","samples","are","retained","but","only","aggregated","statistics",".","This","is","useful","for","running","memory","expensive","models","where","we","care","only","about","specific","statistics","(","especially","useful","in","a","memory","constrained","environments","like","GPU",")",".","For","available","streaming","ops","please","see",":","mod",":","`","~pyro.ops.streaming","`","."]
docstr: Run StreamingMCMC to compute required `self._statistics`.
code: def run(self, *args, **kwargs):
      """
      Run StreamingMCMC to compute required `self._statistics`.
      """
      self._args, self._kwargs = args, kwargs
      num_samples = [0] * self.num_chains
  
      with optional(
          pyro.validation_enabled(not self.disable_validation),
          self.disable_validation is not None,
      ):
          args = [
              arg.detach() if torch.is_tensor(arg) else arg
              for arg in args
          ]
          for x, chain_id in self.sampler.run(*args, **kwargs):
              if num_samples[chain_id] == 0:
                  # If transforms is not explicitly provided, infer automatically using
                  # model args, kwargs.
                  if self.transforms is None:
                      self._set_transforms(*args, **kwargs)
                  num_samples[chain_id] += 1
                  z_structure = x
              elif num_samples[chain_id] == self.num_samples + 1:
                  self._diagnostics[chain_id] = x
              else:
                  num_samples[chain_id] += 1
                  if self.num_chains > 1:
                      x_cloned = x.clone()
                      del x
                  else:
                      x_cloned = x
  
                  # unpack latent
                  pos = 0
                  z_acc = z_structure.copy()
                  for k in sorted(z_structure):
                      shape = z_structure[k]
                      next_pos = pos + shape.numel()
                      z_acc[k] = x_cloned[pos:next_pos].reshape(shape)
                      pos = next_pos
  
                  for name, z in z_acc.items():
                      if name in self.transforms:
                          z_acc[name] = self.transforms[name].inv(z)
  
                  self._statistics.update(
                      {
                          (chain_id, name): transformed_sample
                          for name, transformed_sample in z_acc.items()
                      }
                  )
  
      # terminate the sampler (shut down worker processes)
      self.sampler.terminate(True)
  
imports: import copy
  import json
  import logging
  import queue
  import signal
  import threading
  import warnings
  from abc import ABC, abstractmethod
  from collections import OrderedDict
  from typing import Dict
  import torch
  import torch.multiprocessing
  import pyro
  import pyro.poutine
  from pyro.infer.mcmc.hmc import HMC
  from pyro.infer.mcmc.logger import DIAGNOSTIC_MSG, ProgressBar, TqdmHandler, initialize_logger
  from pyro.infer.mcmc.nuts import NUTS
  from pyro.infer.mcmc.util import diagnostics, diagnostics_from_stats, print_summary, select_samples
  from pyro.ops.streaming import CountMeanVarianceStats, StatsOfDict, StreamingStats
  from pyro.util import optional
label_desc: Use image node_id 2 for calling the StreamingMCMC obj's underlying member method code with example usage: obj.run() without return types