






from typing import Optional, Union

import torch
from torch import nn
from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss

from ...activations import ACTaFN
from ...modeling_outputs import BaseModelOutputWithPoolingAndNoAttention, ImageClassifierOutputWithNoAttention
from ...modeling_utils import PreTrainedModel
from ...utils import add_code_sample_docstrings, add_start_docstrings, add_start_docstrings_to_model_forward, logging
from .configuration_mobilenet_va import MobileNetVaConfig


lowercase    				=   logging.get_logger(__name__)


# General docstring
lowercase    				=   "MobileNetV1Config"

# Base docstring
lowercase    				=   "google/mobilenet_v1_1.0_224"
lowercase    				=   [1, 1024, 7, 7]

# Image classification docstring
lowercase    				=   "google/mobilenet_v1_1.0_224"
lowercase    				=   "tabby, tabby cat"


lowercase    				=   [
    "google/mobilenet_v1_1.0_224",
    "google/mobilenet_v1_0.75_192",
    # See all MobileNetV1 models at https://huggingface.co/models?filter=mobilenet_v1
]





def 		__UpperCAmelCase     (	a_				,	a_				,	a_=None):
							snake_case_           =				{}

							if isinstance(a_				,	a_):
														snake_case_           =				model.mobilenet_va
							else:
														snake_case_           =				model

							snake_case_           =				'MobilenetV1/Conv2d_0/'
							snake_case_           =				backbone.conv_stem.convolution.weight
							snake_case_           =				backbone.conv_stem.normalization.bias
							snake_case_           =				backbone.conv_stem.normalization.weight
							snake_case_           =				backbone.conv_stem.normalization.running_mean
							snake_case_           =				backbone.conv_stem.normalization.running_var

							for i in range(13):
														snake_case_           =				i + 1
														snake_case_           =				i * 2

														snake_case_           =				backbone.layer[pt_index]
														snake_case_           =				f'''MobilenetV1/Conv2d_{tf_index}_depthwise/'''
														snake_case_           =				pointer.convolution.weight
														snake_case_           =				pointer.normalization.bias
														snake_case_           =				pointer.normalization.weight
														snake_case_           =				pointer.normalization.running_mean
														snake_case_           =				pointer.normalization.running_var

														snake_case_           =				backbone.layer[pt_index + 1]
														snake_case_           =				f'''MobilenetV1/Conv2d_{tf_index}_pointwise/'''
														snake_case_           =				pointer.convolution.weight
														snake_case_           =				pointer.normalization.bias
														snake_case_           =				pointer.normalization.weight
														snake_case_           =				pointer.normalization.running_mean
														snake_case_           =				pointer.normalization.running_var

							if isinstance(a_				,	a_):
														snake_case_           =				'MobilenetV1/Logits/Conv2d_1c_1x1/'
														snake_case_           =				model.classifier.weight
														snake_case_           =				model.classifier.bias

							return tf_to_pt_map





def 		__UpperCAmelCase     (	a_				,	a_				,	a_):
							try:
														import numpy as np
														import tensorflow as tf
							except ImportError:
														logger.error(
														    'Loading a TensorFlow models in PyTorch, requires TensorFlow to be installed. Please see '
														    'https://www.tensorflow.org/install/ for installation instructions.')
														raise

							# Load weights from TF model
							snake_case_           =				tf.train.list_variables(a_)
							snake_case_           =				{}
							for name, shape in init_vars:
														logger.info(f'''Loading TF weight {name} with shape {shape}''')
														snake_case_           =				tf.train.load_variable(a_				,	a_)
														snake_case_           =				array

							# Build TF to PyTorch weights loading map
							snake_case_           =				_build_tf_to_pytorch_map(a_				,	a_				,	a_)

							for name, pointer in tf_to_pt_map.items():
														logger.info(f'''Importing {name}''')
														if name not in tf_weights:
																					logger.info(f'''{name} not in tf pre-trained weights, skipping''')
																					continue

														snake_case_           =				tf_weights[name]

														if "depthwise_weights" in name:
																					logger.info('Transposing depthwise')
																					snake_case_           =				np.transpose(a_				,	(2, 3, 0, 1))
														elif "weights" in name:
																					logger.info('Transposing')
																					if len(pointer.shape) == 2:  # copying into linear layer
																												snake_case_           =				array.squeeze().transpose()
																					else:
																												snake_case_           =				np.transpose(a_				,	(3, 2, 0, 1))

														if pointer.shape != array.shape:
																					raise ValueError(f'''Pointer shape {pointer.shape} and array shape {array.shape} mismatched''')

														logger.info(f'''Initialize PyTorch weight {name} {array.shape}''')
														snake_case_           =				torch.from_numpy(a_)

														tf_weights.pop(a_				,	a_)
														tf_weights.pop(name + '/RMSProp'				,	a_)
														tf_weights.pop(name + '/RMSProp_1'				,	a_)
														tf_weights.pop(name + '/ExponentialMovingAverage'				,	a_)

							logger.info(f'''Weights not copied to PyTorch model: {", ".join(tf_weights.keys())}''')
							return model





