"""simple docstring"""






from typing import Optional, Union

import torch
from torch import nn
from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss

from ...activations import ACTaFN
from ...modeling_outputs import BaseModelOutputWithPoolingAndNoAttention, ImageClassifierOutputWithNoAttention
from ...modeling_utils import PreTrainedModel
from ...utils import add_code_sample_docstrings, add_start_docstrings, add_start_docstrings_to_model_forward, logging
from .configuration_mobilenet_va import MobileNetVaConfig


__lowerCAmelCase					: Optional[Any]        =logging.get_logger(__name__)


# General docstring
__lowerCAmelCase					: List[str]        ="""MobileNetV1Config"""

# Base docstring
__lowerCAmelCase					: List[str]        ="""google/mobilenet_v1_1.0_224"""
__lowerCAmelCase					: Any        =[1, 1_0_2_4, 7, 7]

# Image classification docstring
__lowerCAmelCase					: List[str]        ="""google/mobilenet_v1_1.0_224"""
__lowerCAmelCase					: int        ="""tabby, tabby cat"""


__lowerCAmelCase					: Optional[int]        =[
    """google/mobilenet_v1_1.0_224""",
    """google/mobilenet_v1_0.75_192""",
    # See all MobileNetV1 models at https://huggingface.co/models?filter=mobilenet_v1
]


def     UpperCAmelCase__ (       lowerCAmelCase__  :int      ,	lowerCAmelCase__  :Optional[int]      ,	lowerCAmelCase__  :List[Any]=None	)				->					List[str]:
      '''simple docstring'''


      lowercase														=			{}

      if isinstance(lowerCAmelCase__      ,	lowerCAmelCase__	):
            lowercase														=			model.mobilenet_va
      else:
            lowercase														=			model

      lowercase														=			"""MobilenetV1/Conv2d_0/"""
      lowercase														=			backbone.conv_stem.convolution.weight
      lowercase														=			backbone.conv_stem.normalization.bias
      lowercase														=			backbone.conv_stem.normalization.weight
      lowercase														=			backbone.conv_stem.normalization.running_mean
      lowercase														=			backbone.conv_stem.normalization.running_var

      for i in range(1_3	):
            lowercase														=			i + 1
            lowercase														=			i * 2

            lowercase														=			backbone.layer[pt_index]
            lowercase														=			f'MobilenetV1/Conv2d_{tf_index}_depthwise/'
            lowercase														=			pointer.convolution.weight
            lowercase														=			pointer.normalization.bias
            lowercase														=			pointer.normalization.weight
            lowercase														=			pointer.normalization.running_mean
            lowercase														=			pointer.normalization.running_var

            lowercase														=			backbone.layer[pt_index + 1]
            lowercase														=			f'MobilenetV1/Conv2d_{tf_index}_pointwise/'
            lowercase														=			pointer.convolution.weight
            lowercase														=			pointer.normalization.bias
            lowercase														=			pointer.normalization.weight
            lowercase														=			pointer.normalization.running_mean
            lowercase														=			pointer.normalization.running_var

      if isinstance(lowerCAmelCase__      ,	lowerCAmelCase__	):
            lowercase														=			"""MobilenetV1/Logits/Conv2d_1c_1x1/"""
            lowercase														=			model.classifier.weight
            lowercase														=			model.classifier.bias

      return tf_to_pt_map


