
from typing import Optional

import torch
import torch.utils.checkpoint
from torch import Tensor, nn
from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss

from ...activations import ACTaFN
from ...modeling_outputs import (
    BackboneOutput,
    BaseModelOutputWithNoAttention,
    BaseModelOutputWithPoolingAndNoAttention,
    ImageClassifierOutputWithNoAttention,
)
from ...modeling_utils import PreTrainedModel
from ...utils import (
    add_code_sample_docstrings,
    add_start_docstrings,
    add_start_docstrings_to_model_forward,
    logging,
    replace_return_docstrings,
)
from ...utils.backbone_utils import BackboneMixin
from .configuration_resnet import ResNetConfig


_lowerCamelCase	:    Optional[Any]          =      logging.get_logger(__name__)

# General docstring
_lowerCamelCase	:    Optional[Any]          =      '''ResNetConfig'''

# Base docstring
_lowerCamelCase	:    int          =      '''microsoft/resnet-50'''
_lowerCamelCase	:    List[str]          =      [1, 2_048, 7, 7]

# Image classification docstring
_lowerCamelCase	:    int          =      '''microsoft/resnet-50'''
_lowerCamelCase	:    int          =      '''tiger cat'''

_lowerCamelCase	:    Dict          =      [
    '''microsoft/resnet-50''',
    # See all resnet models at https://huggingface.co/models?filter=resnet
]




