

"""simple docstring"""




import argparse
import json
import os

import numpy as np
import PIL
import requests
import tensorflow.keras.applications.efficientnet as efficientnet
import torch
from huggingface_hub import hf_hub_download
from PIL import Image
from tensorflow.keras.preprocessing import image

from transformers import (
    EfficientNetConfig,
    EfficientNetForImageClassification,
    EfficientNetImageProcessor,
)
from transformers.utils import logging


logging.set_verbosity_info()
SCREAMING_SNAKE_CASE_     :			Dict	  =			logging.get_logger(__name__)

SCREAMING_SNAKE_CASE_     :			Tuple	  =			{
    '''b0''': efficientnet.EfficientNetBa,
    '''b1''': efficientnet.EfficientNetBa,
    '''b2''': efficientnet.EfficientNetBa,
    '''b3''': efficientnet.EfficientNetBa,
    '''b4''': efficientnet.EfficientNetBa,
    '''b5''': efficientnet.EfficientNetBa,
    '''b6''': efficientnet.EfficientNetBa,
    '''b7''': efficientnet.EfficientNetBa,
}

SCREAMING_SNAKE_CASE_     :			str	  =			{
    '''b0''': {
        '''hidden_dim''': 1280,
        '''width_coef''': 1.0,
        '''depth_coef''': 1.0,
        '''image_size''': 224,
        '''dropout_rate''': 0.2,
        '''dw_padding''': [],
    },
    '''b1''': {
        '''hidden_dim''': 1280,
        '''width_coef''': 1.0,
        '''depth_coef''': 1.1,
        '''image_size''': 240,
        '''dropout_rate''': 0.2,
        '''dw_padding''': [16],
    },
    '''b2''': {
        '''hidden_dim''': 1408,
        '''width_coef''': 1.1,
        '''depth_coef''': 1.2,
        '''image_size''': 260,
        '''dropout_rate''': 0.3,
        '''dw_padding''': [5, 8, 16],
    },
    '''b3''': {
        '''hidden_dim''': 1536,
        '''width_coef''': 1.2,
        '''depth_coef''': 1.4,
        '''image_size''': 300,
        '''dropout_rate''': 0.3,
        '''dw_padding''': [5, 18],
    },
    '''b4''': {
        '''hidden_dim''': 1792,
        '''width_coef''': 1.4,
        '''depth_coef''': 1.8,
        '''image_size''': 380,
        '''dropout_rate''': 0.4,
        '''dw_padding''': [6],
    },
    '''b5''': {
        '''hidden_dim''': 2048,
        '''width_coef''': 1.6,
        '''depth_coef''': 2.2,
        '''image_size''': 456,
        '''dropout_rate''': 0.4,
        '''dw_padding''': [13, 27],
    },
    '''b6''': {
        '''hidden_dim''': 2304,
        '''width_coef''': 1.8,
        '''depth_coef''': 2.6,
        '''image_size''': 528,
        '''dropout_rate''': 0.5,
        '''dw_padding''': [31],
    },
    '''b7''': {
        '''hidden_dim''': 2560,
        '''width_coef''': 2.0,
        '''depth_coef''': 3.1,
        '''image_size''': 600,
        '''dropout_rate''': 0.5,
        '''dw_padding''': [18],
    },
}



def 	UpperCAmelCase__   (				A__   )      ->      Tuple:




   """simple docstring"""
   lowerCamelCase__						=			EfficientNetConfig()
   lowerCamelCase__						=			CONFIG_MAP[model_name]["hidden_dim"]
   lowerCamelCase__						=			CONFIG_MAP[model_name]["width_coef"]
   lowerCamelCase__						=			CONFIG_MAP[model_name]["depth_coef"]
   lowerCamelCase__						=			CONFIG_MAP[model_name]["image_size"]
   lowerCamelCase__						=			CONFIG_MAP[model_name]["dropout_rate"]
   lowerCamelCase__						=			CONFIG_MAP[model_name]["dw_padding"]

   lowerCamelCase__						=			"huggingface/label-files"
   lowerCamelCase__						=			"imagenet-1k-id2label.json"
   lowerCamelCase__						=			1000
   lowerCamelCase__						=			json.load(open(hf_hub_download(A__	,    A__	,    repo_type="dataset"   )	,    "r"   )   )
   lowerCamelCase__						=			{int(A__   ): v for k, v in idalabel.items()}

   lowerCamelCase__						=			idalabel
   lowerCamelCase__						=			{v: k for k, v in idalabel.items()}
   return config



def 	UpperCAmelCase__   (				)      ->      Tuple:




   """simple docstring"""
   lowerCamelCase__						=			"http://images.cocodataset.org/val2017/000000039769.jpg"
   lowerCamelCase__						=			Image.open(requests.get(A__	,    stream=A__   ).raw   )
   return im



def 	UpperCAmelCase__   (				A__   )      ->      Optional[Any]:




   """simple docstring"""
   lowerCamelCase__						=			CONFIG_MAP[model_name]["image_size"]
   lowerCamelCase__						=			EfficientNetImageProcessor(
       size={"height": size, "width": size}	,    image_mean=[0.485, 0.456, 0.406]	,    image_std=[0.47853944, 0.4732864, 0.47434163]	,    do_center_crop=A__	,    )
   return preprocessor



