






'''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							=						logging.get_logger(__name__)

SCREAMING_SNAKE_CASE							=						{
    '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							=						{
    'b0': {
        'hidden_dim': 1_280,
        'width_coef': 1.0,
        'depth_coef': 1.0,
        'image_size': 224,
        'dropout_rate': 0.2,
        'dw_padding': [],
    },
    'b1': {
        'hidden_dim': 1_280,
        'width_coef': 1.0,
        'depth_coef': 1.1,
        'image_size': 240,
        'dropout_rate': 0.2,
        'dw_padding': [16],
    },
    'b2': {
        'hidden_dim': 1_408,
        'width_coef': 1.1,
        'depth_coef': 1.2,
        'image_size': 260,
        'dropout_rate': 0.3,
        'dw_padding': [5, 8, 16],
    },
    'b3': {
        'hidden_dim': 1_536,
        'width_coef': 1.2,
        'depth_coef': 1.4,
        'image_size': 300,
        'dropout_rate': 0.3,
        'dw_padding': [5, 18],
    },
    'b4': {
        'hidden_dim': 1_792,
        'width_coef': 1.4,
        'depth_coef': 1.8,
        'image_size': 380,
        'dropout_rate': 0.4,
        'dw_padding': [6],
    },
    'b5': {
        'hidden_dim': 2_048,
        'width_coef': 1.6,
        'depth_coef': 2.2,
        'image_size': 456,
        'dropout_rate': 0.4,
        'dw_padding': [13, 27],
    },
    'b6': {
        'hidden_dim': 2_304,
        'width_coef': 1.8,
        'depth_coef': 2.6,
        'image_size': 528,
        'dropout_rate': 0.5,
        'dw_padding': [31],
    },
    'b7': {
        'hidden_dim': 2_560,
        'width_coef': 2.0,
        'depth_coef': 3.1,
        'image_size': 600,
        'dropout_rate': 0.5,
        'dw_padding': [18],
    },
}


def 				lowercase_					(     __A			:							Optional[int]      )							->   Tuple:



 """simple docstring"""




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

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

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


def 				lowercase_					(     )							->   Dict:



 """simple docstring"""




 lowercase       : str						='''http://images.cocodataset.org/val2017/000000039769.jpg'''
 lowercase       : Tuple						=Image.open(requests.get(__A       ,   stream=__A      ).raw      )
 return im


