

"""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_					:	int							  =						logging.get_logger(__name__)

SCREAMING_SNAKE_CASE_					:	List[Any]							  =						{
    '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_					:	Any							  =						{
    'b0': {
        'hidden_dim': 1_2_8_0,
        'width_coef': 1.0,
        'depth_coef': 1.0,
        'image_size': 2_2_4,
        'dropout_rate': 0.2,
        'dw_padding': [],
    },
    'b1': {
        'hidden_dim': 1_2_8_0,
        'width_coef': 1.0,
        'depth_coef': 1.1,
        'image_size': 2_4_0,
        'dropout_rate': 0.2,
        'dw_padding': [1_6],
    },
    'b2': {
        'hidden_dim': 1_4_0_8,
        'width_coef': 1.1,
        'depth_coef': 1.2,
        'image_size': 2_6_0,
        'dropout_rate': 0.3,
        'dw_padding': [5, 8, 1_6],
    },
    'b3': {
        'hidden_dim': 1_5_3_6,
        'width_coef': 1.2,
        'depth_coef': 1.4,
        'image_size': 3_0_0,
        'dropout_rate': 0.3,
        'dw_padding': [5, 1_8],
    },
    'b4': {
        'hidden_dim': 1_7_9_2,
        'width_coef': 1.4,
        'depth_coef': 1.8,
        'image_size': 3_8_0,
        'dropout_rate': 0.4,
        'dw_padding': [6],
    },
    'b5': {
        'hidden_dim': 2_0_4_8,
        'width_coef': 1.6,
        'depth_coef': 2.2,
        'image_size': 4_5_6,
        'dropout_rate': 0.4,
        'dw_padding': [1_3, 2_7],
    },
    'b6': {
        'hidden_dim': 2_3_0_4,
        'width_coef': 1.8,
        'depth_coef': 2.6,
        'image_size': 5_2_8,
        'dropout_rate': 0.5,
        'dw_padding': [3_1],
    },
    'b7': {
        'hidden_dim': 2_5_6_0,
        'width_coef': 2.0,
        'depth_coef': 3.1,
        'image_size': 6_0_0,
        'dropout_rate': 0.5,
        'dw_padding': [1_8],
    },
}





def  _snake_case     (    UpperCAmelCase_  :					Optional[int]			):
     A__										=  EfficientNetConfig()
     A__										=  CONFIG_MAP[model_name]["""hidden_dim"""]
     A__										=  CONFIG_MAP[model_name]["""width_coef"""]
     A__										=  CONFIG_MAP[model_name]["""depth_coef"""]
     A__										=  CONFIG_MAP[model_name]["""image_size"""]
     A__										=  CONFIG_MAP[model_name]["""dropout_rate"""]
     A__										=  CONFIG_MAP[model_name]["""dw_padding"""]

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

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





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





def  _snake_case     (    UpperCAmelCase_  :					Tuple			):
     A__										=  CONFIG_MAP[model_name]["""image_size"""]
     A__										=  EfficientNetImageProcessor(
         size={"""height""": size, """width""": size}					,   image_mean=[0.4_85, 0.4_56, 0.4_06]					,   image_std=[0.47_85_39_44, 0.4_73_28_64, 0.47_43_41_63]					,   do_center_crop=UpperCAmelCase_					,   )
     return preprocessor





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

     A__										=  []
     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:
          A__										=  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""")			)

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

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





def  _snake_case     (    UpperCAmelCase_  :					int					,   UpperCAmelCase_  :					str					,   UpperCAmelCase_  :					int			):
     for key, value in tf_params.items():
          if "normalization" in key:
               continue

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

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





@torch.no_grad()
def  _snake_case     (    UpperCAmelCase_  :					Dict					,   UpperCAmelCase_  :					int					,   UpperCAmelCase_  :					Dict					,   UpperCAmelCase_  :					Tuple			):
     A__										=  model_classes[model_name](
         include_top=UpperCAmelCase_					,   weights="""imagenet"""					,   input_tensor=UpperCAmelCase_					,   input_shape=UpperCAmelCase_					,   pooling=UpperCAmelCase_					,   classes=1000					,   classifier_activation="""softmax"""					,   )

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

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

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

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

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

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

     # Check whether original and HF model outputs match  -> np.allclose
     assert np.allclose(UpperCAmelCase_					,   UpperCAmelCase_					,   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(UpperCAmelCase_			):
               os.mkdir(UpperCAmelCase_			)
          # Save converted model and image processor
          hf_model.save_pretrained(UpperCAmelCase_			)
          preprocessor.save_pretrained(UpperCAmelCase_			)

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


if __name__ == "__main__":
 SCREAMING_SNAKE_CASE_					:	Optional[int]							  =						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_					:	Dict							  =						parser.parse_args()
 convert_efficientnet_checkpoint(args.model_name, args.pytorch_dump_folder_path, args.save_model, args.push_to_hub)









"""simple docstring"""



import baseaa





def  _snake_case     (    UpperCAmelCase_  :					str			):
     return baseaa.aaaencode(string.encode("""utf-8"""			)			)





def  _snake_case     (    UpperCAmelCase_  :					bytes			):
     return baseaa.aaadecode(UpperCAmelCase_			).decode("""utf-8"""			)


if __name__ == "__main__":
 import doctest

 doctest.testmod()