def 	UpperCAmelCase__   (				A__   )      ->      str:




   """simple docstring"""
   lowerCamelCase__						=			[v.split("_"   )[0].split("block"   )[1] for v in original_param_names if v.startswith("block"   )]
   lowerCamelCase__						=			sorted(set(A__   )   )
   lowerCamelCase__						=			len(A__   )
   lowerCamelCase__						=			{b: str(A__   ) for b, i in zip(A__	,    range(A__   )   )}

   lowerCamelCase__						=			[]
   rename_keys.append(("stem_conv/kernel:0", "embeddings.convolution.weight")   )
   rename_keys.append(("stem_bn/gamma:0", "embeddings.batchnorm.weight")   )
   rename_keys.append(("stem_bn/beta:0", "embeddings.batchnorm.bias")   )
   rename_keys.append(("stem_bn/moving_mean:0", "embeddings.batchnorm.running_mean")   )
   rename_keys.append(("stem_bn/moving_variance:0", "embeddings.batchnorm.running_var")   )

   for b in block_names:
      lowerCamelCase__						=			block_name_mapping[b]
      rename_keys.append((f'block{b}_expand_conv/kernel:0', f'encoder.blocks.{hf_b}.expansion.expand_conv.weight')   )
      rename_keys.append((f'block{b}_expand_bn/gamma:0', f'encoder.blocks.{hf_b}.expansion.expand_bn.weight')   )
      rename_keys.append((f'block{b}_expand_bn/beta:0', f'encoder.blocks.{hf_b}.expansion.expand_bn.bias')   )
      rename_keys.append(
          (f'block{b}_expand_bn/moving_mean:0', f'encoder.blocks.{hf_b}.expansion.expand_bn.running_mean')   )
      rename_keys.append(
          (f'block{b}_expand_bn/moving_variance:0', f'encoder.blocks.{hf_b}.expansion.expand_bn.running_var')   )
      rename_keys.append(
          (f'block{b}_dwconv/depthwise_kernel:0', f'encoder.blocks.{hf_b}.depthwise_conv.depthwise_conv.weight')   )
      rename_keys.append((f'block{b}_bn/gamma:0', f'encoder.blocks.{hf_b}.depthwise_conv.depthwise_norm.weight')   )
      rename_keys.append((f'block{b}_bn/beta:0', f'encoder.blocks.{hf_b}.depthwise_conv.depthwise_norm.bias')   )
      rename_keys.append(
          (f'block{b}_bn/moving_mean:0', f'encoder.blocks.{hf_b}.depthwise_conv.depthwise_norm.running_mean')   )
      rename_keys.append(
          (f'block{b}_bn/moving_variance:0', f'encoder.blocks.{hf_b}.depthwise_conv.depthwise_norm.running_var')   )

      rename_keys.append((f'block{b}_se_reduce/kernel:0', f'encoder.blocks.{hf_b}.squeeze_excite.reduce.weight')   )
      rename_keys.append((f'block{b}_se_reduce/bias:0', f'encoder.blocks.{hf_b}.squeeze_excite.reduce.bias')   )
      rename_keys.append((f'block{b}_se_expand/kernel:0', f'encoder.blocks.{hf_b}.squeeze_excite.expand.weight')   )
      rename_keys.append((f'block{b}_se_expand/bias:0', f'encoder.blocks.{hf_b}.squeeze_excite.expand.bias')   )
      rename_keys.append(
          (f'block{b}_project_conv/kernel:0', f'encoder.blocks.{hf_b}.projection.project_conv.weight')   )
      rename_keys.append((f'block{b}_project_bn/gamma:0', f'encoder.blocks.{hf_b}.projection.project_bn.weight')   )
      rename_keys.append((f'block{b}_project_bn/beta:0', f'encoder.blocks.{hf_b}.projection.project_bn.bias')   )
      rename_keys.append(
          (f'block{b}_project_bn/moving_mean:0', f'encoder.blocks.{hf_b}.projection.project_bn.running_mean')   )
      rename_keys.append(
          (f'block{b}_project_bn/moving_variance:0', f'encoder.blocks.{hf_b}.projection.project_bn.running_var')   )

   rename_keys.append(("top_conv/kernel:0", "encoder.top_conv.weight")   )
   rename_keys.append(("top_bn/gamma:0", "encoder.top_bn.weight")   )
   rename_keys.append(("top_bn/beta:0", "encoder.top_bn.bias")   )
   rename_keys.append(("top_bn/moving_mean:0", "encoder.top_bn.running_mean")   )
   rename_keys.append(("top_bn/moving_variance:0", "encoder.top_bn.running_var")   )

   lowerCamelCase__						=			{}
   for item in rename_keys:
      if item[0] in original_param_names:
         lowerCamelCase__						=			"efficientnet." + item[1]

   lowerCamelCase__						=			"classifier.weight"
   lowerCamelCase__						=			"classifier.bias"
   return key_mapping