def 		__UpperCAmelCase     (	a_				,	a_):
							snake_case_     ,						snake_case_           =				features.shape[-2:]
							snake_case_     ,						snake_case_           =				conv_layer.stride
							snake_case_     ,						snake_case_           =				conv_layer.kernel_size

							if in_height % stride_height == 0:
														snake_case_           =				max(kernel_height - stride_height				,	0)
							else:
														snake_case_           =				max(kernel_height - (in_height % stride_height)				,	0)

							if in_width % stride_width == 0:
														snake_case_           =				max(kernel_width - stride_width				,	0)
							else:
														snake_case_           =				max(kernel_width - (in_width % stride_width)				,	0)

							snake_case_           =				pad_along_width // 2
							snake_case_           =				pad_along_width - pad_left
							snake_case_           =				pad_along_height // 2
							snake_case_           =				pad_along_height - pad_top

							snake_case_           =				(pad_left, pad_right, pad_top, pad_bottom)
							return nn.functional.pad(a_				,	a_				,	'constant'				,	0.0)




class 					UpperCamelCase_ (     nn.Module							):



	'''simple docstring'''




	def __init__(			self			,     a			,     a			,     a			,     a			,     a = 1			,     a = 1			,     a = False			,     a = True			,     a = True			,     )			->       None:
								super().__init__()
								snake_case_           =				config

								if in_channels % groups != 0:
															raise ValueError(F'''Input channels ({in_channels}) are not divisible by {groups} groups.'''   )
								if out_channels % groups != 0:
															raise ValueError(F'''Output channels ({out_channels}) are not divisible by {groups} groups.'''   )

								snake_case_           =				0 if config.tf_padding else int((kernel_size - 1) / 2   )

								snake_case_           =				nn.Convad(
								    in_channels=a			,     out_channels=a			,     kernel_size=a			,     stride=a			,     padding=a			,     groups=a			,     bias=a			,     padding_mode='zeros'			,     )

								if use_normalization:
															snake_case_           =				nn.BatchNormad(
															    num_features=a			,     eps=config.layer_norm_eps			,     momentum=0.9_997			,     affine=a			,     track_running_stats=a			,     )
								else:
															snake_case_           =				None

								if use_activation:
															if isinstance(a			,     a   ):
																						snake_case_           =				ACTaFN[use_activation]
															elif isinstance(config.hidden_act			,     a   ):
																						snake_case_           =				ACTaFN[config.hidden_act]
															else:
																						snake_case_           =				config.hidden_act
								else:
															snake_case_           =				None






	def 				_UpperCamelCase     (			self			,     a   )			->       torch.Tensor:
								if self.config.tf_padding:
															snake_case_           =				apply_tf_padding(a			,     self.convolution   )
								snake_case_           =				self.convolution(a   )
								if self.normalization is not None:
															snake_case_           =				self.normalization(a   )
								if self.activation is not None:
															snake_case_           =				self.activation(a   )
								return features






