text: import os
  import typing
  import warnings
  from urllib import request
  from http import client
  import io
  import pkg_resources
  import validators
  import numpy as np
  import scipy as sp
  import cv2
  
  try:
      import PIL
      import PIL.Image
  except ImportError:  # pragma: no cover
      PIL = None
  
  ImageInputType = typing.Union[str, np.ndarray, "PIL.Image.Image", io.BytesIO]
  
  
  def get_imagenet_classes() -> typing.List[str]:
      """Get the list of ImageNet 2012 classes."""
      filepath = pkg_resources.resource_filename("vit_keras", "imagenet2012.txt")
      with open(filepath) as f:
          classes = [l.strip() for l in f.readlines()]
      return classes
  
  
  def read(filepath_or_buffer: ImageInputType, size, timeout=None):
      """Read a file into an image object
      Args:
          filepath_or_buffer: The path to the file or any object
              with a `read` method (such as `io.BytesIO`)
          size: The size to resize the image to.
          timeout: If filepath_or_buffer is a URL, the timeout to
              use for making the HTTP request.
      """
      if PIL is not None and isinstance(filepath_or_buffer, PIL.Image.Image):
          return np.array(filepath_or_buffer.convert("RGB"))
      if isinstance(filepath_or_buffer, (io.BytesIO, client.HTTPResponse)):
          image = np.asarray(
              bytearray(filepath_or_buffer.read()), dtype=np.uint8)
          image = cv2.imdecode(image, cv2.IMREAD_UNCHANGED)
      elif isinstance(filepath_or_buffer, str) and validators.url(filepath_or_buffer):
          return read(request.urlopen(filepath_or_buffer, timeout=timeout), size=size)
      else:
          if not os.path.isfile(filepath_or_buffer):
              raise FileNotFoundError(
                  "Could not find image at path: " + filepath_or_buffer
              )
          image = cv2.imread(filepath_or_buffer)
      if image is None:
          raise ValueError(f"An error occurred reading {filepath_or_buffer}.")
      # We use cvtColor here instead of just ret[..., ::-1]
      # in order to ensure that we provide a contiguous
      # array for later processing. Some hashers use ctypes
      # to pass the array and non-contiguous arrays can lead
      # to erroneous results.
      image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
      return cv2.resize(image, (size, size))
  
  
  def apply_embedding_weights(target_layer, source_weights):
      """Apply embedding weights to a target layer.
  
      Args:
          target_layer: The target layer to which weights will
              be applied.
          source_weights: The source weights, which will be
              resized as necessary.
      """
      expected_shape = target_layer.weights[0].shape
      if expected_shape ==  source_weights.shape:
          grid = source_weights
      elif expected_shape[1] == source_weights.shape[1]-1:
          grid = source_weights[:, 1:]
      else:
          _, grid = source_weights[0, :1], source_weights[0, 1:]
          sin = int(np.sqrt(grid.shape[0]))
          sout = int(np.sqrt(expected_shape[1]))
          warnings.warn(
              "Resizing position embeddings from " f"{sin} to {sout}",
              UserWarning,
          )
          zoom = (sout / sin, sout / sin, 1)
          grid = sp.ndimage.zoom(grid.reshape(sin, sin, -1), zoom, order=1).reshape(
              1, sout * sout, -1)
      target_layer.set_weights([grid])
  
  
  def load_weights_numpy(model, params_path):
      """Load weights saved using Flax as a numpy array.
  
      Args:
          model: A Keras model to load the weights into.
          params_path: Filepath to a numpy archive.
      """
      params_dict = np.load(
          params_path, allow_pickle=False
      )  # pylint: disable=unexpected-keyword-arg
      source_keys = list(params_dict.keys())
      
      source_keys_used = []
      n_transformers = len(
          set(
              "/".join(k.split("/")[:2])
              for k in source_keys
              if k.startswith("Transformer/encoderblock_")
          )
      )
      n_transformers_out = sum(
          l.name.startswith("Transformer/encoderblock_") for l in model.layers
      )
      assert n_transformers == n_transformers_out, (
          f"Wrong number of transformers ("
          f"{n_transformers_out} in model vs. {n_transformers} in weights)."
      )
  
      matches = []
      for tidx in range(n_transformers):
          encoder = model.get_layer(f"Transformer/encoderblock_{tidx}")
          source_prefix = f"Transformer/encoderblock_{tidx}"
          matches.extend(
              [
                  {
                      "layer": layer,
                      "keys": [
                          f"{source_prefix}/{norm}/{name}" for name in ["scale", "bias"]
                      ],
                  }
                  for norm, layer in [
                      ("LayerNorm_0", encoder.layernorm1),
                      ("LayerNorm_2", encoder.layernorm2),
                  ]
              ]
              + [
                  {
                      "layer": encoder.mlpblock.get_layer(
                          f"{source_prefix}/Dense_{mlpdense}"
                      ),
                      "keys": [
                          f"{source_prefix}/MlpBlock_3/Dense_{mlpdense}/{name}"
                          for name in ["kernel", "bias"]
                      ],
                  }
                  for mlpdense in [0, 1]
              ]
              + [
                  {
                      "layer": layer,
                      "keys": [
                          f"{source_prefix}/MultiHeadDotProductAttention_1/{attvar}/{name}"
                          for name in ["kernel", "bias"]
                      ],
                      "reshape": True,
                  }
                  for attvar, layer in [
                      ("query", encoder.att.query_dense),
                      ("key", encoder.att.key_dense),
                      ("value", encoder.att.value_dense),
                      ("out", encoder.att.combine_heads),
                  ]
              ]
          )
  
      # Embedding kernel and bias
      matches.append(
          {
              "layer": model.get_layer("embedding"),
              "keys": [f"embedding/{name}" for name in ["kernel", "bias"]],
          }
      )
  
      matches.append(
          {
              "layer": model.get_layer("Transformer/encoder_norm"),
              "keys": [f"Transformer/encoder_norm/{name}" for name in ["scale", "bias"]],
          }
      )
      apply_embedding_weights(
          target_layer=model.get_layer("Transformer/posembed_input"),
          source_weights=params_dict["Transformer/posembed_input/pos_embedding"],
      )
      source_keys_used.append("Transformer/posembed_input/pos_embedding")
      for match in matches:
          source_keys_used.extend(match["keys"])
          source_weights = [params_dict[k] for k in match["keys"]]
          if match.get("reshape", False):
              source_weights = [
                  source.reshape(expected.shape)
                  for source, expected in zip(
                      source_weights, match["layer"].get_weights()
                  )
              ]
          match["layer"].set_weights(source_weights)
  
      
  