def 	UpperCAmelCase__   (				A__	,    A__	,    A__   )      ->      Tuple:




   """simple docstring"""
   for key, value in tf_params.items():
      if "normalization" in key:
         continue

      lowerCamelCase__						=			key_mapping[key]
      if "_conv" in key and "kernel" in key:
         lowerCamelCase__						=			torch.from_numpy(A__   ).permute(3	,    2	,    0	,    1   )
      elif "depthwise_kernel" in key:
         lowerCamelCase__						=			torch.from_numpy(A__   ).permute(2	,    3	,    0	,    1   )
      elif "kernel" in key:
         lowerCamelCase__						=			torch.from_numpy(np.transpose(A__   )   )
      else:
         lowerCamelCase__						=			torch.from_numpy(A__   )

      # Replace HF parameters with original TF model parameters
      assert hf_params[hf_key].shape == new_hf_value.shape
      hf_params[hf_key].copy_(A__   )



@torch.no_grad()
def 	UpperCAmelCase__   (				A__	,    A__	,    A__	,    A__   )      ->      int:




   """simple docstring"""
   lowerCamelCase__						=			model_classes[model_name](
       include_top=A__	,    weights="imagenet"	,    input_tensor=A__	,    input_shape=A__	,    pooling=A__	,    classes=1000	,    classifier_activation="softmax"	,    )

   lowerCamelCase__						=			original_model.trainable_variables
   lowerCamelCase__						=			original_model.non_trainable_variables
   lowerCamelCase__						=			{param.name: param.numpy() for param in tf_params}
   for param in tf_non_train_params:
      lowerCamelCase__						=			param.numpy()
   lowerCamelCase__						=			list(tf_params.keys()   )

   # Load HuggingFace model
   lowerCamelCase__						=			get_efficientnet_config(A__   )
   lowerCamelCase__						=			EfficientNetForImageClassification(A__   ).eval()
   lowerCamelCase__						=			hf_model.state_dict()

   # Create src-to-dst parameter name mapping dictionary
   print("Converting parameters..."   )
   lowerCamelCase__						=			rename_keys(A__   )
   replace_params(A__	,    A__	,    A__   )

   # Initialize preprocessor and preprocess input image
   lowerCamelCase__						=			convert_image_processor(A__   )
   lowerCamelCase__						=			preprocessor(images=prepare_img()	,    return_tensors="pt"   )

   # HF model inference
   hf_model.eval()
   with torch.no_grad():
      lowerCamelCase__						=			hf_model(**A__   )
   lowerCamelCase__						=			outputs.logits.detach().numpy()

   # Original model inference
   lowerCamelCase__						=			False
   lowerCamelCase__						=			CONFIG_MAP[model_name]["image_size"]
   lowerCamelCase__						=			prepare_img().resize((image_size, image_size)	,    resample=PIL.Image.NEAREST   )
   lowerCamelCase__						=			image.img_to_array(A__   )
   lowerCamelCase__						=			np.expand_dims(A__	,    axis=0   )
   lowerCamelCase__						=			original_model.predict(A__   )

   # Check whether original and HF model outputs match  -> np.allclose
   assert np.allclose(A__	,    A__	,    atol=1E-3   ), "The predicted logits are not the same."
   print("Model outputs match!"   )

   if save_model:
      # Create folder to save model
      if not os.path.isdir(A__   ):
         os.mkdir(A__   )
      # Save converted model and image processor
      hf_model.save_pretrained(A__   )
      preprocessor.save_pretrained(A__   )

   if push_to_hub:
      # Push model and image processor to hub
      print(f'Pushing converted {model_name} to the hub...'   )
      lowerCamelCase__						=			f'efficientnet-{model_name}'
      preprocessor.push_to_hub(A__   )
      hf_model.push_to_hub(A__   )


if __name__ == "__main__":
     SCREAMING_SNAKE_CASE_     :			List[str]	  =			argparse.ArgumentParser()
     # Required parameters
     parser.add_argument(
         '''--model_name''',
         default='''b0''',
         type=str,
         help='''Version name of the EfficientNet model you want to convert, select from [b0, b1, b2, b3, b4, b5, b6, b7].''',
     )
     parser.add_argument(
         '''--pytorch_dump_folder_path''',
         default='''hf_model''',
         type=str,
         help='''Path to the output PyTorch model directory.''',
     )
     parser.add_argument('''--save_model''', action='''store_true''', help='''Save model to local''')
     parser.add_argument('''--push_to_hub''', action='''store_true''', help='''Push model and image processor to the hub''')

     SCREAMING_SNAKE_CASE_     :			Optional[Any]	  =			parser.parse_args()
     convert_efficientnet_checkpoint(args.model_name, args.pytorch_dump_folder_path, args.save_model, args.push_to_hub)







"""simple docstring"""




def 	UpperCAmelCase__   (				A__   )      ->      list[int]:




   """simple docstring"""

   if length <= 0 or not isinstance(A__	,    A__   ):
      raise ValueError("Length must be a positive integer."   )
   return [n * (2 * n - 1) for n in range(A__   )]


if __name__ == "__main__":
     print(hexagonal_numbers(length=5))
     print(hexagonal_numbers(length=10))




