


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()
__UpperCamelCase       :       Optional[int]						       =				logging.get_logger(__name__)

__UpperCamelCase       :       str						       =				{
    "b0": efficientnet.EfficientNetBa,
    "b1": efficientnet.EfficientNetBa,
    "b2": efficientnet.EfficientNetBa,
    "b3": efficientnet.EfficientNetBa,
    "b4": efficientnet.EfficientNetBa,
    "b5": efficientnet.EfficientNetBa,
    "b6": efficientnet.EfficientNetBa,
    "b7": efficientnet.EfficientNetBa,
}

__UpperCamelCase       :       Dict						       =				{
    "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 			_a  (				SCREAMING_SNAKE_CASE	:				str     ):







 """simple docstring"""



 UpperCamelCase__					:    Dict          =   EfficientNetConfig()
 UpperCamelCase__					:    Tuple          =   CONFIG_MAP[model_name]['''hidden_dim''']
 UpperCamelCase__					:    Tuple          =   CONFIG_MAP[model_name]['''width_coef''']
 UpperCamelCase__					:    Any          =   CONFIG_MAP[model_name]['''depth_coef''']
 UpperCamelCase__					:    Optional[Any]          =   CONFIG_MAP[model_name]['''image_size''']
 UpperCamelCase__					:    Optional[int]          =   CONFIG_MAP[model_name]['''dropout_rate''']
 UpperCamelCase__					:    Optional[int]          =   CONFIG_MAP[model_name]['''dw_padding''']

 UpperCamelCase__					:    Union[str, Any]          =   '''huggingface/label-files'''
 UpperCamelCase__					:    Tuple          =   '''imagenet-1k-id2label.json'''
 UpperCamelCase__					:    List[str]          =   1000
 UpperCamelCase__					:    Optional[int]          =   json.load(open(hf_hub_download(SCREAMING_SNAKE_CASE    , SCREAMING_SNAKE_CASE    , repo_type='''dataset'''     )    , '''r'''     )     )
 UpperCamelCase__					:    List[str]          =   {int(SCREAMING_SNAKE_CASE     ): v for k, v in idalabel.items()}

 UpperCamelCase__					:    Tuple          =   idalabel
 UpperCamelCase__					:    Optional[Any]          =   {v: k for k, v in idalabel.items()}
 return config

def 			_a  (				):







 """simple docstring"""



 UpperCamelCase__					:    int          =   '''http://images.cocodataset.org/val2017/000000039769.jpg'''
 UpperCamelCase__					:    Dict          =   Image.open(requests.get(SCREAMING_SNAKE_CASE    , stream=SCREAMING_SNAKE_CASE     ).raw     )
 return im

def 			_a  (				SCREAMING_SNAKE_CASE	:				int     ):







 """simple docstring"""



 UpperCamelCase__					:    Optional[int]          =   CONFIG_MAP[model_name]['''image_size''']
 UpperCamelCase__					:    Any          =   EfficientNetImageProcessor(
     size={'''height''': size, '''width''': size}    , image_mean=[0.485, 0.456, 0.406]    , image_std=[0.4785_3944, 0.473_2864, 0.4743_4163]    , do_center_crop=SCREAMING_SNAKE_CASE    , )
 return preprocessor

def 			_a  (				SCREAMING_SNAKE_CASE	:				Tuple     ):







 """simple docstring"""



 UpperCamelCase__					:    List[Any]          =   [v.split('''_'''     )[0].split('''block'''     )[1] for v in original_param_names if v.startswith('''block'''     )]
 UpperCamelCase__					:    Optional[Any]          =   sorted(set(SCREAMING_SNAKE_CASE     )     )
 UpperCamelCase__					:    Optional[Any]          =   len(SCREAMING_SNAKE_CASE     )
 UpperCamelCase__					:    Any          =   {b: str(SCREAMING_SNAKE_CASE     ) for b, i in zip(SCREAMING_SNAKE_CASE    , range(SCREAMING_SNAKE_CASE     )     )}

 UpperCamelCase__					:    Any          =   []
 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:
  UpperCamelCase__					:    Union[str, Any]          =   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''')     )

 UpperCamelCase__					:    Any          =   {}
 for item in rename_keys:
  if item[0] in original_param_names:
   UpperCamelCase__					:    Any          =   '''efficientnet.''' + item[1]

 UpperCamelCase__					:    List[Any]          =   '''classifier.weight'''
 UpperCamelCase__					:    Dict          =   '''classifier.bias'''
 return key_mapping

def 			_a  (				SCREAMING_SNAKE_CASE	:				Optional[Any]    , SCREAMING_SNAKE_CASE	:				List[Any]    , SCREAMING_SNAKE_CASE	:				Optional[Any]     ):







 """simple docstring"""



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

  UpperCamelCase__					:    Dict          =   key_mapping[key]
  if "_conv" in key and "kernel" in key:
   UpperCamelCase__					:    str          =   torch.from_numpy(SCREAMING_SNAKE_CASE     ).permute(3    , 2    , 0    , 1     )
  elif "depthwise_kernel" in key:
   UpperCamelCase__					:    Optional[Any]          =   torch.from_numpy(SCREAMING_SNAKE_CASE     ).permute(2    , 3    , 0    , 1     )
  elif "kernel" in key:
   UpperCamelCase__					:    int          =   torch.from_numpy(np.transpose(SCREAMING_SNAKE_CASE     )     )
  else:
   UpperCamelCase__					:    int          =   torch.from_numpy(SCREAMING_SNAKE_CASE     )

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

@torch.no_grad()
def 			_a  (				SCREAMING_SNAKE_CASE	:				int    , SCREAMING_SNAKE_CASE	:				Any    , SCREAMING_SNAKE_CASE	:				str    , SCREAMING_SNAKE_CASE	:				List[str]     ):







 """simple docstring"""



 UpperCamelCase__					:    Tuple          =   model_classes[model_name](
     include_top=SCREAMING_SNAKE_CASE    , weights='''imagenet'''    , input_tensor=SCREAMING_SNAKE_CASE    , input_shape=SCREAMING_SNAKE_CASE    , pooling=SCREAMING_SNAKE_CASE    , classes=1000    , classifier_activation='''softmax'''    , )

 UpperCamelCase__					:    List[Any]          =   original_model.trainable_variables
 UpperCamelCase__					:    Union[str, Any]          =   original_model.non_trainable_variables
 UpperCamelCase__					:    Any          =   {param.name: param.numpy() for param in tf_params}
 for param in tf_non_train_params:
  UpperCamelCase__					:    Any          =   param.numpy()
 UpperCamelCase__					:    Tuple          =   list(tf_params.keys()     )

 # Load HuggingFace model
 UpperCamelCase__					:    Tuple          =   get_efficientnet_config(SCREAMING_SNAKE_CASE     )
 UpperCamelCase__					:    Tuple          =   EfficientNetForImageClassification(SCREAMING_SNAKE_CASE     ).eval()
 UpperCamelCase__					:    str          =   hf_model.state_dict()

 # Create src-to-dst parameter name mapping dictionary
 print('''Converting parameters...'''     )
 UpperCamelCase__					:    Any          =   rename_keys(SCREAMING_SNAKE_CASE     )
 replace_params(SCREAMING_SNAKE_CASE    , SCREAMING_SNAKE_CASE    , SCREAMING_SNAKE_CASE     )

 # Initialize preprocessor and preprocess input image
 UpperCamelCase__					:    Optional[Any]          =   convert_image_processor(SCREAMING_SNAKE_CASE     )
 UpperCamelCase__					:    Union[str, Any]          =   preprocessor(images=prepare_img()    , return_tensors='''pt'''     )

 # HF model inference
 hf_model.eval()
 with torch.no_grad():
  UpperCamelCase__					:    Optional[Any]          =   hf_model(**SCREAMING_SNAKE_CASE     )
 UpperCamelCase__					:    Optional[int]          =   outputs.logits.detach().numpy()

 # Original model inference
 UpperCamelCase__					:    List[Any]          =   False
 UpperCamelCase__					:    Tuple          =   CONFIG_MAP[model_name]['''image_size''']
 UpperCamelCase__					:    List[str]          =   prepare_img().resize((image_size, image_size)    , resample=PIL.Image.NEAREST     )
 UpperCamelCase__					:    int          =   image.img_to_array(SCREAMING_SNAKE_CASE     )
 UpperCamelCase__					:    str          =   np.expand_dims(SCREAMING_SNAKE_CASE    , axis=0     )
 UpperCamelCase__					:    Optional[int]          =   original_model.predict(SCREAMING_SNAKE_CASE     )

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

 if push_to_hub:
  # Push model and image processor to hub
  print(F"Pushing converted {model_name} to the hub..."     )
  UpperCamelCase__					:    Optional[Any]          =   F"efficientnet-{model_name}"
  preprocessor.push_to_hub(SCREAMING_SNAKE_CASE     )
  hf_model.push_to_hub(SCREAMING_SNAKE_CASE     )


if __name__ == "__main__":
       __UpperCamelCase       :       Any						       =				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")

       __UpperCamelCase       :       Dict						       =				parser.parse_args()
       convert_efficientnet_checkpoint(args.model_name, args.pytorch_dump_folder_path, args.save_model, args.push_to_hub)






from typing import TYPE_CHECKING

from ..utils import _LazyModule


__UpperCamelCase       :       int						       =				{
    "config": [
        "EXTERNAL_DATA_FORMAT_SIZE_LIMIT",
        "OnnxConfig",
        "OnnxConfigWithPast",
        "OnnxSeq2SeqConfigWithPast",
        "PatchingSpec",
    ],
    "convert": ["export", "validate_model_outputs"],
    "features": ["FeaturesManager"],
    "utils": ["ParameterFormat", "compute_serialized_parameters_size"],
}


if TYPE_CHECKING:
       from .config import (
           EXTERNAL_DATA_FORMAT_SIZE_LIMIT,
           OnnxConfig,
           OnnxConfigWithPast,
           OnnxSeqaSeqConfigWithPast,
           PatchingSpec,
       )
       from .convert import export, validate_model_outputs
       from .features import FeaturesManager
       from .utils import ParameterFormat, compute_serialized_parameters_size

else:
       import sys

       __UpperCamelCase       :       List[str]						       =				_LazyModule(__name__, globals()["__file__"], _import_structure, module_spec=__spec__)


