





import collections.abc
from typing import Optional, Tuple, Union

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

from ...activations import ACTaFN
from ...modeling_outputs import BaseModelOutputWithNoAttention, 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_poolformer import PoolFormerConfig


UpperCAmelCase_      							=     logging.get_logger(__name__)

# General docstring
UpperCAmelCase_      							=     'PoolFormerConfig'

# Base docstring
UpperCAmelCase_      							=     'sail/poolformer_s12'
UpperCAmelCase_      							=     [1, 512, 7, 7]

# Image classification docstring
UpperCAmelCase_      							=     'sail/poolformer_s12'
UpperCAmelCase_      							=     'tabby, tabby cat'

UpperCAmelCase_      							=     [
    'sail/poolformer_s12',
    # See all PoolFormer models at https://huggingface.co/models?filter=poolformer
]





def 						lowerCamelCase__     (     UpperCamelCase__			:       Any       ,    UpperCamelCase__			:       float = 0.0       ,    UpperCamelCase__			:       bool = False						)			-> str:



					'''simple docstring'''




					if drop_prob == 0.0 or not training:
										return input
					_snake_case									=				1 - drop_prob
					_snake_case									=				(input.shape[0],) + (1,) * (input.ndim - 1)  # work with diff dim tensors, not just 2D ConvNets
					_snake_case									=				keep_prob + torch.rand(_lowerCamelCase       ,    dtype=input.dtype       ,    device=input.device						)
					random_tensor.floor_()  # binarize
					_snake_case									=				input.div(_lowerCamelCase						) * random_tensor
					return output
class 			UpperCamelCase_		(  nn.Module					):




					def __init__(		self				,						lowerCAmelCase_ = None  )		->							None:
										super().__init__()
										_snake_case									=				drop_prob




					def 	lowerCAmelCase			(		self				,						lowerCAmelCase_  )		->							torch.Tensor:
										return drop_path(lowerCAmelCase_				,						self.drop_prob				,						self.training  )






					def 	lowerCAmelCase			(		self  )		->							str:
										return "p={}".format(self.drop_prob  )





class 			UpperCamelCase_		(  nn.Module					):




					def __init__(		self				,						lowerCAmelCase_				,						lowerCAmelCase_				,						lowerCAmelCase_				,						lowerCAmelCase_				,						lowerCAmelCase_				,						lowerCAmelCase_=None  )		->							str:
										super().__init__()
										_snake_case									=				patch_size if isinstance(lowerCAmelCase_				,						collections.abc.Iterable  ) else (patch_size, patch_size)
										_snake_case									=				stride if isinstance(lowerCAmelCase_				,						collections.abc.Iterable  ) else (stride, stride)
										_snake_case									=				padding if isinstance(lowerCAmelCase_				,						collections.abc.Iterable  ) else (padding, padding)

										_snake_case									=				nn.Convad(lowerCAmelCase_				,						lowerCAmelCase_				,						kernel_size=lowerCAmelCase_				,						stride=lowerCAmelCase_				,						padding=lowerCAmelCase_  )
										_snake_case									=				norm_layer(lowerCAmelCase_  ) if norm_layer else nn.Identity()






					def 	lowerCAmelCase			(		self				,						lowerCAmelCase_  )		->							Optional[int]:
										_snake_case									=				self.projection(lowerCAmelCase_  )
										_snake_case									=				self.norm(lowerCAmelCase_  )
										return embeddings





class 			UpperCamelCase_		(  nn.GroupNorm					):




					def __init__(		self				,						lowerCAmelCase_				,						**lowerCAmelCase_  )		->							List[str]:
										super().__init__(1				,						lowerCAmelCase_				,						**lowerCAmelCase_  )