def 				lowercase_					(     __A			:							int      )							->   Dict:



 """simple docstring"""




 lowercase       : Optional[Any]						=CONFIG_MAP[model_name]['''image_size''']
 lowercase       : Tuple						=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 				lowercase_					(     __A			:							Union[str, Any]      )							->   Optional[int]:



 """simple docstring"""




 lowercase       : Union[str, Any]						=[v.split('''_'''      )[0].split('''block'''      )[1] for v in original_param_names if v.startswith('''block'''      )]
 lowercase       : Any						=sorted(set(__A      )      )
 lowercase       : Dict						=len(__A      )
 lowercase       : Dict						={b: str(__A      ) for b, i in zip(__A       ,   range(__A      )      )}

 lowercase       : str						=[]
 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:
  lowercase       : List[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''')      )

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

 lowercase       : str						='''classifier.weight'''
 lowercase       : Optional[Any]						='''classifier.bias'''
 return key_mapping


def 				lowercase_					(     __A			:							Any       ,   __A			:							Dict       ,   __A			:							List[Any]      )							->   Union[str, Any]:



 """simple docstring"""




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

  lowercase       : Union[str, Any]						=key_mapping[key]
  if "_conv" in key and "kernel" in key:
   lowercase       : Dict						=torch.from_numpy(__A      ).permute(3       ,   2       ,   0       ,   1      )
  elif "depthwise_kernel" in key:
   lowercase       : Optional[int]						=torch.from_numpy(__A      ).permute(2       ,   3       ,   0       ,   1      )
  elif "kernel" in key:
   lowercase       : Optional[Any]						=torch.from_numpy(np.transpose(__A      )      )
  else:
   lowercase       : str						=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 				lowercase_					(     __A			:							Dict       ,   __A			:							str       ,   __A			:							List[Any]       ,   __A			:							int      )							->   List[Any]:



 """simple docstring"""




 lowercase       : Optional[Any]						=model_classes[model_name](
     include_top=__A       ,   weights='''imagenet'''       ,   input_tensor=__A       ,   input_shape=__A       ,   pooling=__A       ,   classes=1_0_0_0       ,   classifier_activation='''softmax'''       ,   )

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

 # Load HuggingFace model
 lowercase       : Optional[Any]						=get_efficientnet_config(__A      )
 lowercase       : str						=EfficientNetForImageClassification(__A      ).eval()
 lowercase       : str						=hf_model.state_dict()

 # Create src-to-dst parameter name mapping dictionary
 print('''Converting parameters...'''      )
 lowercase       : Optional[int]						=rename_keys(__A      )
 replace_params(__A       ,   __A       ,   __A      )

 # Initialize preprocessor and preprocess input image
 lowercase       : Optional[int]						=convert_image_processor(__A      )
 lowercase       : List[Any]						=preprocessor(images=prepare_img()       ,   return_tensors='''pt'''      )

 # HF model inference
 hf_model.eval()
 with torch.no_grad():
  lowercase       : Any						=hf_model(**__A      )
 lowercase       : str						=outputs.logits.detach().numpy()

 # Original model inference
 lowercase       : List[str]						=False
 lowercase       : int						=CONFIG_MAP[model_name]['''image_size''']
 lowercase       : str						=prepare_img().resize((image_size, image_size)       ,   resample=PIL.Image.NEAREST      )
 lowercase       : Dict						=image.img_to_array(__A      )
 lowercase       : str						=np.expand_dims(__A       ,   axis=0      )
 lowercase       : Tuple						=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...'      )
  lowercase       : Optional[Any]						=F'efficientnet-{model_name}'
  preprocessor.push_to_hub(__A      )
  hf_model.push_to_hub(__A      )


if __name__ == "__main__":
      SCREAMING_SNAKE_CASE							=						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							=						parser.parse_args()
      convert_efficientnet_checkpoint(args.model_name, args.pytorch_dump_folder_path, args.save_model, args.push_to_hub)











'''simple docstring'''



from ...configuration_utils import PretrainedConfig
from ...utils import logging
from ...utils.backbone_utils import BackboneConfigMixin, get_aligned_output_features_output_indices


SCREAMING_SNAKE_CASE							=						logging.get_logger(__name__)

SCREAMING_SNAKE_CASE							=						{
    'google/bit-50': 'https://huggingface.co/google/bit-50/resolve/main/config.json',
}
class UpperCAmelCase_       (     __A					,							__A					):




      """simple docstring"""




      UpperCamelCase_             =      '''bit'''
      UpperCamelCase_             =      ['''preactivation''', '''bottleneck''']
      UpperCamelCase_             =      ['''SAME''', '''VALID''']






      def __init__(			self      :		Any  ,   UpperCAmelCase      :		Optional[int]=3  ,   UpperCAmelCase      :		Any=64  ,   UpperCAmelCase      :		List[str]=[256, 512, 1024, 2048]  ,   UpperCAmelCase      :		Dict=[3, 4, 6, 3]  ,   UpperCAmelCase      :		List[Any]="preactivation"  ,   UpperCAmelCase      :		Tuple="relu"  ,   UpperCAmelCase      :		Tuple=None  ,   UpperCAmelCase      :		Tuple=32  ,   UpperCAmelCase      :		Optional[int]=0.0  ,   UpperCAmelCase      :		Union[str, Any]=False  ,   UpperCAmelCase      :		Dict=32  ,   UpperCAmelCase      :		Any=1  ,   UpperCAmelCase      :		str=None  ,   UpperCAmelCase      :		Union[str, Any]=None  ,   **UpperCAmelCase      :		str  ,   )	->	Dict:


       '''simple docstring'''

       super().__init__(**UpperCAmelCase		)
       if layer_type not in self.layer_types:
        raise ValueError(f'layer_type={layer_type} is not one of {",".join(self.layer_types		)}'		)
       if global_padding is not None:
        if global_padding.upper() in self.supported_padding:
         lowercase       : Any						=global_padding.upper()
        else:
         raise ValueError(f'Padding strategy {global_padding} not supported'		)
       lowercase       : List[Any]						=num_channels
       lowercase       : List[str]						=embedding_size
       lowercase       : Union[str, Any]						=hidden_sizes
       lowercase       : Union[str, Any]						=depths
       lowercase       : Optional[int]						=layer_type
       lowercase       : Optional[Any]						=hidden_act
       lowercase       : List[str]						=global_padding
       lowercase       : Dict						=num_groups
       lowercase       : Optional[Any]						=drop_path_rate
       lowercase       : Union[str, Any]						=embedding_dynamic_padding
       lowercase       : Any						=output_stride
       lowercase       : Union[str, Any]						=width_factor

       lowercase       : Union[str, Any]						=['''stem'''] + [f'stage{idx}' for idx in range(1  ,   len(UpperCAmelCase		) + 1		)]
       lowercase	,		lowercase       : List[str]						=get_aligned_output_features_output_indices(
           out_features=UpperCAmelCase  ,   out_indices=UpperCAmelCase  ,   stage_names=self.stage_names		)