def     UpperCAmelCase__ (       lowerCAmelCase__  :Union[str, Any]      ,	lowerCAmelCase__  :str      ,	lowerCAmelCase__  :int	)				->					Optional[int]:
      '''simple docstring'''


      try:
            import numpy as np
            import tensorflow as tf
      except ImportError:
            logger.error(
                """Loading a TensorFlow models in PyTorch, requires TensorFlow to be installed. Please see """
                """https://www.tensorflow.org/install/ for installation instructions."""	)
            raise

      # Load weights from TF model
      lowercase														=			tf.train.list_variables(lowerCAmelCase__	)
      lowercase														=			{}
      for name, shape in init_vars:
            logger.info(f'Loading TF weight {name} with shape {shape}'	)
            lowercase														=			tf.train.load_variable(lowerCAmelCase__      ,	lowerCAmelCase__	)
            lowercase														=			array

      # Build TF to PyTorch weights loading map
      lowercase														=			_build_tf_to_pytorch_map(lowerCAmelCase__      ,	lowerCAmelCase__      ,	lowerCAmelCase__	)

      for name, pointer in tf_to_pt_map.items():
            logger.info(f'Importing {name}'	)
            if name not in tf_weights:
                  logger.info(f'{name} not in tf pre-trained weights, skipping'	)
                  continue

            lowercase														=			tf_weights[name]

            if "depthwise_weights" in name:
                  logger.info("""Transposing depthwise"""	)
                  lowercase														=			np.transpose(lowerCAmelCase__      ,	(2, 3, 0, 1)	)
            elif "weights" in name:
                  logger.info("""Transposing"""	)
                  if len(pointer.shape	) == 2:  # copying into linear layer
                        lowercase														=			array.squeeze().transpose()
                  else:
                        lowercase														=			np.transpose(lowerCAmelCase__      ,	(3, 2, 0, 1)	)

            if pointer.shape != array.shape:
                  raise ValueError(f'Pointer shape {pointer.shape} and array shape {array.shape} mismatched'	)

            logger.info(f'Initialize PyTorch weight {name} {array.shape}'	)
            lowercase														=			torch.from_numpy(lowerCAmelCase__	)

            tf_weights.pop(lowerCAmelCase__      ,	lowerCAmelCase__	)
            tf_weights.pop(name + """/RMSProp"""      ,	lowerCAmelCase__	)
            tf_weights.pop(name + """/RMSProp_1"""      ,	lowerCAmelCase__	)
            tf_weights.pop(name + """/ExponentialMovingAverage"""      ,	lowerCAmelCase__	)

      logger.info(f'Weights not copied to PyTorch model: {", ".join(tf_weights.keys()	)}'	)
      return model


def     UpperCAmelCase__ (       lowerCAmelCase__  :torch.Tensor      ,	lowerCAmelCase__  :nn.Convad	)				->					torch.Tensor:
      '''simple docstring'''


      lowercase							,							lowercase														=			features.shape[-2:]
      lowercase							,							lowercase														=			conv_layer.stride
      lowercase							,							lowercase														=			conv_layer.kernel_size

      if in_height % stride_height == 0:
            lowercase														=			max(kernel_height - stride_height      ,	0	)
      else:
            lowercase														=			max(kernel_height - (in_height % stride_height)      ,	0	)

      if in_width % stride_width == 0:
            lowercase														=			max(kernel_width - stride_width      ,	0	)
      else:
            lowercase														=			max(kernel_width - (in_width % stride_width)      ,	0	)

      lowercase														=			pad_along_width // 2
      lowercase														=			pad_along_width - pad_left
      lowercase														=			pad_along_height // 2
      lowercase														=			pad_along_height - pad_top

      lowercase														=			(pad_left, pad_right, pad_top, pad_bottom)
      return nn.functional.pad(lowerCAmelCase__      ,	lowerCAmelCase__      ,	"""constant"""      ,	0.0	)