class 					UpperCamelCase_ (     snake_case_							):



	'''simple docstring'''




	lowerCAmelCase						=					MobileNetVaConfig
	lowerCAmelCase						=					load_tf_weights_in_mobilenet_va
	lowerCAmelCase						=					'''mobilenet_v1'''
	lowerCAmelCase						=					'''pixel_values'''
	lowerCAmelCase						=					False




	def 				_UpperCamelCase     (			self			,     a   )			->       None:
								if isinstance(a			,     (nn.Linear, nn.Convad)   ):
															module.weight.data.normal_(mean=0.0			,     std=self.config.initializer_range   )
															if module.bias is not None:
																						module.bias.data.zero_()
								elif isinstance(a			,     nn.BatchNormad   ):
															module.bias.data.zero_()
															module.weight.data.fill_(1.0   )






lowercase    				=   r"\n    This model is a PyTorch [torch.nn.Module](https://pytorch.org/docs/stable/nn.html#torch.nn.Module) subclass. Use it\n    as a regular PyTorch Module and refer to the PyTorch documentation for all matter related to general usage and\n    behavior.\n\n    Parameters:\n        config ([`MobileNetV1Config`]): Model configuration class with all the parameters of the model.\n            Initializing with a config file does not load the weights associated with the model, only the\n            configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights.\n"

lowercase    				=   r"\n    Args:\n        pixel_values (`torch.FloatTensor` of shape `(batch_size, num_channels, height, width)`):\n            Pixel values. Pixel values can be obtained using [`AutoImageProcessor`]. See\n            [`MobileNetV1ImageProcessor.__call__`] for details.\n        output_hidden_states (`bool`, *optional*):\n            Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for\n            more detail.\n        return_dict (`bool`, *optional*):\n            Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple.\n"




@add_start_docstrings(
    '''The bare MobileNetV1 model outputting raw hidden-states without any specific head on top.'''			,   snake_case_			,   )
class 					UpperCamelCase_ (     snake_case_							):



	'''simple docstring'''




	def __init__(			self			,     a			,     a = True   )			->       str:
								super().__init__(a   )
								snake_case_           =				config

								snake_case_           =				32
								snake_case_           =				max(int(depth * config.depth_multiplier   )			,     config.min_depth   )

								snake_case_           =				MobileNetVaConvLayer(
								    a			,     in_channels=config.num_channels			,     out_channels=a			,     kernel_size=3			,     stride=2			,     )

								snake_case_           =				[1, 2, 1, 2, 1, 2, 1, 1, 1, 1, 1, 2, 1]

								snake_case_           =				nn.ModuleList()
								for i in range(13   ):
															snake_case_           =				out_channels

															if strides[i] == 2 or i == 0:
																						depth *= 2
																						snake_case_           =				max(int(depth * config.depth_multiplier   )			,     config.min_depth   )

															self.layer.append(
															    MobileNetVaConvLayer(
															        a			,     in_channels=a			,     out_channels=a			,     kernel_size=3			,     stride=strides[i]			,     groups=a			,     )   )

															self.layer.append(
															    MobileNetVaConvLayer(
															        a			,     in_channels=a			,     out_channels=a			,     kernel_size=1			,     )   )

								snake_case_           =				nn.AdaptiveAvgPoolad((1, 1)   ) if add_pooling_layer else None

								# Initialize weights and apply final processing
								self.post_init()




	def 				_UpperCamelCase     (			self			,     a   )			->       List[str]:
								raise NotImplementedError






	@add_start_docstrings_to_model_forward(a   )
	@add_code_sample_docstrings(
	    checkpoint=_CHECKPOINT_FOR_DOC			,     output_type=a			,     config_class=_CONFIG_FOR_DOC			,     modality='vision'			,     expected_output=_EXPECTED_OUTPUT_SHAPE			,     )
	def 				_UpperCamelCase     (			self			,     a = None			,     a = None			,     a = None			,     )			->       Union[tuple, BaseModelOutputWithPoolingAndNoAttention]:
								snake_case_           =				(
								    output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states
								)
								snake_case_           =				return_dict if return_dict is not None else self.config.use_return_dict

								if pixel_values is None:
															raise ValueError('You have to specify pixel_values'   )

								snake_case_           =				self.conv_stem(a   )

								snake_case_           =				() if output_hidden_states else None

								for i, layer_module in enumerate(self.layer   ):
															snake_case_           =				layer_module(a   )

															if output_hidden_states:
																						snake_case_           =				all_hidden_states + (hidden_states,)

								snake_case_           =				hidden_states

								if self.pooler is not None:
															snake_case_           =				torch.flatten(self.pooler(a   )			,     start_dim=1   )
								else:
															snake_case_           =				None

								if not return_dict:
															return tuple(v for v in [last_hidden_state, pooled_output, all_hidden_states] if v is not None   )

								return BaseModelOutputWithPoolingAndNoAttention(
								    last_hidden_state=a			,     pooler_output=a			,     hidden_states=a			,     )






