
'''simple docstring'''


from typing import Dict, List, Optional, Union

import numpy as np

from ...image_processing_utils import BaseImageProcessor, BatchFeature, get_size_dict
from ...image_transforms import (
    center_crop,
    get_resize_output_image_size,
    normalize,
    rescale,
    resize,
    to_channel_dimension_format,
)
from ...image_utils import (
    IMAGENET_STANDARD_MEAN,
    IMAGENET_STANDARD_STD,
    ChannelDimension,
    ImageInput,
    PILImageResampling,
    make_list_of_images,
    to_numpy_array,
    valid_images,
)
from ...utils import TensorType, logging


snake_case_ :  Union[str, Any]     =					logging.get_logger(__name__)


class 						lowercase__	(  snake_case_   ):






   '''simple docstring'''







   _snake_case		   =							['''pixel_values''']







   def __init__(			self ,   lowerCamelCase__ = True ,   lowerCamelCase__ = None ,   lowerCamelCase__ = PILImageResampling.BILINEAR ,   lowerCamelCase__ = True ,   lowerCamelCase__ = None ,   lowerCamelCase__ = True ,   lowerCamelCase__ = 1 / 2_5_5 ,   lowerCamelCase__ = True ,   lowerCamelCase__ = None ,   lowerCamelCase__ = None ,   **lowerCamelCase__ ,   ):

      '''simple docstring'''







      super().__init__(**lowerCamelCase__   )
      UpperCamelCase       =  size if size is not None else {'''shortest_edge''': 2_5_6}
      UpperCamelCase       =  get_size_dict(lowerCamelCase__ ,   default_to_square=lowerCamelCase__   )
      UpperCamelCase       =  crop_size if crop_size is not None else {'''height''': 2_2_4, '''width''': 2_2_4}
      UpperCamelCase       =  get_size_dict(lowerCamelCase__   )
      UpperCamelCase       =  do_resize
      UpperCamelCase       =  size
      UpperCamelCase       =  resample
      UpperCamelCase       =  do_center_crop
      UpperCamelCase       =  crop_size
      UpperCamelCase       =  do_rescale
      UpperCamelCase       =  rescale_factor
      UpperCamelCase       =  do_normalize
      UpperCamelCase       =  image_mean if image_mean is not None else IMAGENET_STANDARD_MEAN
      UpperCamelCase       =  image_std if image_std is not None else IMAGENET_STANDARD_STD







   def       UpperCAmelCase				(			self ,   lowerCamelCase__ ,   lowerCamelCase__ ,   lowerCamelCase__ = PILImageResampling.BICUBIC ,   lowerCamelCase__ = None ,   **lowerCamelCase__ ,   ):

      '''simple docstring'''







      UpperCamelCase       =  get_size_dict(lowerCamelCase__ ,   default_to_square=lowerCamelCase__   )
      if "shortest_edge" not in size:
         raise ValueError(f'The `size` parameter must contain the key `shortest_edge`. Got {size.keys()}'   )
      UpperCamelCase       =  get_resize_output_image_size(lowerCamelCase__ ,   size=size['''shortest_edge'''] ,   default_to_square=lowerCamelCase__   )
      return resize(lowerCamelCase__ ,   size=lowerCamelCase__ ,   resample=lowerCamelCase__ ,   data_format=lowerCamelCase__ ,   **lowerCamelCase__   )







   def       UpperCAmelCase				(			self ,   lowerCamelCase__ ,   lowerCamelCase__ ,   lowerCamelCase__ = None ,   **lowerCamelCase__ ,   ):

      '''simple docstring'''







      UpperCamelCase       =  get_size_dict(lowerCamelCase__   )
      return center_crop(lowerCamelCase__ ,   size=(size['''height'''], size['''width''']) ,   data_format=lowerCamelCase__ ,   **lowerCamelCase__   )







   def       UpperCAmelCase				(			self ,   lowerCamelCase__ ,   lowerCamelCase__ ,   lowerCamelCase__ = None ,   **lowerCamelCase__   ):

      '''simple docstring'''







      return rescale(lowerCamelCase__ ,   scale=lowerCamelCase__ ,   data_format=lowerCamelCase__ ,   **lowerCamelCase__   )







   def       UpperCAmelCase				(			self ,   lowerCamelCase__ ,   lowerCamelCase__ ,   lowerCamelCase__ ,   lowerCamelCase__ = None ,   **lowerCamelCase__ ,   ):

      '''simple docstring'''







      return normalize(lowerCamelCase__ ,   mean=lowerCamelCase__ ,   std=lowerCamelCase__ ,   data_format=lowerCamelCase__ ,   **lowerCamelCase__   )







   def       UpperCAmelCase				(			self ,   lowerCamelCase__ ,   lowerCamelCase__ = None ,   lowerCamelCase__ = None ,   lowerCamelCase__ = None ,   lowerCamelCase__ = None ,   lowerCamelCase__ = None ,   lowerCamelCase__ = None ,   lowerCamelCase__ = None ,   lowerCamelCase__ = None ,   lowerCamelCase__ = None ,   lowerCamelCase__ = None ,   lowerCamelCase__ = None ,   lowerCamelCase__ = ChannelDimension.FIRST ,   **lowerCamelCase__ ,   ):

      '''simple docstring'''







      UpperCamelCase       =  do_resize if do_resize is not None else self.do_resize
      UpperCamelCase       =  size if size is not None else self.size
      UpperCamelCase       =  get_size_dict(lowerCamelCase__ ,   default_to_square=lowerCamelCase__   )
      UpperCamelCase       =  resample if resample is not None else self.resample
      UpperCamelCase       =  do_center_crop if do_center_crop is not None else self.do_center_crop
      UpperCamelCase       =  crop_size if crop_size is not None else self.crop_size
      UpperCamelCase       =  get_size_dict(lowerCamelCase__   )
      UpperCamelCase       =  do_rescale if do_rescale is not None else self.do_rescale
      UpperCamelCase       =  rescale_factor if rescale_factor is not None else self.rescale_factor
      UpperCamelCase       =  do_normalize if do_normalize is not None else self.do_normalize
      UpperCamelCase       =  image_mean if image_mean is not None else self.image_mean
      UpperCamelCase       =  image_std if image_std is not None else self.image_std

      UpperCamelCase       =  make_list_of_images(lowerCamelCase__   )

      if not valid_images(lowerCamelCase__   ):
         raise ValueError(
             '''Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, '''
             '''torch.Tensor, tf.Tensor or jax.ndarray.'''   )

      if do_resize and size is None:
         raise ValueError('''Size must be specified if do_resize is True.'''   )

      if do_center_crop and crop_size is None:
         raise ValueError('''Crop size must be specified if do_center_crop is True.'''   )

      if do_rescale and rescale_factor is None:
         raise ValueError('''Rescale factor must be specified if do_rescale is True.'''   )

      if do_normalize and (image_mean is None or image_std is None):
         raise ValueError('''Image mean and std must be specified if do_normalize is True.'''   )

      # All transformations expect numpy arrays.
      UpperCamelCase       =  [to_numpy_array(lowerCamelCase__   ) for image in images]

      if do_resize:
         UpperCamelCase       =  [self.resize(image=lowerCamelCase__ ,   size=lowerCamelCase__ ,   resample=lowerCamelCase__   ) for image in images]

      if do_center_crop:
         UpperCamelCase       =  [self.center_crop(image=lowerCamelCase__ ,   size=lowerCamelCase__   ) for image in images]

      if do_rescale:
         UpperCamelCase       =  [self.rescale(image=lowerCamelCase__ ,   scale=lowerCamelCase__   ) for image in images]

      if do_normalize:
         UpperCamelCase       =  [self.normalize(image=lowerCamelCase__ ,   mean=lowerCamelCase__ ,   std=lowerCamelCase__   ) for image in images]

      UpperCamelCase       =  [to_channel_dimension_format(lowerCamelCase__ ,   lowerCamelCase__   ) for image in images]

      UpperCamelCase       =  {'''pixel_values''': images}
      return BatchFeature(data=lowerCamelCase__ ,   tensor_type=lowerCamelCase__   )