class 				_A		( nn.Module			):

      def __init__(		self	, __lowerCAmelCase	, __lowerCAmelCase	, __lowerCAmelCase	, __lowerCAmelCase	, __lowerCAmelCase = 1	, __lowerCAmelCase = 1	, __lowerCAmelCase = False	, __lowerCAmelCase = True	, __lowerCAmelCase = True	, ):







            """simple docstring"""



            super().__init__()
            lowercase														=			config

            if in_channels % groups != 0:
                  raise ValueError(f'Input channels ({in_channels}) are not divisible by {groups} groups.'		)
            if out_channels % groups != 0:
                  raise ValueError(f'Output channels ({out_channels}) are not divisible by {groups} groups.'		)

            lowercase														=			0 if config.tf_padding else int((kernel_size - 1) / 2		)

            lowercase														=			nn.Convad(
                in_channels=__lowerCAmelCase	, out_channels=__lowerCAmelCase	, kernel_size=__lowerCAmelCase	, stride=__lowerCAmelCase	, padding=__lowerCAmelCase	, groups=__lowerCAmelCase	, bias=__lowerCAmelCase	, padding_mode="""zeros"""	, )

            if use_normalization:
                  lowercase														=			nn.BatchNormad(
                      num_features=__lowerCAmelCase	, eps=config.layer_norm_eps	, momentum=0.9_9_9_7	, affine=__lowerCAmelCase	, track_running_stats=__lowerCAmelCase	, )
            else:
                  lowercase														=			None

            if use_activation:
                  if isinstance(__lowerCAmelCase	, __lowerCAmelCase		):
                        lowercase														=			ACTaFN[use_activation]
                  elif isinstance(config.hidden_act	, __lowerCAmelCase		):
                        lowercase														=			ACTaFN[config.hidden_act]
                  else:
                        lowercase														=			config.hidden_act
            else:
                  lowercase														=			None







      def        A__ (		self	, __lowerCAmelCase		):







            """simple docstring"""



            if self.config.tf_padding:
                  lowercase														=			apply_tf_padding(__lowerCAmelCase	, self.convolution		)
            lowercase														=			self.convolution(__lowerCAmelCase		)
            if self.normalization is not None:
                  lowercase														=			self.normalization(__lowerCAmelCase		)
            if self.activation is not None:
                  lowercase														=			self.activation(__lowerCAmelCase		)
            return features






class 				_A		( lowerCAmelCase			):
      snake_case__    :     int													=			MobileNetVaConfig
      snake_case__    :     Tuple													=			load_tf_weights_in_mobilenet_va
      snake_case__    :     Union[str, Any]													=			'mobilenet_v1'
      snake_case__    :     Tuple													=			'pixel_values'
      snake_case__    :     Union[str, Any]													=			False

      def        A__ (		self	, __lowerCAmelCase		):







            """simple docstring"""



            if isinstance(__lowerCAmelCase	, (nn.Linear, nn.Convad)		):
                  module.weight.data.normal_(mean=0.0	, std=self.config.initializer_range		)
                  if module.bias is not None:
                        module.bias.data.zero_()
            elif isinstance(__lowerCAmelCase	, nn.BatchNormad		):
                  module.bias.data.zero_()
                  module.weight.data.fill_(1.0		)






__lowerCAmelCase					: int        =R"""
    This model is a PyTorch [torch.nn.Module](https://pytorch.org/docs/stable/nn.html#torch.nn.Module) subclass. Use it
    as a regular PyTorch Module and refer to the PyTorch documentation for all matter related to general usage and
    behavior.

    Parameters:
        config ([`MobileNetV1Config`]): Model configuration class with all the parameters of the model.
            Initializing with a config file does not load the weights associated with the model, only the
            configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights.
"""

__lowerCAmelCase					: Optional[Any]        =R"""
    Args:
        pixel_values (`torch.FloatTensor` of shape `(batch_size, num_channels, height, width)`):
            Pixel values. Pixel values can be obtained using [`AutoImageProcessor`]. See
            [`MobileNetV1ImageProcessor.__call__`] for details.
        output_hidden_states (`bool`, *optional*):
            Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for
            more detail.
        return_dict (`bool`, *optional*):
            Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple.
"""





@add_start_docstrings(
    'The bare MobileNetV1 model outputting raw hidden-states without any specific head on top.'						,					lowerCAmelCase						,					)
