





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

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

lowerCAmelCase__     						=			{
    '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		(						lowerCAmelCase__     ):
       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__					     = 1_0_0_0
       lowerCAmelCase__					     = json.load(open(hf_hub_download(lowerCAmelCase__     ,  lowerCAmelCase__     ,  repo_type='dataset'     )     ,  'r'     )     )
       lowerCAmelCase__					     = {int(lowerCAmelCase__     ): v for k, v in idalabel.items()}

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






def 				__lowerCamelCase		(						):
       lowerCAmelCase__					     = 'http://images.cocodataset.org/val2017/000000039769.jpg'
       lowerCAmelCase__					     = Image.open(requests.get(lowerCAmelCase__     ,  stream=lowerCAmelCase__     ).raw     )
       return im






def 				__lowerCamelCase		(						lowerCAmelCase__     ):
       lowerCAmelCase__					     = CONFIG_MAP[model_name]['image_size']
       lowerCAmelCase__					     = 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		(						lowerCAmelCase__     ):
       lowerCAmelCase__					     = [v.split('_'     )[0].split('block'     )[1] for v in original_param_names if v.startswith('block'     )]
       lowerCAmelCase__					     = sorted(set(lowerCAmelCase__     )     )
       lowerCAmelCase__					     = len(lowerCAmelCase__     )
       lowerCAmelCase__					     = {b: str(lowerCAmelCase__     ) for b, i in zip(lowerCAmelCase__     ,  range(lowerCAmelCase__     )     )}

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

       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(lowerCAmelCase__     )
       lowerCAmelCase__					     = EfficientNetForImageClassification(lowerCAmelCase__     ).eval()
       lowerCAmelCase__					     = hf_model.state_dict()

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

       # Initialize preprocessor and preprocess input image
       lowerCAmelCase__					     = convert_image_processor(lowerCAmelCase__     )
       lowerCAmelCase__					     = preprocessor(images=prepare_img()     ,  return_tensors='pt'     )

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


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

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

from math import log

from scipy.constants import Boltzmann, physical_constants

lowerCAmelCase__     						=			300  # TEMPERATURE (unit = K)






def 				__lowerCamelCase		(						lowerCAmelCase__     ,  lowerCAmelCase__     ,  lowerCAmelCase__     ,  ):

       if donor_conc <= 0:
              raise ValueError('Donor concentration should be positive'     )
       elif acceptor_conc <= 0:
              raise ValueError('Acceptor concentration should be positive'     )
       elif intrinsic_conc <= 0:
              raise ValueError('Intrinsic concentration should be positive'     )
       elif donor_conc <= intrinsic_conc:
              raise ValueError(
                  'Donor concentration should be greater than intrinsic concentration'     )
       elif acceptor_conc <= intrinsic_conc:
              raise ValueError(
                  'Acceptor concentration should be greater than intrinsic concentration'     )
       else:
              return (
                  Boltzmann
                  * T
                  * log((donor_conc * acceptor_conc) / intrinsic_conc**2     )
                  / physical_constants["electron volt"][0]
              )


if __name__ == "__main__":
    import doctest

    doctest.testmod()