@add_start_docstrings(
    '''
    MobileNetV1 model with an image classification head on top (a linear layer on top of the pooled features), e.g. for
    ImageNet.
    '''			,   snake_case_			,   )
class 					UpperCamelCase_ (     snake_case_							):



	'''simple docstring'''




	def __init__(			self			,     a   )			->       None:
								super().__init__(a   )

								snake_case_           =				config.num_labels
								snake_case_           =				MobileNetVaModel(a   )

								snake_case_           =				self.mobilenet_va.layer[-1].convolution.out_channels

								# Classifier head
								snake_case_           =				nn.Dropout(config.classifier_dropout_prob			,     inplace=a   )
								snake_case_           =				nn.Linear(a			,     config.num_labels   ) if config.num_labels > 0 else nn.Identity()

								# Initialize weights and apply final processing
								self.post_init()






	@add_start_docstrings_to_model_forward(a   )
	@add_code_sample_docstrings(
	    checkpoint=_IMAGE_CLASS_CHECKPOINT			,     output_type=a			,     config_class=_CONFIG_FOR_DOC			,     expected_output=_IMAGE_CLASS_EXPECTED_OUTPUT			,     )
	def 				_UpperCamelCase     (			self			,     a = None			,     a = None			,     a = None			,     a = None			,     )			->       Union[tuple, ImageClassifierOutputWithNoAttention]:
								snake_case_           =				return_dict if return_dict is not None else self.config.use_return_dict

								snake_case_           =				self.mobilenet_va(a			,     output_hidden_states=a			,     return_dict=a   )

								snake_case_           =				outputs.pooler_output if return_dict else outputs[1]

								snake_case_           =				self.classifier(self.dropout(a   )   )

								snake_case_           =				None
								if labels is not None:
															if self.config.problem_type is None:
																						if self.num_labels == 1:
																													snake_case_           =				'regression'
																						elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int):
																													snake_case_           =				'single_label_classification'
																						else:
																													snake_case_           =				'multi_label_classification'

															if self.config.problem_type == "regression":
																						snake_case_           =				MSELoss()
																						if self.num_labels == 1:
																													snake_case_           =				loss_fct(logits.squeeze()			,     labels.squeeze()   )
																						else:
																													snake_case_           =				loss_fct(a			,     a   )
															elif self.config.problem_type == "single_label_classification":
																						snake_case_           =				CrossEntropyLoss()
																						snake_case_           =				loss_fct(logits.view(-1			,     self.num_labels   )			,     labels.view(-1   )   )
															elif self.config.problem_type == "multi_label_classification":
																						snake_case_           =				BCEWithLogitsLoss()
																						snake_case_           =				loss_fct(a			,     a   )

								if not return_dict:
															snake_case_           =				(logits,) + outputs[2:]
															return ((loss,) + output) if loss is not None else output

								return ImageClassifierOutputWithNoAttention(
								    loss=a			,     logits=a			,     hidden_states=outputs.hidden_states			,     )













from __future__ import annotations

from collections.abc import Callable
from typing import Generic, TypeVar

lowercase    				=   TypeVar("T")
lowercase    				=   TypeVar("U")




class 					UpperCamelCase_ (     Generic[T, U]							):



	'''simple docstring'''




	def __init__(			self			,     a			,     a   )			->       List[Any]:
								snake_case_           =				key
								snake_case_           =				val
								snake_case_           =				None
								snake_case_           =				None






	def __repr__(			self   )			->       str:
								return (
								    F'''Node: key: {self.key}, val: {self.val}, '''
								    F'''has next: {bool(self.next   )}, has prev: {bool(self.prev   )}'''
								)