class 				_A		( lowerCAmelCase			):

      def __init__(		self	, __lowerCAmelCase	, __lowerCAmelCase = True		):







            """simple docstring"""



            super().__init__(__lowerCAmelCase		)
            lowercase														=			config

            lowercase														=			32
            lowercase														=			max(int(depth * config.depth_multiplier		)	, config.min_depth		)

            lowercase														=			MobileNetVaConvLayer(
                __lowerCAmelCase	, in_channels=config.num_channels	, out_channels=__lowerCAmelCase	, kernel_size=3	, stride=2	, )

            lowercase														=			[1, 2, 1, 2, 1, 2, 1, 1, 1, 1, 1, 2, 1]

            lowercase														=			nn.ModuleList()
            for i in range(13		):
                  lowercase														=			out_channels

                  if strides[i] == 2 or i == 0:
                        depth *= 2
                        lowercase														=			max(int(depth * config.depth_multiplier		)	, config.min_depth		)

                  self.layer.append(
                      MobileNetVaConvLayer(
                          __lowerCAmelCase	, in_channels=__lowerCAmelCase	, out_channels=__lowerCAmelCase	, kernel_size=3	, stride=strides[i]	, groups=__lowerCAmelCase	, )		)

                  self.layer.append(
                      MobileNetVaConvLayer(
                          __lowerCAmelCase	, in_channels=__lowerCAmelCase	, out_channels=__lowerCAmelCase	, kernel_size=1	, )		)

            lowercase														=			nn.AdaptiveAvgPoolad((1, 1)		) if add_pooling_layer else None

            # Initialize weights and apply final processing
            self.post_init()

      def        A__ (		self	, __lowerCAmelCase		):







            """simple docstring"""



            raise NotImplementedError







      @add_start_docstrings_to_model_forward(__lowerCAmelCase		)
      @add_code_sample_docstrings(
          checkpoint=_CHECKPOINT_FOR_DOC	, output_type=__lowerCAmelCase	, config_class=_CONFIG_FOR_DOC	, modality="""vision"""	, expected_output=_EXPECTED_OUTPUT_SHAPE	, )
      def        A__ (		self	, __lowerCAmelCase = None	, __lowerCAmelCase = None	, __lowerCAmelCase = None	, ):







            """simple docstring"""



            lowercase														=			(
                output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states
            )
            lowercase														=			return_dict if return_dict is not None else self.config.use_return_dict

            if pixel_values is None:
                  raise ValueError("""You have to specify pixel_values"""		)

            lowercase														=			self.conv_stem(__lowerCAmelCase		)

            lowercase														=			() if output_hidden_states else None

            for i, layer_module in enumerate(self.layer		):
                  lowercase														=			layer_module(__lowerCAmelCase		)

                  if output_hidden_states:
                        lowercase														=			all_hidden_states + (hidden_states,)

            lowercase														=			hidden_states

            if self.pooler is not None:
                  lowercase														=			torch.flatten(self.pooler(__lowerCAmelCase		)	, start_dim=1		)
            else:
                  lowercase														=			None

            if not return_dict:
                  return tuple(v for v in [last_hidden_state, pooled_output, all_hidden_states] if v is not None		)

            return BaseModelOutputWithPoolingAndNoAttention(
                last_hidden_state=__lowerCAmelCase	, pooler_output=__lowerCAmelCase	, hidden_states=__lowerCAmelCase	, )






@add_start_docstrings(
    '\n    MobileNetV1 model with an image classification head on top (a linear layer on top of the pooled features), e.g. for\n    ImageNet.\n    '						,					lowerCAmelCase						,					)
class 				_A		( lowerCAmelCase			):

      def __init__(		self	, __lowerCAmelCase		):







            """simple docstring"""



            super().__init__(__lowerCAmelCase		)

            lowercase														=			config.num_labels
            lowercase														=			MobileNetVaModel(__lowerCAmelCase		)

            lowercase														=			self.mobilenet_va.layer[-1].convolution.out_channels

            # Classifier head
            lowercase														=			nn.Dropout(config.classifier_dropout_prob	, inplace=__lowerCAmelCase		)
            lowercase														=			nn.Linear(__lowerCAmelCase	, config.num_labels		) if config.num_labels > 0 else nn.Identity()

            # Initialize weights and apply final processing
            self.post_init()







      @add_start_docstrings_to_model_forward(__lowerCAmelCase		)
      @add_code_sample_docstrings(
          checkpoint=_IMAGE_CLASS_CHECKPOINT	, output_type=__lowerCAmelCase	, config_class=_CONFIG_FOR_DOC	, expected_output=_IMAGE_CLASS_EXPECTED_OUTPUT	, )
      def        A__ (		self	, __lowerCAmelCase = None	, __lowerCAmelCase = None	, __lowerCAmelCase = None	, __lowerCAmelCase = None	, ):







            """simple docstring"""



            lowercase														=			return_dict if return_dict is not None else self.config.use_return_dict

            lowercase														=			self.mobilenet_va(__lowerCAmelCase	, output_hidden_states=__lowerCAmelCase	, return_dict=__lowerCAmelCase		)

            lowercase														=			outputs.pooler_output if return_dict else outputs[1]

            lowercase														=			self.classifier(self.dropout(__lowerCAmelCase		)		)

            lowercase														=			None
            if labels is not None:
                  if self.config.problem_type is None:
                        if self.num_labels == 1:
                              lowercase														=			"""regression"""
                        elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int):
                              lowercase														=			"""single_label_classification"""
                        else:
                              lowercase														=			"""multi_label_classification"""

                  if self.config.problem_type == "regression":
                        lowercase														=			MSELoss()
                        if self.num_labels == 1:
                              lowercase														=			loss_fct(logits.squeeze()	, labels.squeeze()		)
                        else:
                              lowercase														=			loss_fct(__lowerCAmelCase	, __lowerCAmelCase		)
                  elif self.config.problem_type == "single_label_classification":
                        lowercase														=			CrossEntropyLoss()
                        lowercase														=			loss_fct(logits.view(-1	, self.num_labels		)	, labels.view(-1		)		)
                  elif self.config.problem_type == "multi_label_classification":
                        lowercase														=			BCEWithLogitsLoss()
                        lowercase														=			loss_fct(__lowerCAmelCase	, __lowerCAmelCase		)

            if not return_dict:
                  lowercase														=			(logits,) + outputs[2:]
                  return ((loss,) + output) if loss is not None else output

            return ImageClassifierOutputWithNoAttention(
                loss=__lowerCAmelCase	, logits=__lowerCAmelCase	, hidden_states=outputs.hidden_states	, )




