class_docstr: A memory efficient optimizer for memory-efficient variables.
  
  We employ the following techniques:
   - 16-bit fixed-point quantization
   - inline updates during backprop, instead of through the optimizer.  This
     keeps the gradients from staying around in memory.
   - momentum is optional - saves a slot if it is off (beta1=0.0).
   - "factored second-moment accumulator"
      (keep row-wise and col-wise averages instead of full accumulator)
   - tighter control over operation ordering to make sure that only a small
     portion of the decompressed variables and of the variable gradients
     are resident in memory at any given time.
  
  All together these techniques reduce the memory footprint per parameter to
  a little over 2 bytes, allowing for roughly 4B parameters per GPU.   This is
  roughly an 8x improvement over the naive version.
  
  Usage:
  
  Diet variables should be created with the
  DietAdamOptimizer.get_variable() method.  The resulting variables
  have extra fields pointing to the optimizer and to the accumulator
  slots.
  
  The variable is kept in quantized form, so you need to call
  var.optimizer.dequantize(var) to get the value.
  
  The variables are created with trainable=False, so that they will
  not be optimized by an ordinary optimizer.  Instead, the user is
  responsible for making sure that var.optimizer.update(var, grad) is
  called during backprop.  The reason for this inline update is to
  avoid keeping around the gradients for all variables at once.  This
  is done with the clever use of defuns and control dependencies.  See
  diet_expert() for an example of how all of this is done.
  
  To facilitate fixed-point quantization and to make it easier to
  choose a learning rate, all variables are initialized with unit
  normal initialization.  If you want smaller values, downscale on the
  outside.
docstr: Create the factorized Adam accumulators for diet variables.
docstr_tok: ["Create","the","factorized","Adam","accumulators","for","diet","variables","."]
code: def create_slots(self, var):
      """Create the factorized Adam accumulators for diet variables."""
      params = self.params
      shape = var.get_shape().as_list()
  
      if not hasattr(params, "slots"):
          params.slots = defaultdict(dict)
  
      name = var.op.name
      slots = params.slots[name]
  
      if params.factored_second_moment_accumulator and len(shape) == 2:
          slots["adam_vr"] = tf.get_variable(
              name + "_adam_vr",
              [shape[0], 1],
              trainable=False,
              initializer=tf.zeros_initializer(),
          )
          slots["adam_vc"] = tf.get_variable(
              name + "_adam_vc",
              [1, shape[1]],
              trainable=False,
              initializer=tf.zeros_initializer(),
          )
      else:
          slots["adam_v"] = tf.get_variable(
              name + "_adam_v",
              shape,
              trainable=False,
              initializer=tf.zeros_initializer(),
          )
      if params.beta1 != 0.0:
          slots["adam_m"] = tf.get_variable(
              name + "_adam_m",
              shape,
              trainable=False,
              initializer=tf.zeros_initializer(),
          )
  
imports: from collections import defaultdict
  import copy
  import math
  from tensor2tensor.layers import common_layers
  from tensor2tensor.utils import hparam
  import tensorflow.compat.v1
label_desc: Use image node_id 1 for calling the DietAdamOptimizer obj's underlying member method code with example usage: obj.create_slots(var) without return types