

'''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 	lowerCamelCase__							(   a__)		->     Tuple:



    """simple docstring"""







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

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

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

def 	lowerCamelCase__							(   )		->     List[str]:



    """simple docstring"""







    _snake_case			:			Tuple				       =		'http://images.cocodataset.org/val2017/000000039769.jpg'
    _snake_case			:			List[Any]				       =		Image.open(requests.get(lowerCAmelCase__      ,   stream=lowerCAmelCase__).raw)
    return im

def 	lowerCamelCase__							(   a__)		->     Tuple:



    """simple docstring"""







    _snake_case			:			int				       =		CONFIG_MAP[model_name]['image_size']
    _snake_case			:			Dict				       =		EfficientNetImageProcessor(
        size={'height': size, 'width': size}      ,   image_mean=[0.4_8_5, 0.4_5_6, 0.4_0_6]      ,   image_std=[0.4_7_8_5_3_9_4_4, 0.4_7_3_2_8_6_4, 0.4_7_4_3_4_1_6_3]      ,   do_center_crop=lowerCAmelCase__      ,   )
    return preprocessor

def 	lowerCamelCase__							(   a__)		->     str:



    """simple docstring"""







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

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

    _snake_case			:			List[Any]				       =		{}
    for item in rename_keys:
        if item[0] in original_param_names:
            _snake_case			:			Union[str, Any]				       =		'efficientnet.' + item[1]

    _snake_case			:			Union[str, Any]				       =		'classifier.weight'
    _snake_case			:			str				       =		'classifier.bias'
    return key_mapping

def 	lowerCamelCase__							(   a__      ,   a__      ,   a__)		->     Optional[int]:



    """simple docstring"""







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

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

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

@torch.no_grad()
def 	lowerCamelCase__							(   a__      ,   a__      ,   a__      ,   a__)		->     List[str]:



    """simple docstring"""







    _snake_case			:			Tuple				       =		model_classes[model_name](
        include_top=lowerCAmelCase__      ,   weights='imagenet'      ,   input_tensor=lowerCAmelCase__      ,   input_shape=lowerCAmelCase__      ,   pooling=lowerCAmelCase__      ,   classes=1_0_0_0      ,   classifier_activation='softmax'      ,   )

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

    # Load HuggingFace model
    _snake_case			:			str				       =		get_efficientnet_config(lowerCAmelCase__)
    _snake_case			:			Tuple				       =		EfficientNetForImageClassification(lowerCAmelCase__).eval()
    _snake_case			:			List[Any]				       =		hf_model.state_dict()

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

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

    # HF model inference
    hf_model.eval()
    with torch.no_grad():
        _snake_case			:			List[Any]				       =		hf_model(**lowerCAmelCase__)
    _snake_case			:			str				       =		outputs.logits.detach().numpy()

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

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

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


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"""






def      UpperCAmelCase__			(							lowerCAmelCase__	:int = 5_0						)					->       int:
      '''simple docstring'''


      lowercase								=      [1] * (length + 1)

      for row_length in range(3   ,						length + 1						):
            for block_length in range(3   ,						row_length + 1						):
                  for block_start in range(row_length - block_length						):
                        ways_number[row_length] += ways_number[
                            row_length - block_start - block_length - 1
                        ]

                  ways_number[row_length] += 1

      return ways_number[length]


if __name__ == "__main__":
       print(F"""{solution() = }""")



