


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

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

A     :   Optional[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 _lowerCamelCase	(		_UpperCamelCase      ):

			'''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(_UpperCamelCase    , _UpperCamelCase    , repo_type="dataset"      )    , "r"      )      )
			__lowerCAmelCase				    =			{int(_UpperCamelCase      ): v for k, v in idalabel.items()}

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


def _lowerCamelCase	(		):

			'''simple docstring'''




			__lowerCAmelCase				    =			"http://images.cocodataset.org/val2017/000000039769.jpg"
			__lowerCAmelCase				    =			Image.open(requests.get(_UpperCamelCase    , stream=_UpperCamelCase      ).raw      )
			return im


def _lowerCamelCase	(		_UpperCamelCase      ):

			'''simple docstring'''




			__lowerCAmelCase				    =			CONFIG_MAP[model_name]["image_size"]
			__lowerCAmelCase				    =			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 _lowerCamelCase	(		_UpperCamelCase      ):

			'''simple docstring'''




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

			__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 _lowerCamelCase	(		_UpperCamelCase    , _UpperCamelCase    , _UpperCamelCase      ):

			'''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(_UpperCamelCase      ).permute(3    , 2    , 0    , 1      )
						elif "depthwise_kernel" in key:
									__lowerCAmelCase				    =			torch.from_numpy(_UpperCamelCase      ).permute(2    , 3    , 0    , 1      )
						elif "kernel" in key:
									__lowerCAmelCase				    =			torch.from_numpy(np.transpose(_UpperCamelCase      )      )
						else:
									__lowerCAmelCase				    =			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 _lowerCamelCase	(		_UpperCamelCase    , _UpperCamelCase    , _UpperCamelCase    , _UpperCamelCase      ):

			'''simple docstring'''




			__lowerCAmelCase				    =			model_classes[model_name](
			    include_top=_UpperCamelCase    , weights="imagenet"    , input_tensor=_UpperCamelCase    , input_shape=_UpperCamelCase    , pooling=_UpperCamelCase    , 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(_UpperCamelCase      )
			__lowerCAmelCase				    =			EfficientNetForImageClassification(_UpperCamelCase      ).eval()
			__lowerCAmelCase				    =			hf_model.state_dict()

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

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

			# HF model inference
			hf_model.eval()
			with torch.no_grad():
						__lowerCAmelCase				    =			hf_model(**_UpperCamelCase      )
			__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(_UpperCamelCase      )
			__lowerCAmelCase				    =			np.expand_dims(_UpperCamelCase    , axis=0      )
			__lowerCAmelCase				    =			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..."      )
						__lowerCAmelCase				    =			f"efficientnet-{model_name}"
						preprocessor.push_to_hub(_UpperCamelCase      )
						hf_model.push_to_hub(_UpperCamelCase      )


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

	A     :   Any			    =			parser.parse_args()
	convert_efficientnet_checkpoint(args.model_name, args.pytorch_dump_folder_path, args.save_model, args.push_to_hub)








"""simple docstring"""


import unittest

from transformers import (
    MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING,
    TF_MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING,
    TextaTextGenerationPipeline,
    pipeline,
)
from transformers.testing_utils import is_pipeline_test, require_tf, require_torch
from transformers.utils import is_torch_available

from .test_pipelines_common import ANY


if is_torch_available():
	import torch
@is_pipeline_test
class   _UpperCamelCase  (   unittest.TestCase		):
							'''simple docstring'''







							__UpperCAmelCase						:    Union[str, Any]				      =MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING
							__UpperCAmelCase						:    Union[str, Any]				      =TF_MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING

							def 			snake_case				(     self    ,   __a    ,   __a    ,   __a	):
										__lowerCAmelCase				    =			TextaTextGenerationPipeline(model=__a    ,   tokenizer=__a	)
										return generator, ["Something to write", "Something else"]

							def 			snake_case				(     self    ,   __a    ,   __a	):
										__lowerCAmelCase				    =			generator("Something there"	)
										self.assertEqual(__a    ,   [{"generated_text": ANY(__a	)}]	)
										# These are encoder decoder, they don't just append to incoming string
										self.assertFalse(outputs[0]["generated_text"].startswith("Something there"	)	)

										__lowerCAmelCase				    =			generator(["This is great !", "Something else"]    ,   num_return_sequences=2    ,   do_sample=__a	)
										self.assertEqual(
										    __a    ,   [
										        [{"generated_text": ANY(__a	)}, {"generated_text": ANY(__a	)}],
										        [{"generated_text": ANY(__a	)}, {"generated_text": ANY(__a	)}],
										    ]    ,   )

										__lowerCAmelCase				    =			generator(
										    ["This is great !", "Something else"]    ,   num_return_sequences=2    ,   batch_size=2    ,   do_sample=__a	)
										self.assertEqual(
										    __a    ,   [
										        [{"generated_text": ANY(__a	)}, {"generated_text": ANY(__a	)}],
										        [{"generated_text": ANY(__a	)}, {"generated_text": ANY(__a	)}],
										    ]    ,   )

										with self.assertRaises(__a	):
													generator(4	)

							@require_torch
							def 			snake_case				(     self	):
										__lowerCAmelCase				    =			pipeline("text2text-generation"    ,   model="patrickvonplaten/t5-tiny-random"    ,   framework="pt"	)
										# do_sample=False necessary for reproducibility
										__lowerCAmelCase				    =			generator("Something there"    ,   do_sample=__a	)
										self.assertEqual(__a    ,   [{"generated_text": ""}]	)

										__lowerCAmelCase				    =			3
										__lowerCAmelCase				    =			generator(
										    "Something there"    ,   num_return_sequences=__a    ,   num_beams=__a    ,   )
										__lowerCAmelCase				    =			[
										    {"generated_text": "Beide Beide Beide Beide Beide Beide Beide Beide Beide"},
										    {"generated_text": "Beide Beide Beide Beide Beide Beide Beide Beide"},
										    {"generated_text": ""},
										]
										self.assertEqual(__a    ,   __a	)

										__lowerCAmelCase				    =			generator("This is a test"    ,   do_sample=__a    ,   num_return_sequences=2    ,   return_tensors=__a	)
										self.assertEqual(
										    __a    ,   [
										        {"generated_token_ids": ANY(torch.Tensor	)},
										        {"generated_token_ids": ANY(torch.Tensor	)},
										    ]    ,   )
										__lowerCAmelCase				    =			generator.model.config.eos_token_id
										__lowerCAmelCase				    =			"<pad>"
										__lowerCAmelCase				    =			generator(
										    ["This is a test", "This is a second test"]    ,   do_sample=__a    ,   num_return_sequences=2    ,   batch_size=2    ,   return_tensors=__a    ,   )
										self.assertEqual(
										    __a    ,   [
										        [
										            {"generated_token_ids": ANY(torch.Tensor	)},
										            {"generated_token_ids": ANY(torch.Tensor	)},
										        ],
										        [
										            {"generated_token_ids": ANY(torch.Tensor	)},
										            {"generated_token_ids": ANY(torch.Tensor	)},
										        ],
										    ]    ,   )



							@require_tf
							def 			snake_case				(     self	):
										__lowerCAmelCase				    =			pipeline("text2text-generation"    ,   model="patrickvonplaten/t5-tiny-random"    ,   framework="tf"	)
										# do_sample=False necessary for reproducibility
										__lowerCAmelCase				    =			generator("Something there"    ,   do_sample=__a	)
										self.assertEqual(__a    ,   [{"generated_text": ""}]	)