class 			UpperCamelCase_		(  nn.Module					):




					def __init__(		self				,						lowerCAmelCase_  )		->							Any:
										super().__init__()
										_snake_case									=				nn.AvgPoolad(lowerCAmelCase_				,						stride=1				,						padding=pool_size // 2				,						count_include_pad=lowerCAmelCase_  )






					def 	lowerCAmelCase			(		self				,						lowerCAmelCase_  )		->							List[str]:
										return self.pool(lowerCAmelCase_  ) - hidden_states





class 			UpperCamelCase_		(  nn.Module					):




					def __init__(		self				,						lowerCAmelCase_				,						lowerCAmelCase_				,						lowerCAmelCase_				,						lowerCAmelCase_  )		->							Any:
										super().__init__()
										_snake_case									=				nn.Convad(lowerCAmelCase_				,						lowerCAmelCase_				,						1  )
										_snake_case									=				nn.Convad(lowerCAmelCase_				,						lowerCAmelCase_				,						1  )
										_snake_case									=				PoolFormerDropPath(lowerCAmelCase_  )
										if isinstance(config.hidden_act				,						lowerCAmelCase_  ):
															_snake_case									=				ACTaFN[config.hidden_act]
										else:
															_snake_case									=				config.hidden_act






					def 	lowerCAmelCase			(		self				,						lowerCAmelCase_  )		->							List[Any]:
										_snake_case									=				self.conva(lowerCAmelCase_  )
										_snake_case									=				self.act_fn(lowerCAmelCase_  )
										_snake_case									=				self.drop(lowerCAmelCase_  )
										_snake_case									=				self.conva(lowerCAmelCase_  )
										_snake_case									=				self.drop(lowerCAmelCase_  )

										return hidden_states





class 			UpperCamelCase_		(  nn.Module					):




					def __init__(		self				,						lowerCAmelCase_				,						lowerCAmelCase_				,						lowerCAmelCase_				,						lowerCAmelCase_				,						lowerCAmelCase_				,						lowerCAmelCase_  )		->							List[str]:
										super().__init__()
										_snake_case									=				PoolFormerPooling(lowerCAmelCase_  )
										_snake_case									=				PoolFormerOutput(lowerCAmelCase_				,						lowerCAmelCase_				,						lowerCAmelCase_				,						lowerCAmelCase_  )
										_snake_case									=				PoolFormerGroupNorm(lowerCAmelCase_  )
										_snake_case									=				PoolFormerGroupNorm(lowerCAmelCase_  )

										# Useful for training neural nets
										_snake_case									=				PoolFormerDropPath(lowerCAmelCase_  ) if drop_path > 0.0 else nn.Identity()
										_snake_case									=				config.use_layer_scale
										if config.use_layer_scale:
															_snake_case									=				nn.Parameter(
															    config.layer_scale_init_value * torch.ones((lowerCAmelCase_)  )				,						requires_grad=lowerCAmelCase_  )
															_snake_case									=				nn.Parameter(
															    config.layer_scale_init_value * torch.ones((lowerCAmelCase_)  )				,						requires_grad=lowerCAmelCase_  )






					def 	lowerCAmelCase			(		self				,						lowerCAmelCase_  )		->							List[str]:
										if self.use_layer_scale:
															_snake_case									=				self.pooling(self.before_norm(lowerCAmelCase_  )  )
															_snake_case									=				self.layer_scale_a.unsqueeze(-1  ).unsqueeze(-1  ) * pooling_output
															# First residual connection
															_snake_case									=				hidden_states + self.drop_path(lowerCAmelCase_  )
															_snake_case									=				()

															_snake_case									=				self.output(self.after_norm(lowerCAmelCase_  )  )
															_snake_case									=				self.layer_scale_a.unsqueeze(-1  ).unsqueeze(-1  ) * layer_output
															# Second residual connection
															_snake_case									=				hidden_states + self.drop_path(lowerCAmelCase_  )

															_snake_case									=				(output,) + outputs
															return outputs

										else:
															_snake_case									=				self.drop_path(self.pooling(self.before_norm(lowerCAmelCase_  )  )  )
															# First residual connection
															_snake_case									=				pooling_output + hidden_states
															_snake_case									=				()

															# Second residual connection inside the PoolFormerOutput block
															_snake_case									=				self.drop_path(self.output(self.after_norm(lowerCAmelCase_  )  )  )
															_snake_case									=				hidden_states + layer_output

															_snake_case									=				(output,) + outputs
															return outputs





class 			UpperCamelCase_		(  nn.Module					):




					def __init__(		self				,						lowerCAmelCase_  )		->							Optional[int]:
										super().__init__()
										_snake_case									=				config
										# stochastic depth decay rule
										_snake_case									=				[x.item() for x in torch.linspace(0				,						config.drop_path_rate				,						sum(config.depths  )  )]

										# patch embeddings
										_snake_case									=				[]
										for i in range(config.num_encoder_blocks  ):
															embeddings.append(
															    PoolFormerEmbeddings(
															        patch_size=config.patch_sizes[i]				,						stride=config.strides[i]				,						padding=config.padding[i]				,						num_channels=config.num_channels if i == 0 else config.hidden_sizes[i - 1]				,						hidden_size=config.hidden_sizes[i]				,						)  )
										_snake_case									=				nn.ModuleList(lowerCAmelCase_  )

										# Transformer blocks
										_snake_case									=				[]
										_snake_case									=				0
										for i in range(config.num_encoder_blocks  ):
															# each block consists of layers
															_snake_case									=				[]
															if i != 0:
																				cur += config.depths[i - 1]
															for j in range(config.depths[i]  ):
																				layers.append(
																				    PoolFormerLayer(
																				        lowerCAmelCase_				,						num_channels=config.hidden_sizes[i]				,						pool_size=config.pool_size				,						hidden_size=config.hidden_sizes[i]				,						intermediate_size=int(config.hidden_sizes[i] * config.mlp_ratio  )				,						drop_path=dpr[cur + j]				,						)  )
															blocks.append(nn.ModuleList(lowerCAmelCase_  )  )

										_snake_case									=				nn.ModuleList(lowerCAmelCase_  )






					def 	lowerCAmelCase			(		self				,						lowerCAmelCase_				,						lowerCAmelCase_=False				,						lowerCAmelCase_=True  )		->							int:
										_snake_case									=				() if output_hidden_states else None

										_snake_case									=				pixel_values
										for idx, layers in enumerate(zip(self.patch_embeddings				,						self.block  )  ):
															_snake_case									=				layers
															# Get patch embeddings from hidden_states
															_snake_case									=				embedding_layer(lowerCAmelCase_  )
															# Send the embeddings through the blocks
															for _, blk in enumerate(lowerCAmelCase_  ):
																				_snake_case									=				blk(lowerCAmelCase_  )
																				_snake_case									=				layer_outputs[0]

															if output_hidden_states:
																				_snake_case									=				all_hidden_states + (hidden_states,)

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

										return BaseModelOutputWithNoAttention(last_hidden_state=lowerCAmelCase_				,						hidden_states=lowerCAmelCase_  )





class 			UpperCamelCase_		(  __lowercase					):
					lowerCAmelCase_							=	PoolFormerConfig
					lowerCAmelCase_							=	'''poolformer'''
					lowerCAmelCase_							=	'''pixel_values'''
					lowerCAmelCase_							=	True




					def 	lowerCAmelCase			(		self				,						lowerCAmelCase_  )		->							Optional[int]:
										if isinstance(lowerCAmelCase_				,						(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(lowerCAmelCase_				,						nn.LayerNorm  ):
															module.bias.data.zero_()
															module.weight.data.fill_(1.0  )






					def 	lowerCAmelCase			(		self				,						lowerCAmelCase_				,						lowerCAmelCase_=False  )		->							List[Any]:
										if isinstance(lowerCAmelCase_				,						lowerCAmelCase_  ):
															_snake_case									=				value





UpperCAmelCase_      							=     R'\n    This model is a PyTorch [torch.nn.Module](https://pytorch.org/docs/stable/nn.html#torch.nn.Module) sub-class. Use\n    it 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 ([`PoolFormerConfig`]): 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'

UpperCAmelCase_      							=     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            [`PoolFormerImageProcessor.__call__`] for details.\n'
@add_start_docstrings(
    '''The bare PoolFormer Model transformer outputting raw hidden-states without any specific head on top.'''							,  __lowercase							,  )
class 			UpperCamelCase_		(  __lowercase					):




					def __init__(		self				,						lowerCAmelCase_  )		->							Union[str, Any]:
										super().__init__(lowerCAmelCase_  )
										_snake_case									=				config

										_snake_case									=				PoolFormerEncoder(lowerCAmelCase_  )

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




					def 	lowerCAmelCase			(		self  )		->							Union[str, Any]:
										return self.embeddings.patch_embeddings






					@add_start_docstrings_to_model_forward(lowerCAmelCase_  )
					@add_code_sample_docstrings(
					    checkpoint=_CHECKPOINT_FOR_DOC				,						output_type=lowerCAmelCase_				,						config_class=_CONFIG_FOR_DOC				,						modality='vision'				,						expected_output=_EXPECTED_OUTPUT_SHAPE				,						)
					def 	lowerCAmelCase			(		self				,						lowerCAmelCase_ = None				,						lowerCAmelCase_ = None				,						lowerCAmelCase_ = None				,						)		->							Union[Tuple, BaseModelOutputWithNoAttention]:
										_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.encoder(
										    lowerCAmelCase_				,						output_hidden_states=lowerCAmelCase_				,						return_dict=lowerCAmelCase_				,						)
										_snake_case									=				encoder_outputs[0]

										if not return_dict:
															return (sequence_output, None) + encoder_outputs[1:]

										return BaseModelOutputWithNoAttention(
										    last_hidden_state=lowerCAmelCase_				,						hidden_states=encoder_outputs.hidden_states				,						)





class 			UpperCamelCase_		(  nn.Module					):




					def __init__(		self				,						lowerCAmelCase_  )		->							Optional[int]:
										super().__init__()
										_snake_case									=				nn.Linear(config.hidden_size				,						config.hidden_size  )






					def 	lowerCAmelCase			(		self				,						lowerCAmelCase_  )		->							Optional[int]:
										_snake_case									=				self.dense(lowerCAmelCase_  )
										return output





@add_start_docstrings(
    '''\n    PoolFormer Model transformer with an image classification head on top\n    '''							,  __lowercase							,  )
class 			UpperCamelCase_		(  __lowercase					):




					def __init__(		self				,						lowerCAmelCase_  )		->							Any:
										super().__init__(lowerCAmelCase_  )
										_snake_case									=				config.num_labels
										_snake_case									=				PoolFormerModel(lowerCAmelCase_  )

										# Final norm
										_snake_case									=				PoolFormerGroupNorm(config.hidden_sizes[-1]  )
										# Classifier head
										_snake_case									=				(
										    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(lowerCAmelCase_  )
					@add_code_sample_docstrings(
					    checkpoint=_IMAGE_CLASS_CHECKPOINT				,						output_type=lowerCAmelCase_				,						config_class=_CONFIG_FOR_DOC				,						expected_output=_IMAGE_CLASS_EXPECTED_OUTPUT				,						)
					def 	lowerCAmelCase			(		self				,						lowerCAmelCase_ = None				,						lowerCAmelCase_ = None				,						lowerCAmelCase_ = None				,						lowerCAmelCase_ = None				,						)		->							Union[Tuple, ImageClassifierOutputWithNoAttention]:
										_snake_case									=				return_dict if return_dict is not None else self.config.use_return_dict

										_snake_case									=				self.poolformer(
										    lowerCAmelCase_				,						output_hidden_states=lowerCAmelCase_				,						return_dict=lowerCAmelCase_				,						)

										_snake_case									=				outputs[0]

										_snake_case									=				self.classifier(self.norm(lowerCAmelCase_  ).mean([-2, -1]  )  )

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

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

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










from cva import destroyAllWindows, imread, imshow, waitKey





def 						lowerCamelCase__     (     UpperCamelCase__			:       Optional[int]						)			-> Optional[int]:



					'''simple docstring'''




					_snake_case							,     _snake_case									=				img.shape[0], img.shape[1]

					# converting each pixel's color to its negative
					for i in range(UpperCamelCase__						):
										for j in range(UpperCamelCase__						):
															_snake_case									=				[255, 255, 255] - img[i][j]

					return img


if __name__ == "__main__":
					# read original image
					UpperCAmelCase_      							=     imread("""image_data/lena.jpg""", 1)

					# convert to its negative
					UpperCAmelCase_      							=     convert_to_negative(img)

					# show result image
					imshow("""negative of original image""", img)
					waitKey(0)
					destroyAllWindows()