class 					UpperCamelCase_ (     Generic[T, U]							):



	'''simple docstring'''




	def __init__(			self   )			->       None:
								snake_case_           =				DoubleLinkedListNode(a			,     a   )
								snake_case_           =				DoubleLinkedListNode(a			,     a   )
								snake_case_     ,						snake_case_           =				self.rear, self.head




	def __repr__(			self   )			->       str:
								snake_case_           =				['DoubleLinkedList']
								snake_case_           =				self.head
								while node.next is not None:
															rep.append(str(a   )   )
															snake_case_           =				node.next
								rep.append(str(self.rear   )   )
								return ",\n    ".join(a   )




	def 				_UpperCamelCase     (			self			,     a   )			->       None:
								snake_case_           =				self.rear.prev

								# All nodes other than self.head are guaranteed to have non-None previous
								assert previous is not None

								snake_case_           =				node
								snake_case_           =				previous
								snake_case_           =				node
								snake_case_           =				self.rear






	def 				_UpperCamelCase     (			self			,     a   )			->       DoubleLinkedListNode[T, U] | None:

								if node.prev is None or node.next is None:
															return None

								snake_case_           =				node.next
								snake_case_           =				node.prev
								snake_case_           =				None
								snake_case_           =				None
								return node






class 					UpperCamelCase_ (     Generic[T, U]							):



	'''simple docstring'''




	lowerCAmelCase						=					{}




	def __init__(			self			,     a   )			->       str:
								snake_case_           =				DoubleLinkedList()
								snake_case_           =				capacity
								snake_case_           =				0
								snake_case_           =				0
								snake_case_           =				0
								snake_case_           =				{}




	def __repr__(			self   )			->       str:
								return (
								    F'''CacheInfo(hits={self.hits}, misses={self.miss}, '''
								    F'''capacity={self.capacity}, current size={self.num_keys})'''
								)




	def __contains__(			self			,     a   )			->       bool:
								return key in self.cache




	def 				_UpperCamelCase     (			self			,     a   )			->       U | None:
								# Note: pythonic interface would throw KeyError rather than return None

								if key in self.cache:
															self.hits += 1
															snake_case_           =				self.cache[key]
															snake_case_           =				self.list.remove(self.cache[key]   )
															assert node == value_node

															# node is guaranteed not None because it is in self.cache
															assert node is not None
															self.list.add(a   )
															return node.val
								self.miss += 1
								return None




	def 				_UpperCamelCase     (			self			,     a			,     a   )			->       None:

								if key not in self.cache:
															if self.num_keys >= self.capacity:
																						# delete first node (oldest) when over capacity
																						snake_case_           =				self.list.head.next

																						# guaranteed to have a non-None first node when num_keys > 0
																						# explain to type checker via assertions
																						assert first_node is not None
																						assert first_node.key is not None
																						assert (
																						    self.list.remove(a   ) is not None
																						)  # node guaranteed to be in list assert node.key is not None

																						del self.cache[first_node.key]
																						self.num_keys -= 1
															snake_case_           =				DoubleLinkedListNode(a			,     a   )
															self.list.add(self.cache[key]   )
															self.num_keys += 1

								else:
															# bump node to the end of the list, update value
															snake_case_           =				self.list.remove(self.cache[key]   )
															assert node is not None  # node guaranteed to be in list
															snake_case_           =				value
															self.list.add(a   )






	@classmethod
	def 				_UpperCamelCase     (			cls			,     a = 1_28   )			->       Callable[[Callable[[T], U]], Callable[..., U]]:

								def cache_decorator_inner(a   ) -> Callable[..., U]:
															def cache_decorator_wrapper(*a   ) -> U:
																						if func not in cls.decorator_function_to_instance_map:
																													snake_case_           =				LRUCache(a   )

																						snake_case_           =				cls.decorator_function_to_instance_map[func].get(args[0]   )
																						if result is None:
																													snake_case_           =				func(*a   )
																													cls.decorator_function_to_instance_map[func].put(args[0]			,     a   )
																						return result

															def cache_info() -> LRUCache[T, U]:
																						return cls.decorator_function_to_instance_map[func]

															setattr(a			,     'cache_info'			,     a   )  # noqa: B010

															return cache_decorator_wrapper

								return cache_decorator_inner


if __name__ == "__main__":
	import doctest

	doctest.testmod()