class        SCREAMING_SNAKE_CASE__					(     nn.Module ):





	'''simple docstring'''



	def __init__(  self     :   Any      ,  lowercase     :   int      ,  lowercase     :   int      ,  lowercase     :   int = 3      ,  lowercase     :   int = 1      ,  lowercase     :   str = "relu"     ):


				'''simple docstring'''


				super().__init__()
				_snake_case          =      nn.Convad(
				    lowercase      ,  lowercase      ,  kernel_size=lowercase      ,  stride=lowercase      ,  padding=kernel_size // 2      ,  bias=lowercase     )
				_snake_case          =      nn.BatchNormad(lowercase     )
				_snake_case          =      ACTaFN[activation] if activation is not None else nn.Identity()





	def 			A							(  self     :   Union[str, Any]      ,  lowercase     :   Tensor     ):


				'''simple docstring'''


				_snake_case          =      self.convolution(lowercase     )
				_snake_case          =      self.normalization(lowercase     )
				_snake_case          =      self.activation(lowercase     )
				return hidden_state




class        SCREAMING_SNAKE_CASE__					(     nn.Module ):





	'''simple docstring'''



	def __init__(  self     :   Dict      ,  lowercase     :   ResNetConfig     ):


				'''simple docstring'''


				super().__init__()
				_snake_case          =      ResNetConvLayer(
				    config.num_channels      ,  config.embedding_size      ,  kernel_size=7      ,  stride=2      ,  activation=config.hidden_act     )
				_snake_case          =      nn.MaxPoolad(kernel_size=3      ,  stride=2      ,  padding=1     )
				_snake_case          =      config.num_channels





	def 			A							(  self     :   List[str]      ,  lowercase     :   Tensor     ):


				'''simple docstring'''


				_snake_case          =      pixel_values.shape[1]
				if num_channels != self.num_channels:
							raise ValueError(
							    'Make sure that the channel dimension of the pixel values match with the one set in the configuration.'     )
				_snake_case          =      self.embedder(lowercase     )
				_snake_case          =      self.pooler(lowercase     )
				return embedding




class        SCREAMING_SNAKE_CASE__					(     nn.Module ):





	'''simple docstring'''



	def __init__(  self     :   Dict      ,  lowercase     :   int      ,  lowercase     :   int      ,  lowercase     :   int = 2     ):


				'''simple docstring'''


				super().__init__()
				_snake_case          =      nn.Convad(lowercase      ,  lowercase      ,  kernel_size=1      ,  stride=lowercase      ,  bias=lowercase     )
				_snake_case          =      nn.BatchNormad(lowercase     )





	def 			A							(  self     :   int      ,  lowercase     :   Tensor     ):


				'''simple docstring'''


				_snake_case          =      self.convolution(lowercase     )
				_snake_case          =      self.normalization(lowercase     )
				return hidden_state




class        SCREAMING_SNAKE_CASE__					(     nn.Module ):





	'''simple docstring'''



	def __init__(  self     :   Optional[Any]      ,  lowercase     :   int      ,  lowercase     :   int      ,  lowercase     :   int = 1      ,  lowercase     :   str = "relu"     ):


				'''simple docstring'''


				super().__init__()
				_snake_case          =      in_channels != out_channels or stride != 1
				_snake_case          =      (
				    ResNetShortCut(lowercase      ,  lowercase      ,  stride=lowercase     ) if should_apply_shortcut else nn.Identity()
				)
				_snake_case          =      nn.Sequential(
				    ResNetConvLayer(lowercase      ,  lowercase      ,  stride=lowercase     )      ,  ResNetConvLayer(lowercase      ,  lowercase      ,  activation=lowercase     )      ,  )
				_snake_case          =      ACTaFN[activation]





	def 			A							(  self     :   Optional[Any]      ,  lowercase     :   Optional[int]     ):


				'''simple docstring'''


				_snake_case          =      hidden_state
				_snake_case          =      self.layer(lowercase     )
				_snake_case          =      self.shortcut(lowercase     )
				hidden_state += residual
				_snake_case          =      self.activation(lowercase     )
				return hidden_state




class        SCREAMING_SNAKE_CASE__					(     nn.Module ):





	'''simple docstring'''



	def __init__(  self     :   Tuple      ,  lowercase     :   int      ,  lowercase     :   int      ,  lowercase     :   int = 1      ,  lowercase     :   str = "relu"      ,  lowercase     :   int = 4     ):


				'''simple docstring'''


				super().__init__()
				_snake_case          =      in_channels != out_channels or stride != 1
				_snake_case          =      out_channels // reduction
				_snake_case          =      (
				    ResNetShortCut(lowercase      ,  lowercase      ,  stride=lowercase     ) if should_apply_shortcut else nn.Identity()
				)
				_snake_case          =      nn.Sequential(
				    ResNetConvLayer(lowercase      ,  lowercase      ,  kernel_size=1     )      ,  ResNetConvLayer(lowercase      ,  lowercase      ,  stride=lowercase     )      ,  ResNetConvLayer(lowercase      ,  lowercase      ,  kernel_size=1      ,  activation=lowercase     )      ,  )
				_snake_case          =      ACTaFN[activation]





	def 			A							(  self     :   Optional[int]      ,  lowercase     :   int     ):


				'''simple docstring'''


				_snake_case          =      hidden_state
				_snake_case          =      self.layer(lowercase     )
				_snake_case          =      self.shortcut(lowercase     )
				hidden_state += residual
				_snake_case          =      self.activation(lowercase     )
				return hidden_state




class        SCREAMING_SNAKE_CASE__					(     nn.Module ):





	'''simple docstring'''



	def __init__(  self     :   int      ,  lowercase     :   ResNetConfig      ,  lowercase     :   int      ,  lowercase     :   int      ,  lowercase     :   int = 2      ,  lowercase     :   int = 2      ,  ):


				'''simple docstring'''


				super().__init__()

				_snake_case          =      ResNetBottleNeckLayer if config.layer_type == 'bottleneck' else ResNetBasicLayer

				_snake_case          =      nn.Sequential(
				    # downsampling is done in the first layer with stride of 2
				    layer(lowercase      ,  lowercase      ,  stride=lowercase      ,  activation=config.hidden_act     )      ,  *[layer(lowercase      ,  lowercase      ,  activation=config.hidden_act     ) for _ in range(depth - 1     )]      ,  )





	def 			A							(  self     :   int      ,  lowercase     :   Tensor     ):


				'''simple docstring'''


				_snake_case          =      input
				for layer in self.layers:
							_snake_case          =      layer(lowercase     )
				return hidden_state




class        SCREAMING_SNAKE_CASE__					(     nn.Module ):





	'''simple docstring'''



	def __init__(  self     :   Tuple      ,  lowercase     :   ResNetConfig     ):


				'''simple docstring'''


				super().__init__()
				_snake_case          =      nn.ModuleList([]     )
				# based on `downsample_in_first_stage` the first layer of the first stage may or may not downsample the input
				self.stages.append(
				    ResNetStage(
				        lowercase      ,  config.embedding_size      ,  config.hidden_sizes[0]      ,  stride=2 if config.downsample_in_first_stage else 1      ,  depth=config.depths[0]      ,  )     )
				_snake_case          =      zip(config.hidden_sizes      ,  config.hidden_sizes[1:]     )
				for (in_channels, out_channels), depth in zip(lowercase      ,  config.depths[1:]     ):
							self.stages.append(ResNetStage(lowercase      ,  lowercase      ,  lowercase      ,  depth=lowercase     )     )





	def 			A							(  self     :   Optional[Any]      ,  lowercase     :   Tensor      ,  lowercase     :   bool = False      ,  lowercase     :   bool = True     ):


				'''simple docstring'''


				_snake_case          =      () if output_hidden_states else None

				for stage_module in self.stages:
							if output_hidden_states:
										_snake_case          =      hidden_states + (hidden_state,)

							_snake_case          =      stage_module(lowercase     )

				if output_hidden_states:
							_snake_case          =      hidden_states + (hidden_state,)

				if not return_dict:
							return tuple(v for v in [hidden_state, hidden_states] if v is not None     )

				return BaseModelOutputWithNoAttention(
				    last_hidden_state=lowercase      ,  hidden_states=lowercase      ,  )




class        SCREAMING_SNAKE_CASE__					(     UpperCAmelCase ):





	'''simple docstring'''



	_UpperCAmelCase	:		Optional[int]          = ResNetConfig
	_UpperCAmelCase	:		Union[str, Any]          = "resnet"
	_UpperCAmelCase	:		Optional[int]          = "pixel_values"
	_UpperCAmelCase	:		Any          = True



	def 			A							(  self     :   List[Any]      ,  lowercase     :   Dict     ):


				'''simple docstring'''


				if isinstance(lowercase      ,  nn.Convad     ):
							nn.init.kaiming_normal_(module.weight      ,  mode='fan_out'      ,  nonlinearity='relu'     )
				elif isinstance(lowercase      ,  (nn.BatchNormad, nn.GroupNorm)     ):
							nn.init.constant_(module.weight      ,  1     )
							nn.init.constant_(module.bias      ,  0     )





	def 			A							(  self     :   Dict      ,  lowercase     :   List[Any]      ,  lowercase     :   Dict=False     ):


				'''simple docstring'''


				if isinstance(lowercase      ,  lowercase     ):
							_snake_case          =      value




_lowerCamelCase	:    Tuple          =      r'''
    This model is a PyTorch [torch.nn.Module](https://pytorch.org/docs/stable/nn.html#torch.nn.Module) subclass. Use it
    as a regular PyTorch Module and refer to the PyTorch documentation for all matter related to general usage and
    behavior.

    Parameters:
        config ([`ResNetConfig`]): Model configuration class with all the parameters of the model.
            Initializing with a config file does not load the weights associated with the model, only the
            configuration. Check out the [`~PreTrainedModel.from_pretrained`] method to load the model weights.
'''

_lowerCamelCase	:    Union[str, Any]          =      r'''
    Args:
        pixel_values (`torch.FloatTensor` of shape `(batch_size, num_channels, height, width)`):
            Pixel values. Pixel values can be obtained using [`AutoImageProcessor`]. See
            [`ConvNextImageProcessor.__call__`] for details.

        output_hidden_states (`bool`, *optional*):
            Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for
            more detail.
        return_dict (`bool`, *optional*):
            Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple.
'''




@add_start_docstrings(
    "The bare ResNet model outputting raw features without any specific head on top."							,UpperCAmelCase							,)
class        SCREAMING_SNAKE_CASE__					(     UpperCAmelCase ):





	'''simple docstring'''



	def __init__(  self     :   str      ,  lowercase     :   Optional[int]     ):


				'''simple docstring'''


				super().__init__(lowercase     )
				_snake_case          =      config
				_snake_case          =      ResNetEmbeddings(lowercase     )
				_snake_case          =      ResNetEncoder(lowercase     )
				_snake_case          =      nn.AdaptiveAvgPoolad((1, 1)     )
				# Initialize weights and apply final processing
				self.post_init()





	@add_start_docstrings_to_model_forward(lowercase     )
	@add_code_sample_docstrings(
	    checkpoint=_CHECKPOINT_FOR_DOC      ,  output_type=lowercase      ,  config_class=_CONFIG_FOR_DOC      ,  modality='vision'      ,  expected_output=_EXPECTED_OUTPUT_SHAPE      ,  )
	def 			A							(  self     :   Union[str, Any]      ,  lowercase     :   Tensor      ,  lowercase     :   Optional[bool] = None      ,  lowercase     :   Optional[bool] = None     ):


				'''simple docstring'''


				_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

				_snake_case          =      self.embedder(lowercase     )

				_snake_case          =      self.encoder(
				    lowercase      ,  output_hidden_states=lowercase      ,  return_dict=lowercase     )

				_snake_case          =      encoder_outputs[0]

				_snake_case          =      self.pooler(lowercase     )

				if not return_dict:
							return (last_hidden_state, pooled_output) + encoder_outputs[1:]

				return BaseModelOutputWithPoolingAndNoAttention(
				    last_hidden_state=lowercase      ,  pooler_output=lowercase      ,  hidden_states=encoder_outputs.hidden_states      ,  )




@add_start_docstrings(
    "\n    ResNet Model with an image classification head on top (a linear layer on top of the pooled features), e.g. for\n    ImageNet.\n    "							,UpperCAmelCase							,)
class        SCREAMING_SNAKE_CASE__					(     UpperCAmelCase ):





	'''simple docstring'''



	def __init__(  self     :   Optional[int]      ,  lowercase     :   Optional[Any]     ):


				'''simple docstring'''


				super().__init__(lowercase     )
				_snake_case          =      config.num_labels
				_snake_case          =      ResNetModel(lowercase     )
				# classification head
				_snake_case          =      nn.Sequential(
				    nn.Flatten()      ,  nn.Linear(config.hidden_sizes[-1]      ,  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(lowercase     )
	@add_code_sample_docstrings(
	    checkpoint=_IMAGE_CLASS_CHECKPOINT      ,  output_type=lowercase      ,  config_class=_CONFIG_FOR_DOC      ,  expected_output=_IMAGE_CLASS_EXPECTED_OUTPUT      ,  )
	def 			A							(  self     :   int      ,  lowercase     :   Optional[torch.FloatTensor] = None      ,  lowercase     :   Optional[torch.LongTensor] = None      ,  lowercase     :   Optional[bool] = None      ,  lowercase     :   Optional[bool] = None      ,  ):


				'''simple docstring'''


				_snake_case          =      return_dict if return_dict is not None else self.config.use_return_dict

				_snake_case          =      self.resnet(lowercase      ,  output_hidden_states=lowercase      ,  return_dict=lowercase     )

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

				_snake_case          =      self.classifier(lowercase     )

				_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(lowercase      ,  lowercase     )
							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(lowercase      ,  lowercase     )

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

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




@add_start_docstrings(
    "\n    ResNet backbone, to be used with frameworks like DETR and MaskFormer.\n    "							,UpperCAmelCase							,)
class        SCREAMING_SNAKE_CASE__					(     UpperCAmelCase							,UpperCAmelCase ):





	'''simple docstring'''



	def __init__(  self     :   Any      ,  lowercase     :   Union[str, Any]     ):


				'''simple docstring'''


				super().__init__(lowercase     )
				super()._init_backbone(lowercase     )

				_snake_case          =      [config.embedding_size] + config.hidden_sizes
				_snake_case          =      ResNetEmbeddings(lowercase     )
				_snake_case          =      ResNetEncoder(lowercase     )

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





	@add_start_docstrings_to_model_forward(lowercase     )
	@replace_return_docstrings(output_type=lowercase      ,  config_class=_CONFIG_FOR_DOC     )
	def 			A							(  self     :   str      ,  lowercase     :   Tensor      ,  lowercase     :   Optional[bool] = None      ,  lowercase     :   Optional[bool] = None     ):


				'''simple docstring'''


				_snake_case          =      return_dict if return_dict is not None else self.config.use_return_dict
				_snake_case          =      (
				    output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states
				)

				_snake_case          =      self.embedder(lowercase     )

				_snake_case          =      self.encoder(lowercase      ,  output_hidden_states=lowercase      ,  return_dict=lowercase     )

				_snake_case          =      outputs.hidden_states

				_snake_case          =      ()
				for idx, stage in enumerate(self.stage_names     ):
							if stage in self.out_features:
										feature_maps += (hidden_states[idx],)

				if not return_dict:
							_snake_case          =      (feature_maps,)
							if output_hidden_states:
										output += (outputs.hidden_states,)
							return output

				return BackboneOutput(
				    feature_maps=lowercase      ,  hidden_states=outputs.hidden_states if output_hidden_states else None      ,  attentions=lowercase      ,  )

from functools import lru_cache






@lru_cache
def 	a_		(	__lowercase       :     int			)			->  int:
			if num < 0:
						raise ValueError('Number should not be negative.'			)

			return 1 if num in (0, 1) else num * factorial(num - 1			)


if __name__ == "__main__":
			import doctest

			doctest.testmod()