

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


UpperCamelCase__		 =     logging.get_logger(__name__)


# General docstring
UpperCamelCase__		 =     '''MobileNetV1Config'''

# Base docstring
UpperCamelCase__		 =     '''google/mobilenet_v1_1.0_224'''
UpperCamelCase__		 =     [1, 1024, 7, 7]

# Image classification docstring
UpperCamelCase__		 =     '''google/mobilenet_v1_1.0_224'''
UpperCamelCase__		 =     '''tabby, tabby cat'''


UpperCamelCase__		 =     [
    '''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 						lowerCamelCase__      ( __A    :Optional[int]	,__A    :List[str]	,__A    :Optional[int]=None		):


       """simple docstring"""




       __snake_case       	=							{}

       if isinstance(__A	,__A		):
              __snake_case       	=							model.mobilenet_va
       else:
              __snake_case       	=							model

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

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

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

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

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

       return tf_to_pt_map







def 						lowerCamelCase__      ( __A    :Tuple	,__A    :Union[str, Any]	,__A    :Union[str, Any]		):


       """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
       __snake_case       	=							tf.train.list_variables(__A		)
       __snake_case       	=							{}
       for name, shape in init_vars:
              logger.info(F'Loading TF weight {name} with shape {shape}'		)
              __snake_case       	=							tf.train.load_variable(__A	,__A		)
              __snake_case       	=							array

       # Build TF to PyTorch weights loading map
       __snake_case       	=							_build_tf_to_pytorch_map(__A	,__A	,__A		)

       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

              __snake_case       	=							tf_weights[name]

              if "depthwise_weights" in name:
                     logger.info("""Transposing depthwise"""		)
                     __snake_case       	=							np.transpose(__A	,(2, 3, 0, 1)		)
              elif "weights" in name:
                     logger.info("""Transposing"""		)
                     if len(pointer.shape		) == 2:  # copying into linear layer
                            __snake_case       	=							array.squeeze().transpose()
                     else:
                            __snake_case       	=							np.transpose(__A	,(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}'		)
              __snake_case       	=							torch.from_numpy(__A		)

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

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







def 						lowerCamelCase__      ( __A    :torch.Tensor	,__A    :nn.Convad		):


       """simple docstring"""




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

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

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

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

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

class     __snake_case    (				nn.Module  ):
       """simple docstring"""







       def __init__(		self      , _UpperCamelCase      , _UpperCamelCase      , _UpperCamelCase      , _UpperCamelCase      , _UpperCamelCase = 1      , _UpperCamelCase = 1      , _UpperCamelCase = False      , _UpperCamelCase = True      , _UpperCamelCase = True      , )      ->							None:






              """simple docstring"""


              super().__init__()
              __snake_case       	=							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.'   )

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

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

              if use_normalization:
                     __snake_case       	=							nn.BatchNormad(
                         num_features=_UpperCamelCase      , eps=config.layer_norm_eps      , momentum=0.9997      , affine=_UpperCamelCase      , track_running_stats=_UpperCamelCase      , )
              else:
                     __snake_case       	=							None

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






       def 			a		(		self      , _UpperCamelCase   )      ->							torch.Tensor:






              """simple docstring"""


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






class     __snake_case    (				snake_case__  ):
       """simple docstring"""







       __SCREAMING_SNAKE_CASE				    =							MobileNetVaConfig
       __SCREAMING_SNAKE_CASE				    =							load_tf_weights_in_mobilenet_va
       __SCREAMING_SNAKE_CASE				    =							"mobilenet_v1"
       __SCREAMING_SNAKE_CASE				    =							"pixel_values"
       __SCREAMING_SNAKE_CASE				    =							False


       def 			a		(		self      , _UpperCamelCase   )      ->							None:






              """simple docstring"""


              if isinstance(_UpperCamelCase      , (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(_UpperCamelCase      , nn.BatchNormad   ):
                     module.bias.data.zero_()
                     module.weight.data.fill_(1.0   )






UpperCamelCase__		 =     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.
'''

UpperCamelCase__		 =     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."			,	snake_case__			,	)
class     __snake_case    (				snake_case__  ):
       """simple docstring"""







       def __init__(		self      , _UpperCamelCase      , _UpperCamelCase = True   )      ->							Tuple:






              """simple docstring"""


              super().__init__(_UpperCamelCase   )
              __snake_case       	=							config

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

              __snake_case       	=							MobileNetVaConvLayer(
                  _UpperCamelCase      , in_channels=config.num_channels      , out_channels=_UpperCamelCase      , kernel_size=3      , stride=2      , )

              __snake_case       	=							[1, 2, 1, 2, 1, 2, 1, 1, 1, 1, 1, 2, 1]

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

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

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

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

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

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


       def 			a		(		self      , _UpperCamelCase   )      ->							Optional[Any]:






              """simple docstring"""


              raise NotImplementedError






       @add_start_docstrings_to_model_forward(_UpperCamelCase   )
       @add_code_sample_docstrings(
           checkpoint=_CHECKPOINT_FOR_DOC      , output_type=_UpperCamelCase      , config_class=_CONFIG_FOR_DOC      , modality="""vision"""      , expected_output=_EXPECTED_OUTPUT_SHAPE      , )
       def 			a		(		self      , _UpperCamelCase = None      , _UpperCamelCase = None      , _UpperCamelCase = None      , )      ->							Union[tuple, BaseModelOutputWithPoolingAndNoAttention]:






              """simple docstring"""


              __snake_case       	=							(
                  output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states
              )
              __snake_case       	=							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"""   )

              __snake_case       	=							self.conv_stem(_UpperCamelCase   )

              __snake_case       	=							() if output_hidden_states else None

              for i, layer_module in enumerate(self.layer   ):
                     __snake_case       	=							layer_module(_UpperCamelCase   )

                     if output_hidden_states:
                            __snake_case       	=							all_hidden_states + (hidden_states,)

              __snake_case       	=							hidden_states

              if self.pooler is not None:
                     __snake_case       	=							torch.flatten(self.pooler(_UpperCamelCase   )      , start_dim=1   )
              else:
                     __snake_case       	=							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=_UpperCamelCase      , pooler_output=_UpperCamelCase      , hidden_states=_UpperCamelCase      , )






@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    "			,	snake_case__			,	)
class     __snake_case    (				snake_case__  ):
       """simple docstring"""







       def __init__(		self      , _UpperCamelCase   )      ->							None:






              """simple docstring"""


              super().__init__(_UpperCamelCase   )

              __snake_case       	=							config.num_labels
              __snake_case       	=							MobileNetVaModel(_UpperCamelCase   )

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

              # Classifier head
              __snake_case       	=							nn.Dropout(config.classifier_dropout_prob      , inplace=_UpperCamelCase   )
              __snake_case       	=							nn.Linear(_UpperCamelCase      , 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(_UpperCamelCase   )
       @add_code_sample_docstrings(
           checkpoint=_IMAGE_CLASS_CHECKPOINT      , output_type=_UpperCamelCase      , config_class=_CONFIG_FOR_DOC      , expected_output=_IMAGE_CLASS_EXPECTED_OUTPUT      , )
       def 			a		(		self      , _UpperCamelCase = None      , _UpperCamelCase = None      , _UpperCamelCase = None      , _UpperCamelCase = None      , )      ->							Union[tuple, ImageClassifierOutputWithNoAttention]:






              """simple docstring"""


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

              __snake_case       	=							self.mobilenet_va(_UpperCamelCase      , output_hidden_states=_UpperCamelCase      , return_dict=_UpperCamelCase   )

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

              __snake_case       	=							self.classifier(self.dropout(_UpperCamelCase   )   )

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

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

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

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




from __future__ import annotations

import random

# Maximum size of the population.  Bigger could be faster but is more memory expensive.
UpperCamelCase__		 =     200
# Number of elements selected in every generation of evolution. The selection takes
# place from best to worst of that generation and must be smaller than N_POPULATION.
UpperCamelCase__		 =     50
# Probability that an element of a generation can mutate, changing one of its genes.
# This will guarantee that all genes will be used during evolution.
UpperCamelCase__		 =     0.4
# Just a seed to improve randomness required by the algorithm.
random.seed(random.randint(0, 1000))







def 						lowerCamelCase__      ( __A    :str	,__A    :str		):


       """simple docstring"""




       __snake_case       	=							len([g for position, g in enumerate(__A		) if g == main_target[position]]		)
       return (item, float(__A		))







def 						lowerCamelCase__      ( __A    :str	,__A    :str		):


       """simple docstring"""




       __snake_case       	=							random.randint(0	,len(__A		) - 1		)
       __snake_case       	=							parent_a[:random_slice] + parent_a[random_slice:]
       __snake_case       	=							parent_a[:random_slice] + parent_a[random_slice:]
       return (child_a, child_a)







def 						lowerCamelCase__      ( __A    :str	,__A    :list[str]		):


       """simple docstring"""




       __snake_case       	=							list(__A		)
       if random.uniform(0	,1		) < MUTATION_PROBABILITY:
              __snake_case       	=							random.choice(__A		)
       return "".join(__A		)







def 						lowerCamelCase__      ( __A    :tuple[str, float]	,__A    :list[tuple[str, float]]	,__A    :list[str]	,):


       """simple docstring"""




       __snake_case       	=							[]
       # Generate more children proportionally to the fitness score.
       __snake_case       	=							int(parent_a[1] * 1_0_0		) + 1
       __snake_case       	=							1_0 if child_n >= 1_0 else child_n
       for _ in range(__A		):
              __snake_case       	=							population_score[random.randint(0	,__A		)][0]

              __snake_case	,    __snake_case       	=							crossover(parent_a[0]	,__A		)
              # Append new string to the population list.
              pop.append(mutate(__A	,__A		)		)
              pop.append(mutate(__A	,__A		)		)
       return pop







def 						lowerCamelCase__      ( __A    :str	,__A    :list[str]	,__A    :bool = True		):


       """simple docstring"""




       if N_POPULATION < N_SELECTED:
              __snake_case       	=							F'{N_POPULATION} must be bigger than {N_SELECTED}'
              raise ValueError(__A		)
       # Verify that the target contains no genes besides the ones inside genes variable.
       __snake_case       	=							sorted({c for c in target if c not in genes}		)
       if not_in_genes_list:
              __snake_case       	=							F'{not_in_genes_list} is not in genes list, evolution cannot converge'
              raise ValueError(__A		)

       # Generate random starting population.
       __snake_case       	=							[]
       for _ in range(__A		):
              population.append("""""".join([random.choice(__A		) for i in range(len(__A		)		)]		)		)

       # Just some logs to know what the algorithms is doing.
       __snake_case	,    __snake_case       	=							0, 0

       # This loop will end when we find a perfect match for our target.
       while True:
              generation += 1
              total_population += len(__A		)

              # Random population created. Now it's time to evaluate.

              # Adding a bit of concurrency can make everything faster,
              #
              # import concurrent.futures
              # population_score: list[tuple[str, float]] = []
              # with concurrent.futures.ThreadPoolExecutor(
              #                                   max_workers=NUM_WORKERS) as executor:
              #     futures = {executor.submit(evaluate, item) for item in population}
              #     concurrent.futures.wait(futures)
              #     population_score = [item.result() for item in futures]
              #
              # but with a simple algorithm like this, it will probably be slower.
              # We just need to call evaluate for every item inside the population.
              __snake_case       	=							[evaluate(__A	,__A		) for item in population]

              # Check if there is a matching evolution.
              __snake_case       	=							sorted(__A	,key=lambda __A		: x[1]	,reverse=__A		)
              if population_score[0][0] == target:
                     return (generation, total_population, population_score[0][0])

              # Print the best result every 10 generation.
              # Just to know that the algorithm is working.
              if debug and generation % 1_0 == 0:
                     print(
                         F'\nGeneration: {generation}'
                         F'\nTotal Population:{total_population}'
                         F'\nBest score: {population_score[0][1]}'
                         F'\nBest string: {population_score[0][0]}'		)

              # Flush the old population, keeping some of the best evolutions.
              # Keeping this avoid regression of evolution.
              __snake_case       	=							population[: int(N_POPULATION / 3		)]
              population.clear()
              population.extend(__A		)
              # Normalize population score to be between 0 and 1.
              __snake_case       	=							[
                  (item, score / len(__A		)) for item, score in population_score
              ]

              # This is selection
              for i in range(__A		):
                     population.extend(select(population_score[int(__A		)]	,__A	,__A		)		)
                     # Check if the population has already reached the maximum value and if so,
                     # break the cycle.  If this check is disabled, the algorithm will take
                     # forever to compute large strings, but will also calculate small strings in
                     # a far fewer generations.
                     if len(__A		) > N_POPULATION:
                            break


if __name__ == "__main__":
    UpperCamelCase__		 =     (
        '''This is a genetic algorithm to evaluate, combine, evolve, and mutate a string!'''
    )
    UpperCamelCase__		 =     list(
        ''' ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklm'''
        '''nopqrstuvwxyz.,;!?+-*#@^\'èéòà€ù=)(&%$£/\\'''
    )
    UpperCamelCase__ ,UpperCamelCase__ ,UpperCamelCase__		 =     basic(target_str, genes_list)
    print(
        F'\nGeneration: {generation}\nTotal Population: {population}\nTarget: {target}'
    )

