class_docstr: Invertible `TextEncoder` using word pieces with a byte-level fallback.
  
  Encoding is fully invertible because all out-of-vocab wordpieces are
  byte-encoded.
  
  The vocabulary is "trained" on a corpus and all wordpieces are stored in a
  vocabulary file. To generate a vocabulary from a corpus, use
  `tfds.deprecated.text.SubwordTextEncoder.build_from_corpus`.
  
  Typical usage:
  
  ```
  # Build
  encoder = tfds.deprecated.text.SubwordTextEncoder.build_from_corpus(
      corpus_generator, target_vocab_size=2**15)
  encoder.save_to_file(vocab_fname)
  
  # Load
  encoder = tfds.deprecated.text.SubwordTextEncoder.load_from_file(vocab_fname)
  ids = encoder.encode("hello world")
  text = encoder.decode([1, 2, 3, 4])
  ```
code: def _build_from_token_counts(
      cls,
      token_counts,
      min_token_count,
      reserved_tokens,
      num_iterations,
      max_subword_length,
  ):
      # Start with subwords initialized to only reserved_tokens
      subwords = list(reserved_tokens)
  
      for _ in range(num_iterations):
          encoder = cls(vocab_list=subwords)
          subword_counts = collections.defaultdict(int)
          for token, count in token_counts.items():
              start_idx = 0
              for subword in encoder._token_to_subwords(
                  token
              ):  # pylint: disable=protected-access
                  last_idx = min(
                      len(token), start_idx + max_subword_length
                  )
                  for end_idx in range(start_idx + 1, last_idx + 1):
                      candidate_subword = token[start_idx:end_idx]
                      subword_counts[candidate_subword] += count
                  start_idx += len(subword)
  
          # Group subword candidates by length and filter bad candidates
          len_to_subwords = [
              set() for _ in range(max_subword_length + 1)
          ]
          for subword, count in subword_counts.items():
              if count < min_token_count:
                  continue
              # Skip single bytes because they're always in the vocab
              if len(tf.compat.as_bytes(subword)) <= 1:
                  continue
              len_to_subwords[len(subword)].add(subword)
  
          # Consider subword candidates by descending length so that if a longer
          # subword is accepted, its prefixes can have their counts decremented.
          candidate_subwords = []
          for subword_len in reversed(range(max_subword_length + 1)):
              for subword in len_to_subwords[subword_len]:
                  count = subword_counts[subword]
                  if count < min_token_count:
                      continue
                  candidate_subwords.append((count, subword))
                  # Decrement prefix counts
                  for end_idx in range(1, subword_len):
                      subword_counts[subword[:end_idx]] -= count
  
          # Sort subwords by count in descending order, keeping reserved_tokens as
          # the beginning.
          candidate_subwords.sort(reverse=True)
          subwords = reserved_tokens + [
              s for _, s in candidate_subwords
          ]
  
      return cls(vocab_list=subwords)
  
imports: from __future__ import unicode_literals
  import collections
  from absl import logging
  from tensorflow_datasets.core.deprecated.text import text_encoder
  from tensorflow_datasets.core.utils.lazy_imports_utils import tensorflow
label_desc: Use image node_id 15 for calling the SubwordTextEncoder obj's underlying member method code with example usage: obj._build_from_token_counts(cls, token_counts, min_token_count, reserved_tokens, num_iterations, max_subword_length) and returns: cls