"""simple docstring"""






def     UpperCAmelCase__ (       lowerCAmelCase__  :str      ,	lowerCAmelCase__  :int	)				->					list:
      '''simple docstring'''


      lowercase														=			word.split()

      def justify(lowerCAmelCase__  :list      ,	lowerCAmelCase__  :int      ,	lowerCAmelCase__  :int	) -> str:
            lowercase														=			max_width - width
            lowercase														=			len(lowerCAmelCase__	)
            if len(lowerCAmelCase__	) == 1:
                  # if there is only word in line
                  # just insert overall_spaces_count for the remainder of line
                  return line[0] + " " * overall_spaces_count
            else:
                  lowercase														=			words_count - 1
                  # num_spaces_between_words_list[i] : tells you to insert
                  # num_spaces_between_words_list[i] spaces
                  # after word on line[i]
                  lowercase														=			spaces_to_insert_between_words * [
                      overall_spaces_count // spaces_to_insert_between_words
                  ]
                  lowercase														=			(
                      overall_spaces_count % spaces_to_insert_between_words
                  )
                  # distribute spaces via round robin to the left words
                  for i in range(lowerCAmelCase__	):
                        num_spaces_between_words_list[i] += 1
                  lowercase														=			[]
                  for i in range(lowerCAmelCase__	):
                        # add the word
                        aligned_words_list.append(line[i]	)
                        # add the spaces to insert
                        aligned_words_list.append(num_spaces_between_words_list[i] * """ """	)
                  # just add the last word to the sentence
                  aligned_words_list.append(line[-1]	)
                  # join the aligned words list to form a justified line
                  return "".join(lowerCAmelCase__	)

      lowercase														=			[]
      lowercase														=			[]
      lowercase														=			0
      for word in words:
            if width + len(lowerCAmelCase__	) + len(lowerCAmelCase__	) <= max_width:
                  # keep adding words until we can fill out max_width
                  # width = sum of length of all words (without overall_spaces_count)
                  # len(word) = length of current word
                  # len(line) = number of overall_spaces_count to insert between words
                  line.append(lowerCAmelCase__	)
                  width += len(lowerCAmelCase__	)
            else:
                  # justify the line and add it to result
                  answer.append(justify(lowerCAmelCase__      ,	lowerCAmelCase__      ,	lowerCAmelCase__	)	)
                  # reset new line and new width
                  lowercase							,							lowercase														=			[word], len(lowerCAmelCase__	)
      lowercase														=			max_width - width - len(lowerCAmelCase__	)
      answer.append(""" """.join(lowerCAmelCase__	) + (remaining_spaces + 1) * """ """	)
      return answer


if __name__ == "__main__":
       from doctest import testmod

       testmod()