'''simple docstring'''


import torch
from torch import nn


class 						lowercase__	(  nn.Module   ):






   '''simple docstring'''







   def __init__(			self ,   lowerCamelCase__ ,   lowerCamelCase__ ,   lowerCamelCase__ ,   lowerCamelCase__ ,   lowerCamelCase__=1 ,   lowerCamelCase__=False   ):

      '''simple docstring'''







      super().__init__()

      UpperCamelCase       =  n_token
      UpperCamelCase       =  d_embed
      UpperCamelCase       =  d_proj

      UpperCamelCase       =  cutoffs + [n_token]
      UpperCamelCase       =  [0] + self.cutoffs
      UpperCamelCase       =  div_val

      UpperCamelCase       =  self.cutoffs[0]
      UpperCamelCase       =  len(self.cutoffs   ) - 1
      UpperCamelCase       =  self.shortlist_size + self.n_clusters

      if self.n_clusters > 0:
         UpperCamelCase       =  nn.Parameter(torch.zeros(self.n_clusters ,   self.d_embed   )   )
         UpperCamelCase       =  nn.Parameter(torch.zeros(self.n_clusters   )   )

      UpperCamelCase       =  nn.ModuleList()
      UpperCamelCase       =  nn.ParameterList()

      if div_val == 1:
         for i in range(len(self.cutoffs   )   ):
            if d_proj != d_embed:
               self.out_projs.append(nn.Parameter(torch.FloatTensor(lowerCamelCase__ ,   lowerCamelCase__   )   )   )
            else:
               self.out_projs.append(lowerCamelCase__   )

         self.out_layers.append(nn.Linear(lowerCamelCase__ ,   lowerCamelCase__   )   )
      else:
         for i in range(len(self.cutoffs   )   ):
            UpperCamelCase     , UpperCamelCase       =  self.cutoff_ends[i], self.cutoff_ends[i + 1]
            UpperCamelCase       =  d_embed // (div_val**i)

            self.out_projs.append(nn.Parameter(torch.FloatTensor(lowerCamelCase__ ,   lowerCamelCase__   )   )   )

            self.out_layers.append(nn.Linear(lowerCamelCase__ ,   r_idx - l_idx   )   )

      UpperCamelCase       =  keep_order







   def       UpperCAmelCase				(			self ,   lowerCamelCase__ ,   lowerCamelCase__ ,   lowerCamelCase__ ,   lowerCamelCase__   ):

      '''simple docstring'''







      if proj is None:
         UpperCamelCase       =  nn.functional.linear(lowerCamelCase__ ,   lowerCamelCase__ ,   bias=lowerCamelCase__   )
      else:
         # if CUDA_MAJOR <= 9 and CUDA_MINOR <= 1:
         UpperCamelCase       =  nn.functional.linear(lowerCamelCase__ ,   proj.t().contiguous()   )
         UpperCamelCase       =  nn.functional.linear(lowerCamelCase__ ,   lowerCamelCase__ ,   bias=lowerCamelCase__   )
         # else:
         #     logit = torch.einsum('bd,de,ev->bv', (hidden, proj, weight.t()))
         #     if bias is not None:
         #         logit = logit + bias

      return logit







   def       UpperCAmelCase				(			self ,   lowerCamelCase__ ,   lowerCamelCase__=None ,   lowerCamelCase__=False   ):

      '''simple docstring'''







      if labels is not None:
         # Shift so that tokens < n predict n
         UpperCamelCase       =  hidden[..., :-1, :].contiguous()
         UpperCamelCase       =  labels[..., 1:].contiguous()
         UpperCamelCase       =  hidden.view(-1 ,   hidden.size(-1   )   )
         UpperCamelCase       =  labels.view(-1   )
         if hidden.size(0   ) != labels.size(0   ):
            raise RuntimeError('''Input and labels should have the same size in the batch dimension.'''   )
      else:
         UpperCamelCase       =  hidden.view(-1 ,   hidden.size(-1   )   )

      if self.n_clusters == 0:
         UpperCamelCase       =  self._compute_logit(lowerCamelCase__ ,   self.out_layers[0].weight ,   self.out_layers[0].bias ,   self.out_projs[0]   )
         if labels is not None:
            UpperCamelCase       =  labels != -1_0_0
            UpperCamelCase       =  torch.zeros_like(lowerCamelCase__ ,   dtype=hidden.dtype ,   device=hidden.device   )
            UpperCamelCase       =  (
                -nn.functional.log_softmax(lowerCamelCase__ ,   dim=-1   )[mask].gather(1 ,   labels[mask].unsqueeze(1   )   ).squeeze(1   )
            )
         else:
            UpperCamelCase       =  nn.functional.log_softmax(lowerCamelCase__ ,   dim=-1   )
      else:
         # construct weights and biases
         UpperCamelCase     , UpperCamelCase       =  [], []
         for i in range(len(self.cutoffs   )   ):
            if self.div_val == 1:
               UpperCamelCase     , UpperCamelCase       =  self.cutoff_ends[i], self.cutoff_ends[i + 1]
               UpperCamelCase       =  self.out_layers[0].weight[l_idx:r_idx]
               UpperCamelCase       =  self.out_layers[0].bias[l_idx:r_idx]
            else:
               UpperCamelCase       =  self.out_layers[i].weight
               UpperCamelCase       =  self.out_layers[i].bias

            if i == 0:
               UpperCamelCase       =  torch.cat([weight_i, self.cluster_weight] ,   dim=0   )
               UpperCamelCase       =  torch.cat([bias_i, self.cluster_bias] ,   dim=0   )

            weights.append(lowerCamelCase__   )
            biases.append(lowerCamelCase__   )

         UpperCamelCase     , UpperCamelCase     , UpperCamelCase       =  weights[0], biases[0], self.out_projs[0]

         UpperCamelCase       =  self._compute_logit(lowerCamelCase__ ,   lowerCamelCase__ ,   lowerCamelCase__ ,   lowerCamelCase__   )
         UpperCamelCase       =  nn.functional.log_softmax(lowerCamelCase__ ,   dim=1   )

         if labels is None:
            UpperCamelCase       =  hidden.new_empty((head_logit.size(0   ), self.n_token)   )
         else:
            UpperCamelCase       =  torch.zeros_like(lowerCamelCase__ ,   dtype=hidden.dtype ,   device=hidden.device   )

         UpperCamelCase       =  0
         UpperCamelCase       =  [0] + self.cutoffs
         for i in range(len(lowerCamelCase__   ) - 1   ):
            UpperCamelCase     , UpperCamelCase       =  cutoff_values[i], cutoff_values[i + 1]

            if labels is not None:
               UpperCamelCase       =  (labels >= l_idx) & (labels < r_idx)
               UpperCamelCase       =  mask_i.nonzero().squeeze()

               if indices_i.numel() == 0:
                  continue

               UpperCamelCase       =  labels.index_select(0 ,   lowerCamelCase__   ) - l_idx
               UpperCamelCase       =  head_logprob.index_select(0 ,   lowerCamelCase__   )
               UpperCamelCase       =  hidden.index_select(0 ,   lowerCamelCase__   )
            else:
               UpperCamelCase       =  hidden

            if i == 0:
               if labels is not None:
                  UpperCamelCase       =  head_logprob_i.gather(1 ,   target_i[:, None]   ).squeeze(1   )
               else:
                  UpperCamelCase       =  head_logprob[:, : self.cutoffs[0]]
            else:
               UpperCamelCase     , UpperCamelCase     , UpperCamelCase       =  weights[i], biases[i], self.out_projs[i]

               UpperCamelCase       =  self._compute_logit(lowerCamelCase__ ,   lowerCamelCase__ ,   lowerCamelCase__ ,   lowerCamelCase__   )
               UpperCamelCase       =  nn.functional.log_softmax(lowerCamelCase__ ,   dim=1   )
               UpperCamelCase       =  self.cutoffs[0] + i - 1  # No probability for the head cluster
               if labels is not None:
                  UpperCamelCase       =  head_logprob_i[:, cluster_prob_idx] + tail_logprob_i.gather(
                      1 ,   target_i[:, None]   ).squeeze(1   )
               else:
                  UpperCamelCase       =  head_logprob[:, cluster_prob_idx, None] + tail_logprob_i
                  UpperCamelCase       =  logprob_i

            if labels is not None:
               if (hasattr(self ,   '''keep_order'''   ) and self.keep_order) or keep_order:
                  out.index_copy_(0 ,   lowerCamelCase__ ,   -logprob_i   )
               else:
                  out[offset : offset + logprob_i.size(0   )].copy_(-logprob_i   )
               offset += logprob_i.size(0   )

      return out







   def       UpperCAmelCase				(			self ,   lowerCamelCase__   ):

      '''simple docstring'''







      if self.n_clusters == 0:
         UpperCamelCase       =  self._compute_logit(lowerCamelCase__ ,   self.out_layers[0].weight ,   self.out_layers[0].bias ,   self.out_projs[0]   )
         return nn.functional.log_softmax(lowerCamelCase__ ,   dim=-1   )
      else:
         # construct weights and biases
         UpperCamelCase     , UpperCamelCase       =  [], []
         for i in range(len(self.cutoffs   )   ):
            if self.div_val == 1:
               UpperCamelCase     , UpperCamelCase       =  self.cutoff_ends[i], self.cutoff_ends[i + 1]
               UpperCamelCase       =  self.out_layers[0].weight[l_idx:r_idx]
               UpperCamelCase       =  self.out_layers[0].bias[l_idx:r_idx]
            else:
               UpperCamelCase       =  self.out_layers[i].weight
               UpperCamelCase       =  self.out_layers[i].bias

            if i == 0:
               UpperCamelCase       =  torch.cat([weight_i, self.cluster_weight] ,   dim=0   )
               UpperCamelCase       =  torch.cat([bias_i, self.cluster_bias] ,   dim=0   )

            weights.append(lowerCamelCase__   )
            biases.append(lowerCamelCase__   )

         UpperCamelCase     , UpperCamelCase     , UpperCamelCase       =  weights[0], biases[0], self.out_projs[0]
         UpperCamelCase       =  self._compute_logit(lowerCamelCase__ ,   lowerCamelCase__ ,   lowerCamelCase__ ,   lowerCamelCase__   )

         UpperCamelCase       =  hidden.new_empty((head_logit.size(0   ), self.n_token)   )
         UpperCamelCase       =  nn.functional.log_softmax(lowerCamelCase__ ,   dim=1   )

         UpperCamelCase       =  [0] + self.cutoffs
         for i in range(len(lowerCamelCase__   ) - 1   ):
            UpperCamelCase     , UpperCamelCase       =  cutoff_values[i], cutoff_values[i + 1]

            if i == 0:
               UpperCamelCase       =  head_logprob[:, : self.cutoffs[0]]
            else:
               UpperCamelCase     , UpperCamelCase     , UpperCamelCase       =  weights[i], biases[i], self.out_projs[i]

               UpperCamelCase       =  self._compute_logit(lowerCamelCase__ ,   lowerCamelCase__ ,   lowerCamelCase__ ,   lowerCamelCase__   )
               UpperCamelCase       =  nn.functional.log_softmax(lowerCamelCase__ ,   dim=1   )

               UpperCamelCase       =  head_logprob[:, -i] + tail_logprob_i
               UpperCamelCase       =  logprob_i

         return out





