code: def train_and_log(
      model,
      optimizer,
      batch_size=128,
      # this is equal to the ENTIRE test set, each time.
      measure_batch_size=10000,
      batches=5,
      measure_every=1,
      local_path: Optional[str] = None,
      gcloud_path: Optional[str] = None,
      tensorboard_path: Optional[str] = None,
  ):
      """Run the training loop on all data and record measurements as we go."""
  
      # Get the data downloaded and prepared, batched by the supplied batch size.
      data = prepare_mnist(batch_size)
      batched_training = data["batched"]
  
      # These are the train and test sets, not batched at all. We have these for
      # metric reporting purposes.
      train = data["train"]
      test = data["test"]
  
      # This is equivalent to batched_training.take(batches), but wrapped with a
      # fancy progress bar.
      meter = tqdm.tqdm(
          batched_training.take(batches),
          total=batches,
          unit="batch",
          desc="training",
      )
  
      job_name = f"{getpass.getuser()}_{u.uuid()}"
      tqdm.tqdm.write(f"Job Name: {job_name}")
  
      # this is the mutable map where the MemoryReporter will keep its data.
      metrics = {}
  
      # This is the base reporter, plus the map of prefix => prefixed reporter. The
      # code below only uses the map to record measurements, but it could just as
      # easily have used base directly.
      base, reporters = build_reporters(
          job_name,
          metrics,
          local_path=local_path,
          gcloud_path=gcloud_path,
          tensorboard_path=tensorboard_path,
      )
  
      def should_measure(step):
          """Returns true if we should trigger a measurement for the supplied step, false
          otherwise.
  
          """
          return step % measure_every == 0
  
      def measure(step):
          """This function gets our record_measurements function to happen only every so
          often. The reason to gate the measurement this way, vs using a filter_step
          call on the reporter itself, is that the calculation of data that we want
          to report at ALL takes a long time.
  
          """
          if should_measure(step):
              record_measurements(
                  step,
                  reporters,
                  measure_batch_size,
                  model,
                  train,
                  test,
              )
  
      # For good measure, we make two MORE reporter instances with new prefixes.
      # We'll use batch_reporter inside the training loop to record stats on the
      # training loop process itself.
      batch_reporter = reporters["train"].with_prefix("batch")
  
      # This is how we can gate the reporter itself, using filter_step. This will
      # get the same data as batch_reporter, but with a different prefix; it will
      # only send measurements down the line every measure_every steps.
      limited_batch = (
          reporters["train"]
          .filter_step(lambda s: s % measure_every == 0)
          .with_prefix(f"batch_every_{measure_every}")
      )
  
      # Get initial measurements on the randomized model's performance before we've
      # trained at all.
      measure(0)
  
      # enter the training loop.
      for step, batch in enumerate(meter, 1):
          # for every batch... go get the images and labels.
          images = batch["image"]
          labels = batch["label"]
  
          # Perform the training step, and get back loss and accuracy for the current
          # batch.
          metadata = train_step(model, optimizer, images, labels)
  
          # Perform measurements on the test and training steps, if we pass the gate.
          measure(step)
  
          # Now we ALSO report the batch training steps.
          batch_reporter.report_all(step, metadata)
          limited_batch.report_all(step, metadata)
  
      # Once the loop is over, close the reporter and return the final mutable
      # metric store for graphing in-process.
      base.close()
      return metrics
  
imports: from __future__ import division, print_function
  import getpass
  from typing import Dict, Optional
  import fs
  import tensorflow
  import tensorflow_datasets
  import tqdm
  import uv
  import uv.tensorflow.reporter
  import uv.util
  from absl import app
  from uv.fs.reporter import FSReporter
  from uv.mlflow.reporter import MLFlowReporter
  from trainer import cli
label_desc: Use image node_id 14 for calling a global function with example usage: train_and_log(model, optimizer, batch_size, measure_batch_size, batches, measure_every, local_path, gcloud_path, tensorboard_path) and returns: metrics, unknown