



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

lowercase_								=     {
    '''b0''': efficientnet.EfficientNetBa,
    '''b1''': efficientnet.EfficientNetBa,
    '''b2''': efficientnet.EfficientNetBa,
    '''b3''': efficientnet.EfficientNetBa,
    '''b4''': efficientnet.EfficientNetBa,
    '''b5''': efficientnet.EfficientNetBa,
    '''b6''': efficientnet.EfficientNetBa,
    '''b7''': efficientnet.EfficientNetBa,
}

lowercase_								=     {
    '''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 __lowerCAmelCase (     SCREAMING_SNAKE_CASE_  ):
			lowercase__					  =				EfficientNetConfig()
			lowercase__					  =				CONFIG_MAP[model_name]["hidden_dim"]
			lowercase__					  =				CONFIG_MAP[model_name]["width_coef"]
			lowercase__					  =				CONFIG_MAP[model_name]["depth_coef"]
			lowercase__					  =				CONFIG_MAP[model_name]["image_size"]
			lowercase__					  =				CONFIG_MAP[model_name]["dropout_rate"]
			lowercase__					  =				CONFIG_MAP[model_name]["dw_padding"]

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

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



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



def __lowerCAmelCase (     SCREAMING_SNAKE_CASE_  ):
			lowercase__					  =				CONFIG_MAP[model_name]["image_size"]
			lowercase__					  =				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=_A						,  )
			return preprocessor



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

			lowercase__					  =				[]
			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__					  =				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__					  =				{}
			for item in rename_keys:
						if item[0] in original_param_names:
									lowercase__					  =				"efficientnet." + item[1]

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



def __lowerCAmelCase (     SCREAMING_SNAKE_CASE_						,  SCREAMING_SNAKE_CASE_						,  SCREAMING_SNAKE_CASE_  ):

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

						lowercase__					  =				key_mapping[key]
						if "_conv" in key and "kernel" in key:
									lowercase__					  =				torch.from_numpy(_A  ).permute(3						,  2						,  0						,  1  )
						elif "depthwise_kernel" in key:
									lowercase__					  =				torch.from_numpy(_A  ).permute(2						,  3						,  0						,  1  )
						elif "kernel" in key:
									lowercase__					  =				torch.from_numpy(np.transpose(_A  )  )
						else:
									lowercase__					  =				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 __lowerCAmelCase (     SCREAMING_SNAKE_CASE_						,  SCREAMING_SNAKE_CASE_						,  SCREAMING_SNAKE_CASE_						,  SCREAMING_SNAKE_CASE_  ):
			lowercase__					  =				model_classes[model_name](
			    include_top=_A						,  weights="imagenet"						,  input_tensor=_A						,  input_shape=_A						,  pooling=_A						,  classes=1000						,  classifier_activation="softmax"						,  )

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

			# Load HuggingFace model
			lowercase__					  =				get_efficientnet_config(_A  )
			lowercase__					  =				EfficientNetForImageClassification(_A  ).eval()
			lowercase__					  =				hf_model.state_dict()

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

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

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

			# Original model inference
			lowercase__					  =				False
			lowercase__					  =				CONFIG_MAP[model_name]["image_size"]
			lowercase__					  =				prepare_img().resize((image_size, image_size)						,  resample=PIL.Image.NEAREST  )
			lowercase__					  =				image.img_to_array(_A  )
			lowercase__					  =				np.expand_dims(_A						,  axis=0  )
			lowercase__					  =				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__					  =				f'''efficientnet-{model_name}'''
						preprocessor.push_to_hub(_A  )
						hf_model.push_to_hub(_A  )


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

			lowercase_								=     parser.parse_args()
			convert_efficientnet_checkpoint(args.model_name, args.pytorch_dump_folder_path, args.save_model, args.push_to_hub)









import unittest

import numpy as np
import requests

from transformers.testing_utils import require_torch, require_vision
from transformers.utils import is_torch_available, is_vision_available

from ...test_image_processing_common import ImageProcessingSavingTestMixin, prepare_image_inputs


if is_torch_available():
							import torch

							from transformers.pytorch_utils import is_torch_greater_or_equal_than_1_11
else:
							lowercase_								=     False

if is_vision_available():
							from PIL import Image

							from transformers import PixaStructImageProcessor
class 				_snake_case			(					unittest.TestCase):




				def __init__(						self					:						List[Any],					__lowercase					:						int,					__lowercase					:						Optional[int]=7,					__lowercase					:						List[str]=3,					__lowercase					:						Tuple=18,					__lowercase					:						List[Any]=30,					__lowercase					:						Tuple=400,					__lowercase					:						Any=None,					__lowercase					:						Optional[int]=True,					__lowercase					:						List[str]=True,					__lowercase					:						Union[str, Any]=None,					):
							lowercase__					  =				size if size is not None else {"height": 20, "width": 20}
							lowercase__					  =				parent
							lowercase__					  =				batch_size
							lowercase__					  =				num_channels
							lowercase__					  =				image_size
							lowercase__					  =				min_resolution
							lowercase__					  =				max_resolution
							lowercase__					  =				size
							lowercase__					  =				do_normalize
							lowercase__					  =				do_convert_rgb
							lowercase__					  =				[512, 1024, 2048, 4096]
							lowercase__					  =				patch_size if patch_size is not None else {"height": 16, "width": 16}




				def 							A__      (						self					:						List[str]						):
							return {"do_normalize": self.do_normalize, "do_convert_rgb": self.do_convert_rgb}




				def 							A__      (						self					:						Any						):
							lowercase__					  =				"https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/tasks/australia.jpg"
							lowercase__					  =				Image.open(requests.get(__lowercase,					stream=__lowercase						).raw						).convert("RGB"						)
							return raw_image
@unittest.skipIf(
    not is_torch_greater_or_equal_than_1_11    ,	reason="""`Pix2StructImageProcessor` requires `torch>=1.11.0`."""    ,	)
@require_torch
@require_vision
class 				_snake_case			(					lowercase__    ,	unittest.TestCase):
				UpperCamelCase__				:					Any     		=PixaStructImageProcessor if is_vision_available() else None




				def 							A__      (						self					:						Any						):
							lowercase__					  =				PixaStructImageProcessingTester(self						)




				@property
				def 							A__      (						self					:						Union[str, Any]						):
							return self.image_processor_tester.prepare_image_processor_dict()




				def 							A__      (						self					:						Optional[Any]						):
							lowercase__					  =				self.image_processing_class(**self.image_processor_dict						)
							self.assertTrue(hasattr(__lowercase,					"do_normalize"						)						)
							self.assertTrue(hasattr(__lowercase,					"do_convert_rgb"						)						)




				def 							A__      (						self					:						Optional[int]						):
							lowercase__					  =				self.image_processor_tester.prepare_dummy_image()

							lowercase__					  =				self.image_processing_class(**self.image_processor_dict						)
							lowercase__					  =				2048

							lowercase__					  =				image_processor(__lowercase,					return_tensors="pt",					max_patches=__lowercase						)
							self.assertTrue(torch.allclose(inputs.flattened_patches.mean(),					torch.tensor(0.0606						),					atol=1e-3,					rtol=1e-3						)						)




				def 							A__      (						self					:						Union[str, Any]						):
							# Initialize image_processor
							lowercase__					  =				self.image_processing_class(**self.image_processor_dict						)
							# create random PIL images
							lowercase__					  =				prepare_image_inputs(self.image_processor_tester,					equal_resolution=__lowercase						)
							for image in image_inputs:
										self.assertIsInstance(__lowercase,					Image.Image						)

							# Test not batched input
							lowercase__					  =				(
							    (self.image_processor_tester.patch_size["height"] * self.image_processor_tester.patch_size["width"])
							    * self.image_processor_tester.num_channels
							) + 2

							for max_patch in self.image_processor_tester.max_patches:
										# Test not batched input
										lowercase__					  =				image_processor(
										    image_inputs[0],					return_tensors="pt",					max_patches=__lowercase						).flattened_patches
										self.assertEqual(
										    encoded_images.shape,					(1, max_patch, expected_hidden_dim),					)

										# Test batched
										lowercase__					  =				image_processor(
										    __lowercase,					return_tensors="pt",					max_patches=__lowercase						).flattened_patches
										self.assertEqual(
										    encoded_images.shape,					(self.image_processor_tester.batch_size, max_patch, expected_hidden_dim),					)




				def 							A__      (						self					:						int						):
							# Initialize image_processor
							lowercase__					  =				self.image_processing_class(**self.image_processor_dict						)
							# create random PIL images
							lowercase__					  =				prepare_image_inputs(self.image_processor_tester,					equal_resolution=__lowercase						)
							for image in image_inputs:
										self.assertIsInstance(__lowercase,					Image.Image						)

							# Test not batched input
							lowercase__					  =				(
							    (self.image_processor_tester.patch_size["height"] * self.image_processor_tester.patch_size["width"])
							    * self.image_processor_tester.num_channels
							) + 2

							lowercase__					  =				True

							for max_patch in self.image_processor_tester.max_patches:
										# Test not batched input
										with self.assertRaises(__lowercase						):
													lowercase__					  =				image_processor(
													    image_inputs[0],					return_tensors="pt",					max_patches=__lowercase						).flattened_patches

										lowercase__					  =				"Hello"

										lowercase__					  =				image_processor(
										    image_inputs[0],					return_tensors="pt",					max_patches=__lowercase,					header_text=__lowercase						).flattened_patches
										self.assertEqual(
										    encoded_images.shape,					(1, max_patch, expected_hidden_dim),					)

										# Test batched
										lowercase__					  =				image_processor(
										    __lowercase,					return_tensors="pt",					max_patches=__lowercase,					header_text=__lowercase						).flattened_patches
										self.assertEqual(
										    encoded_images.shape,					(self.image_processor_tester.batch_size, max_patch, expected_hidden_dim),					)




				def 							A__      (						self					:						Tuple						):
							# Initialize image_processor
							lowercase__					  =				self.image_processing_class(**self.image_processor_dict						)
							# create random numpy tensors
							lowercase__					  =				prepare_image_inputs(self.image_processor_tester,					equal_resolution=__lowercase,					numpify=__lowercase						)
							for image in image_inputs:
										self.assertIsInstance(__lowercase,					np.ndarray						)

							lowercase__					  =				(
							    (self.image_processor_tester.patch_size["height"] * self.image_processor_tester.patch_size["width"])
							    * self.image_processor_tester.num_channels
							) + 2

							for max_patch in self.image_processor_tester.max_patches:
										# Test not batched input
										lowercase__					  =				image_processor(
										    image_inputs[0],					return_tensors="pt",					max_patches=__lowercase						).flattened_patches
										self.assertEqual(
										    encoded_images.shape,					(1, max_patch, expected_hidden_dim),					)

										# Test batched
										lowercase__					  =				image_processor(
										    __lowercase,					return_tensors="pt",					max_patches=__lowercase						).flattened_patches
										self.assertEqual(
										    encoded_images.shape,					(self.image_processor_tester.batch_size, max_patch, expected_hidden_dim),					)




				def 							A__      (						self					:						Any						):
							# Initialize image_processor
							lowercase__					  =				self.image_processing_class(**self.image_processor_dict						)
							# create random PyTorch tensors
							lowercase__					  =				prepare_image_inputs(self.image_processor_tester,					equal_resolution=__lowercase,					torchify=__lowercase						)
							for image in image_inputs:
										self.assertIsInstance(__lowercase,					torch.Tensor						)

							# Test not batched input
							lowercase__					  =				(
							    (self.image_processor_tester.patch_size["height"] * self.image_processor_tester.patch_size["width"])
							    * self.image_processor_tester.num_channels
							) + 2

							for max_patch in self.image_processor_tester.max_patches:
										# Test not batched input
										lowercase__					  =				image_processor(
										    image_inputs[0],					return_tensors="pt",					max_patches=__lowercase						).flattened_patches
										self.assertEqual(
										    encoded_images.shape,					(1, max_patch, expected_hidden_dim),					)

										# Test batched
										lowercase__					  =				image_processor(
										    __lowercase,					return_tensors="pt",					max_patches=__lowercase						).flattened_patches
										self.assertEqual(
										    encoded_images.shape,					(self.image_processor_tester.batch_size, max_patch, expected_hidden_dim),					)
@unittest.skipIf(
    not is_torch_greater_or_equal_than_1_11    ,	reason="""`Pix2StructImageProcessor` requires `torch>=1.11.0`."""    ,	)
@require_torch
@require_vision
class 				_snake_case			(					lowercase__    ,	unittest.TestCase):
				UpperCamelCase__				:					Optional[int]     		=PixaStructImageProcessor if is_vision_available() else None




				def 							A__      (						self					:						Optional[int]						):
							lowercase__					  =				PixaStructImageProcessingTester(self,					num_channels=4						)
							lowercase__					  =				3




				@property
				def 							A__      (						self					:						Union[str, Any]						):
							return self.image_processor_tester.prepare_image_processor_dict()




				def 							A__      (						self					:						Dict						):
							lowercase__					  =				self.image_processing_class(**self.image_processor_dict						)
							self.assertTrue(hasattr(__lowercase,					"do_normalize"						)						)
							self.assertTrue(hasattr(__lowercase,					"do_convert_rgb"						)						)




				def 							A__      (						self					:						Union[str, Any]						):
							# Initialize image_processor
							lowercase__					  =				self.image_processing_class(**self.image_processor_dict						)
							# create random PIL images
							lowercase__					  =				prepare_image_inputs(self.image_processor_tester,					equal_resolution=__lowercase						)
							for image in image_inputs:
										self.assertIsInstance(__lowercase,					Image.Image						)

							# Test not batched input
							lowercase__					  =				(
							    (self.image_processor_tester.patch_size["height"] * self.image_processor_tester.patch_size["width"])
							    * (self.image_processor_tester.num_channels - 1)
							) + 2

							for max_patch in self.image_processor_tester.max_patches:
										# Test not batched input
										lowercase__					  =				image_processor(
										    image_inputs[0],					return_tensors="pt",					max_patches=__lowercase						).flattened_patches
										self.assertEqual(
										    encoded_images.shape,					(1, max_patch, expected_hidden_dim),					)

										# Test batched
										lowercase__					  =				image_processor(
										    __lowercase,					return_tensors="pt",					max_patches=__lowercase						).flattened_patches
										self.assertEqual(
										    encoded_images.shape,					(self.image_processor_tester.batch_size, max_patch, expected_hidden_dim),					)




