class_docstr: Temporal Entropy Model
class_docstr_tok: ["Temporal","Entropy","Model"]
docstr: Decompress strings
  
  Args:
      strings: list of strings, length should be seq_len_dec
      encoded: previous latents, passed to transformer
      shape: H, W, C
      encode_means: means from encode (compresss) step
      encode_scales: scales from encode (compresss) step
      use_output_from_encode: use encode_means and encode_scales from the encode
          step (not real compression), or use the transformer to compute them.
          Note there could be a discrepancy between the two due to the
          non-deterministic nature of transformers (which makes them suboptimal
          for pmf prediction and use in compression), so for research purposes it
          could be acceptable to use the output from the encoder.
  
  Returns:
      A tenosor of the decoded strings
docstr_tok: ["Decompress","strings","Args",":","strings",":","list","of","strings",",","length","should","be","seq_len_dec","encoded",":","previous","latents",",","passed","to","transformer","shape",":","H",",","W",",","C","encode_means",":","means","from","encode","(","compresss",")","step","encode_scales",":","scales","from","encode","(","compresss",")","step","use_output_from_encode",":","use","encode_means","and","encode_scales","from","the","encode","step","(","not","real","compression",")",",","or","use","the","transformer","to","compute","them",".","Note","there","could","be","a","discrepancy","between","the","two","due","to","the","non-deterministic","nature","of","transformers","(","which","makes","them","suboptimal","for","pmf","prediction","and","use","in","compression",")",",","so","for","research","purposes","it","could","be","acceptable","to","use","the","output","from","the","encoder",".","Returns",":","A","tenosor","of","the","decoded","strings"]
code: def _decode(
      self,
      strings: List[str],
      encoded: Tensor,
      shape: Sequence[int],
      encode_means: Tensor,
      encode_scales: Tensor,
      use_output_from_encode: bool = True,
  ) -> Tensor:
      """
      Decompress strings
  
      Args:
          strings: list of strings, length should be seq_len_dec
          encoded: previous latents, passed to transformer
          shape: H, W, C
          encode_means: means from encode (compresss) step
          encode_scales: scales from encode (compresss) step
          use_output_from_encode: use encode_means and encode_scales from the encode
              step (not real compression), or use the transformer to compute them.
              Note there could be a discrepancy between the two due to the
              non-deterministic nature of transformers (which makes them suboptimal
              for pmf prediction and use in compression), so for research purposes it
              could be acceptable to use the output from the encoder.
  
      Returns:
          A tenosor of the decoded strings
      """
      H, W, C = shape
      _device = encode_means.device
      fake_patched = self.patcher(
          torch.ones((1, C, H, W), device=_device), self.window_size_dec
      )  # placeholder object Patched(tensor, num_patches)
      decompressed = torch.full_like(
          fake_patched.tensor, fill_value=10.0
      )  # [b', seq_len_dec, C]
  
      prev_mean = None
      prev_scale = None
      for i in itertools.chain(range(self.seq_len_dec), [0]):
          if prev_mean is not None and prev_scale is not None:
              decoded_i = self.bottleneck.decompress(
                  strings=strings.pop(0),
                  scales=prev_scale.unsqueeze(0),
                  means=prev_mean.unsqueeze(0),  #
              )  # decompressed i-th token, [b', C]
              decompressed[:, i - 1, :] = decoded_i
              if i == 0:
                  break
          # predict mean and scale for the i-th token, given previously decompressed
          mean_i, scale_i, _ = self._get_transformer_output(
              encoded_patched=encoded, latent_q_patched=decompressed
          )  # [b', seq_len_dec, C]x2
  
          target_mean, target_scale = (
              encode_means[:, i, :],
              encode_scales[:, i, :],
          )
          actual_mean, actual_scale = mean_i[:, i, :], scale_i[:, i, :]
  
          if use_output_from_encode:
              # NOTE: To deal with non-deterministm of the transformer, use the means
              # and the scales from encoding, and log errors. Note that this cannot
              # be done in practice.
              prev_mean = target_mean  # mean of current token, [b', C]
              prev_scale = (
                  target_scale  # scale of current token, [b', C]
              )
              error_mean = (actual_mean - target_mean).abs().sum()
              error_scale = (actual_scale - target_scale).abs().sum()
              percent_of_total_mean = (
                  error_mean / target_mean.abs().sum()
              )
              percent_of_total_scale = (
                  error_scale / target_scale.abs().sum()
              )
              if (
                  percent_of_total_mean > 0.01
                  or percent_of_total_scale > 0.01
              ):
                  print(
                      "Larger than expected discrepancy in transformer output found! ",
                      f"Decode step {i}: mean error = {100*percent_of_total_mean}%, ",
                      f"mean error = {100*percent_of_total_scale}%",
                      file=sys.stderr,
                  )
          else:
              prev_mean = actual_mean  # mean of current token, [b', C]
              prev_scale = (
                  actual_scale  # scale of current token, [b', C]
              )
  
      assert not strings
      return self.patcher.unpatch(
          x_patched=(decompressed, fake_patched.num_patches),
          crop=(H, W),
          channels_last=True,
      )
  
imports: import itertools
  import sys
  from typing import Dict, List, NamedTuple, Optional, Sequence, Tuple
  import torch
  import torch.nn
  from torch import Tensor
  from .bottlenecks import GsnConditionalLocScaleShift
  from .entropy_model_layers import EncoderSection, LearnedPosition, StartSym, Transformer
  from .layers_utils import make_embedding
  from .patcher import Patcher
label_desc: Use image node_id 12 for calling the VCTEntropyModel obj's underlying member method code with example usage: obj._decode(strings, encoded, shape, encode_means, encode_scales, use_output_from_encode) and returns: self