class_docstr: Categorical distribution, for discrete integer actions (specification key: `categorical`).
  
  Args:
      temperature_mode ("predicted" | "global"): Whether to predict the temperature via a linear
          transformation of the state embedding, or to parametrize the temperature by a separate
          set of trainable weights
          (<span style="color:#00C000"><b>default</b></span>: default temperature of 1).
      skip_linear (bool): Whether to not add the implicit linear logits layer, requires suitable
          network output shape according to action space, not compatible with temperature_mode
          (<span style="color:#00C000"><b>default</b></span>: false).
      name (string): <span style="color:#0000C0"><b>internal use</b></span>.
      action_spec (specification): <span style="color:#0000C0"><b>internal use</b></span>.
      input_spec (specification): <span style="color:#0000C0"><b>internal use</b></span>.
class_docstr_tok: ["Categorical","distribution",",","for","discrete","integer","actions","(","specification","key",":","`","categorical","`",")",".","Args",":","temperature_mode","(","``","predicted","''","|","``","global","''",")",":","Whether","to","predict","the","temperature","via","a","linear","transformation","of","the","state","embedding",",","or","to","parametrize","the","temperature","by","a","separate","set","of","trainable","weights","(","<","span","style=","''","color",":","#","00C000","''",">","<","b",">","default","<","\/b",">","<","\/span",">",":","default","temperature","of","1",")",".","skip_linear","(","bool",")",":","Whether","to","not","add","the","implicit","linear","logits","layer",",","requires","suitable","network","output","shape","according","to","action","space",",","not","compatible","with","temperature_mode","(","<","span","style=","''","color",":","#","00C000","''",">","<","b",">","default","<","\/b",">","<","\/span",">",":","false",")",".","name","(","string",")",":","<","span","style=","''","color",":","#","0000C0","''",">","<","b",">","internal","use","<","\/b",">","<","\/span",">",".","action_spec","(","specification",")",":","<","span","style=","''","color",":","#","0000C0","''",">","<","b",">","internal","use","<","\/b",">","<","\/span",">",".","input_spec","(","specification",")",":","<","span","style=","''","color",":","#","0000C0","''",">","<","b",">","internal","use","<","\/b",">","<","\/span",">","."]
code: def sample(self, *, parameters, temperature, independent):
      if self.temperature_mode is None:
          probabilities, logits, action_values = parameters.get(
              ("probabilities", "logits", "action_values")
          )
      else:
          probabilities, temp, logits, action_values = parameters.get(
              (
                  "probabilities",
                  "temperature",
                  "logits",
                  "action_values",
              )
          )
  
      # Distribution parameter summaries
      dependencies = list()
      if not independent:
  
          def fn_summary():
              axis = range(self.action_spec.rank + 1)
              probs = tf.math.reduce_mean(
                  input_tensor=probabilities, axis=axis
              )
              probs = [
                  probs[n] for n in range(self.action_spec.num_values)
              ]
              if self.temperature_mode is not None:
                  probs.append(
                      tf.math.reduce_mean(input_tensor=temp, axis=axis)
                  )
              return probs
  
          prefix = "distributions/" + self.name + "-probability"
          names = [
              prefix + str(n)
              for n in range(self.action_spec.num_values)
          ]
          names.append("distributions/" + self.name + "-temperature")
          dependencies.extend(
              self.summary(
                  label="distribution",
                  name=names,
                  data=fn_summary,
                  step="timesteps",
              )
          )
  
      # Distribution parameter tracking
      def fn_tracking():
          return tf.math.reduce_mean(input_tensor=probabilities, axis=0)
  
      dependencies.extend(
          self.track(
              label="distribution",
              name="probabilities",
              data=fn_tracking,
          )
      )
  
      if self.temperature_mode is not None:
  
          def fn_tracking():
              return tf.math.reduce_mean(input_tensor=temp, axis=0)
  
          dependencies.extend(
              self.track(
                  label="distribution",
                  name="temperature",
                  data=fn_tracking,
              )
          )
  
      epsilon = tf_util.constant(value=util.epsilon, dtype="float")
  
      def fn_mode():
          # Deterministic: maximum likelihood action
          action = tf.math.argmax(input=action_values, axis=-1)
          return tf_util.cast(x=action, dtype="int")
  
      def fn_sample():
          # Set logits to minimal value
          min_float = tf.fill(
              dims=tf.shape(input=logits),
              value=tf_util.get_dtype(type="float").min,
          )
          temp_logits = logits / (temperature + epsilon)
          temp_logits = tf.where(
              condition=(probabilities < epsilon),
              x=min_float,
              y=temp_logits,
          )
  
          # Non-deterministic: sample action using Gumbel distribution
          one = tf_util.constant(value=1.0, dtype="float")
          uniform_distribution = tf.random.uniform(
              shape=tf.shape(input=temp_logits),
              minval=epsilon,
              maxval=(one - epsilon),
              dtype=tf_util.get_dtype(type="float"),
          )
          # Second log numerically stable since log(1-eps) ~ -eps
          gumbel_distribution = -tf.math.log(
              x=-tf.math.log(x=uniform_distribution)
          )
          action = tf.math.argmax(
              input=(temp_logits + gumbel_distribution), axis=-1
          )
          return tf_util.cast(x=action, dtype="int")
  
      with tf.control_dependencies(control_inputs=dependencies):
          return tf.cond(
              pred=(temperature < epsilon),
              true_fn=fn_mode,
              false_fn=fn_sample,
          )
  
file_path: tensorforce/tensorforce/core/distributions/categorical.py
imports: import numpy
  import tensorflow
  from tensorforce import TensorforceError, util
  from tensorforce.core import layer_modules, TensorDict, TensorSpec, TensorsSpec, tf_function, tf_util
  from tensorforce.core.distributions import Distribution
label_desc: Use image node_id 6 for calling the Categorical obj's underlying member method code with example usage: obj.sample() and returns: tf, tf_util, tf_util, tf, probs, tf