


from typing import List, Optional, Tuple, Union

import torch
from torch import nn
from torch.nn import CrossEntropyLoss

from ... import AutoBackbone
from ...modeling_outputs import SemanticSegmenterOutput
from ...modeling_utils import PreTrainedModel
from ...utils import add_start_docstrings, add_start_docstrings_to_model_forward, replace_return_docstrings
from ...utils.backbone_utils import BackboneMixin
from .configuration_upernet import UperNetConfig


SCREAMING_SNAKE_CASE :   Any							      =				[
    "openmmlab/upernet-convnext-tiny",
    # See all UperNet models at https://huggingface.co/models?filter=upernet
]

# General docstring
SCREAMING_SNAKE_CASE :   Optional[Any]							      =				"UperNetConfig"






class _lowerCamelCase(		nn.Module     ):
							def __init__(      self,   lowerCamelCase,   lowerCamelCase,   lowerCamelCase,   lowerCamelCase = 0,   lowerCamelCase = False,   lowerCamelCase = 1,   ) ->     Optional[Any]:




											"""simple docstring"""

											super().__init__()
											_lowercase :							Any   	=	nn.Convad(
											    in_channels=__UpperCamelCase,   out_channels=__UpperCamelCase,   kernel_size=__UpperCamelCase,   padding=__UpperCamelCase,   bias=__UpperCamelCase,   dilation=__UpperCamelCase,   )
											_lowercase :							List[Any]   	=	nn.BatchNormad(__UpperCamelCase)
											_lowercase :							List[str]   	=	nn.ReLU()




							def     UpperCamelCase  (      self,   lowerCamelCase) ->     Any:




											"""simple docstring"""

											_lowercase :							Optional[Any]   	=	self.conv(__UpperCamelCase)
											_lowercase :							Tuple   	=	self.batch_norm(__UpperCamelCase)
											_lowercase :							Tuple   	=	self.activation(__UpperCamelCase)

											return output






class _lowerCamelCase(		nn.Module     ):
							def __init__(      self,   lowerCamelCase,   lowerCamelCase,   lowerCamelCase) ->     int:




											"""simple docstring"""

											super().__init__()
											_lowercase :							Union[str, Any]   	=	[
											    nn.AdaptiveAvgPoolad(__UpperCamelCase),
											    UperNetConvModule(__UpperCamelCase,   __UpperCamelCase,   kernel_size=1),
											]
											for i, layer in enumerate(self.layers):
															self.add_module(str(__UpperCamelCase),   __UpperCamelCase)




							def     UpperCamelCase  (      self,   lowerCamelCase) ->     str:




											"""simple docstring"""

											_lowercase :							Tuple   	=	input
											for layer in self.layers:
															_lowercase :							int   	=	layer(__UpperCamelCase)
											return hidden_state






class _lowerCamelCase(		nn.Module     ):
							def __init__(      self,   lowerCamelCase,   lowerCamelCase,   lowerCamelCase,   lowerCamelCase) ->     Optional[int]:




											"""simple docstring"""

											super().__init__()
											_lowercase :							int   	=	pool_scales
											_lowercase :							List[str]   	=	align_corners
											_lowercase :							Union[str, Any]   	=	in_channels
											_lowercase :							Tuple   	=	channels
											_lowercase :							List[Any]   	=	[]
											for i, pool_scale in enumerate(__UpperCamelCase):
															_lowercase :							Optional[int]   	=	UperNetPyramidPoolingBlock(pool_scale=__UpperCamelCase,   in_channels=__UpperCamelCase,   channels=__UpperCamelCase)
															self.blocks.append(__UpperCamelCase)
															self.add_module(str(__UpperCamelCase),   __UpperCamelCase)




							def     UpperCamelCase  (      self,   lowerCamelCase) ->     List[str]:




											"""simple docstring"""

											_lowercase :							Union[str, Any]   	=	[]
											for ppm in self.blocks:
															_lowercase :							Optional[Any]   	=	ppm(__UpperCamelCase)
															_lowercase :							Optional[int]   	=	nn.functional.interpolate(
															    __UpperCamelCase,   size=x.size()[2:],   mode='bilinear',   align_corners=self.align_corners)
															ppm_outs.append(__UpperCamelCase)
											return ppm_outs






class _lowerCamelCase(		nn.Module     ):
							def __init__(      self,   lowerCamelCase,   lowerCamelCase) ->     List[str]:




											"""simple docstring"""

											super().__init__()

											_lowercase :							Tuple   	=	config
											_lowercase :							Tuple   	=	config.pool_scales  # e.g. (1, 2, 3, 6)
											_lowercase :							Optional[Any]   	=	in_channels
											_lowercase :							Union[str, Any]   	=	config.hidden_size
											_lowercase :							List[str]   	=	False
											_lowercase :							Dict   	=	nn.Convad(self.channels,   config.num_labels,   kernel_size=1)

											# PSP Module
											_lowercase :							Any   	=	UperNetPyramidPoolingModule(
											    self.pool_scales,   self.in_channels[-1],   self.channels,   align_corners=self.align_corners,   )
											_lowercase :							List[str]   	=	UperNetConvModule(
											    self.in_channels[-1] + len(self.pool_scales) * self.channels,   self.channels,   kernel_size=3,   padding=1,   )
											# FPN Module
											_lowercase :							Any   	=	nn.ModuleList()
											_lowercase :							int   	=	nn.ModuleList()
											for in_channels in self.in_channels[:-1]:  # skip the top layer
															_lowercase :							Any   	=	UperNetConvModule(__UpperCamelCase,   self.channels,   kernel_size=1)
															_lowercase :							Optional[Any]   	=	UperNetConvModule(self.channels,   self.channels,   kernel_size=3,   padding=1)
															self.lateral_convs.append(__UpperCamelCase)
															self.fpn_convs.append(__UpperCamelCase)

											_lowercase :							str   	=	UperNetConvModule(
											    len(self.in_channels) * self.channels,   self.channels,   kernel_size=3,   padding=1,   )
							def     UpperCamelCase  (      self) ->     Any:




											"""simple docstring"""

											self.apply(self._init_weights)
							def     UpperCamelCase  (      self,   lowerCamelCase) ->     List[Any]:




											"""simple docstring"""

											if isinstance(__UpperCamelCase,   nn.Convad):
															module.weight.data.normal_(mean=0.0,   std=self.config.initializer_range)
															if module.bias is not None:
																			module.bias.data.zero_()
							def     UpperCamelCase  (      self,   lowerCamelCase) ->     Optional[Any]:




											"""simple docstring"""

											_lowercase :							str   	=	inputs[-1]
											_lowercase :							Union[str, Any]   	=	[x]
											psp_outs.extend(self.psp_modules(__UpperCamelCase))
											_lowercase :							int   	=	torch.cat(__UpperCamelCase,   dim=1)
											_lowercase :							Optional[Any]   	=	self.bottleneck(__UpperCamelCase)

											return output




							def     UpperCamelCase  (      self,   lowerCamelCase) ->     str:




											"""simple docstring"""

											_lowercase :							Any   	=	[lateral_conv(encoder_hidden_states[i]) for i, lateral_conv in enumerate(self.lateral_convs)]

											laterals.append(self.psp_forward(__UpperCamelCase))

											# build top-down path
											_lowercase :							List[str]   	=	len(__UpperCamelCase)
											for i in range(used_backbone_levels - 1,   0,   -1):
															_lowercase :							List[Any]   	=	laterals[i - 1].shape[2:]
															_lowercase :							List[Any]   	=	laterals[i - 1] + nn.functional.interpolate(
															    laterals[i],   size=__UpperCamelCase,   mode='bilinear',   align_corners=self.align_corners)

											# build outputs
											_lowercase :							Optional[Any]   	=	[self.fpn_convs[i](laterals[i]) for i in range(used_backbone_levels - 1)]
											# append psp feature
											fpn_outs.append(laterals[-1])

											for i in range(used_backbone_levels - 1,   0,   -1):
															_lowercase :							int   	=	nn.functional.interpolate(
															    fpn_outs[i],   size=fpn_outs[0].shape[2:],   mode='bilinear',   align_corners=self.align_corners)
											_lowercase :							int   	=	torch.cat(__UpperCamelCase,   dim=1)
											_lowercase :							str   	=	self.fpn_bottleneck(__UpperCamelCase)
											_lowercase :							Tuple   	=	self.classifier(__UpperCamelCase)

											return output






class _lowerCamelCase(		nn.Module     ):
							def __init__(      self,   lowerCamelCase,   lowerCamelCase = 2,   lowerCamelCase = 3,   lowerCamelCase = 1) ->     Any:




											"""simple docstring"""

											super().__init__()

											_lowercase :							str   	=	config
											_lowercase :							Dict   	=	config.auxiliary_in_channels
											_lowercase :							Optional[int]   	=	config.auxiliary_channels
											_lowercase :							int   	=	config.auxiliary_num_convs
											_lowercase :							int   	=	config.auxiliary_concat_input
											_lowercase :							Any   	=	in_index

											_lowercase :							Any   	=	(kernel_size // 2) * dilation
											_lowercase :							Optional[Any]   	=	[]
											convs.append(
											    UperNetConvModule(
											        self.in_channels,   self.channels,   kernel_size=__UpperCamelCase,   padding=__UpperCamelCase,   dilation=__UpperCamelCase))
											for i in range(self.num_convs - 1):
															convs.append(
															    UperNetConvModule(
															        self.channels,   self.channels,   kernel_size=__UpperCamelCase,   padding=__UpperCamelCase,   dilation=__UpperCamelCase))
											if self.num_convs == 0:
															_lowercase :							Optional[Any]   	=	nn.Identity()
											else:
															_lowercase :							Union[str, Any]   	=	nn.Sequential(*__UpperCamelCase)
											if self.concat_input:
															_lowercase :							Optional[int]   	=	UperNetConvModule(
															    self.in_channels + self.channels,   self.channels,   kernel_size=__UpperCamelCase,   padding=kernel_size // 2)

											_lowercase :							Tuple   	=	nn.Convad(self.channels,   config.num_labels,   kernel_size=1)
							def     UpperCamelCase  (      self) ->     Union[str, Any]:




											"""simple docstring"""

											self.apply(self._init_weights)
							def     UpperCamelCase  (      self,   lowerCamelCase) ->     Dict:




											"""simple docstring"""

											if isinstance(__UpperCamelCase,   nn.Convad):
															module.weight.data.normal_(mean=0.0,   std=self.config.initializer_range)
															if module.bias is not None:
																			module.bias.data.zero_()




							def     UpperCamelCase  (      self,   lowerCamelCase) ->     Union[str, Any]:




											"""simple docstring"""

											_lowercase :							Optional[int]   	=	encoder_hidden_states[self.in_index]
											_lowercase :							List[Any]   	=	self.convs(__UpperCamelCase)
											if self.concat_input:
															_lowercase :							Dict   	=	self.conv_cat(torch.cat([hidden_states, output],   dim=1))
											_lowercase :							Tuple   	=	self.classifier(__UpperCamelCase)
											return output






class _lowerCamelCase(		_a     ):
							lowercase_				:			Optional[Any]									=    UperNetConfig
							lowercase_				:			List[str]									=    """pixel_values"""
							lowercase_				:			Any									=    True
							def     UpperCamelCase  (      self,   lowerCamelCase) ->     List[str]:




											"""simple docstring"""

											if isinstance(__UpperCamelCase,   __UpperCamelCase):
															module.backbone.init_weights()
															module.decode_head.init_weights()
															module.auxiliary_head.init_weights()
							def     UpperCamelCase  (      self) ->     Dict:




											"""simple docstring"""

											self.backbone.init_weights()
											self.decode_head.init_weights()
											self.auxiliary_head.init_weights()




							def     UpperCamelCase  (      self,   lowerCamelCase,   lowerCamelCase=False) ->     Union[str, Any]:




											"""simple docstring"""

											if isinstance(__UpperCamelCase,   __UpperCamelCase):
															_lowercase :							Optional[Any]   	=	value


SCREAMING_SNAKE_CASE :   List[Any]							      =				r"\n    Parameters:\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        config ([`UperNetConfig`]): 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"

SCREAMING_SNAKE_CASE :   List[str]							      =				r"\n    Args:\n        pixel_values (`torch.FloatTensor` of shape `(batch_size, num_channels, height, width)`):\n            Pixel values. Padding will be ignored by default should you provide it. Pixel values can be obtained using\n            [`AutoImageProcessor`]. See [`SegformerImageProcessor.__call__`] for details.\n        output_attentions (`bool`, *optional*):\n            Whether or not to return the attentions tensors of all attention layers in case the backbone has them. See\n            `attentions` under returned tensors for more detail.\n        output_hidden_states (`bool`, *optional*):\n            Whether or not to return the hidden states of all layers of the backbone. See `hidden_states` under\n            returned tensors for 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(
    """UperNet framework leveraging any vision backbone e.g. for ADE20k, CityScapes.""",				_a,				)
class _lowerCamelCase(		_a     ):
							def __init__(      self,   lowerCamelCase) ->     int:




											"""simple docstring"""

											super().__init__(__UpperCamelCase)

											_lowercase :							Optional[int]   	=	AutoBackbone.from_config(config.backbone_config)

											# Semantic segmentation head(s)
											_lowercase :							Any   	=	UperNetHead(__UpperCamelCase,   in_channels=self.backbone.channels)
											_lowercase :							int   	=	UperNetFCNHead(__UpperCamelCase) if config.use_auxiliary_head else None

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




							@add_start_docstrings_to_model_forward(UPERNET_INPUTS_DOCSTRING.format('batch_size, sequence_length'))
							@replace_return_docstrings(output_type=__UpperCamelCase,   config_class=_CONFIG_FOR_DOC)
							def     UpperCamelCase  (      self,   lowerCamelCase = None,   lowerCamelCase = None,   lowerCamelCase = None,   lowerCamelCase = None,   lowerCamelCase = None,   ) ->     Optional[int]:




											"""simple docstring"""

											_lowercase :							Union[str, Any]   	=	return_dict if return_dict is not None else self.config.use_return_dict
											_lowercase :							Any   	=	(
											    output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states
											)
											_lowercase :							Optional[int]   	=	output_attentions if output_attentions is not None else self.config.output_attentions

											_lowercase :							List[str]   	=	self.backbone.forward_with_filtered_kwargs(
											    __UpperCamelCase,   output_hidden_states=__UpperCamelCase,   output_attentions=__UpperCamelCase)
											_lowercase :							Tuple   	=	outputs.feature_maps

											_lowercase :							str   	=	self.decode_head(__UpperCamelCase)
											_lowercase :							Union[str, Any]   	=	nn.functional.interpolate(__UpperCamelCase,   size=pixel_values.shape[2:],   mode='bilinear',   align_corners=__UpperCamelCase)

											_lowercase :							int   	=	None
											if self.auxiliary_head is not None:
															_lowercase :							List[Any]   	=	self.auxiliary_head(__UpperCamelCase)
															_lowercase :							str   	=	nn.functional.interpolate(
															    __UpperCamelCase,   size=pixel_values.shape[2:],   mode='bilinear',   align_corners=__UpperCamelCase)

											_lowercase :							int   	=	None
											if labels is not None:
															if self.config.num_labels == 1:
																			raise ValueError('The number of labels should be greater than one')
															else:
																			# compute weighted loss
																			_lowercase :							Optional[Any]   	=	CrossEntropyLoss(ignore_index=self.config.loss_ignore_index)
																			_lowercase :							Dict   	=	loss_fct(__UpperCamelCase,   __UpperCamelCase)
																			_lowercase :							int   	=	loss_fct(__UpperCamelCase,   __UpperCamelCase)
																			_lowercase :							List[Any]   	=	main_loss + self.config.auxiliary_loss_weight * auxiliary_loss

											if not return_dict:
															if output_hidden_states:
																			_lowercase :							Optional[int]   	=	(logits,) + outputs[1:]
															else:
																			_lowercase :							Optional[Any]   	=	(logits,) + outputs[2:]
															return ((loss,) + output) if loss is not None else output

											return SemanticSegmenterOutput(
											    loss=__UpperCamelCase,   logits=__UpperCamelCase,   hidden_states=outputs.hidden_states,   attentions=outputs.attentions,   )






from jiwer import compute_measures

import datasets


SCREAMING_SNAKE_CASE :   Tuple							      =				"\\n@inproceedings{inproceedings,\n    author = {Morris, Andrew and Maier, Viktoria and Green, Phil},\n    year = {2004},\n    month = {01},\n    pages = {},\n    title = {From WER and RIL to MER and WIL: improved evaluation measures for connected speech recognition.}\n}\n"

SCREAMING_SNAKE_CASE :   Optional[Any]							      =				"\\nWord error rate (WER) is a common metric of the performance of an automatic speech recognition system.\n\nThe general difficulty of measuring performance lies in the fact that the recognized word sequence can have a different length from the reference word sequence (supposedly the correct one). The WER is derived from the Levenshtein distance, working at the word level instead of the phoneme level. The WER is a valuable tool for comparing different systems as well as for evaluating improvements within one system. This kind of measurement, however, provides no details on the nature of translation errors and further work is therefore required to identify the main source(s) of error and to focus any research effort.\n\nThis problem is solved by first aligning the recognized word sequence with the reference (spoken) word sequence using dynamic string alignment. Examination of this issue is seen through a theory called the power law that states the correlation between perplexity and word error rate.\n\nWord error rate can then be computed as:\n\nWER = (S + D + I) / N = (S + D + I) / (S + D + C)\n\nwhere\n\nS is the number of substitutions,\nD is the number of deletions,\nI is the number of insertions,\nC is the number of correct words,\nN is the number of words in the reference (N=S+D+C).\n\nThis value indicates the average number of errors per reference word. The lower the value, the better the\nperformance of the ASR system with a WER of 0 being a perfect score.\n"

SCREAMING_SNAKE_CASE :   Any							      =				"\nCompute WER score of transcribed segments against references.\n\nArgs:\n    references: List of references for each speech input.\n    predictions: List of transcriptions to score.\n    concatenate_texts (bool, default=False): Whether to concatenate all input texts or compute WER iteratively.\n\nReturns:\n    (float): the word error rate\n\nExamples:\n\n    >>> predictions = [\"this is the prediction\", \"there is an other sample\"]\n    >>> references = [\"this is the reference\", \"there is another one\"]\n    >>> wer = datasets.load_metric(\"wer\")\n    >>> wer_score = wer.compute(predictions=predictions, references=references)\n    >>> print(wer_score)\n    0.5\n"






@datasets.utils.file_utils.add_start_docstrings(_DESCRIPTION,				_KWARGS_DESCRIPTION     )
class _lowerCamelCase(		datasets.Metric     ):
       def     UpperCamelCase  (      self) ->     Optional[Any]:




           """simple docstring"""

           return datasets.MetricInfo(
               description=_DESCRIPTION,   citation=_CITATION,   inputs_description=_KWARGS_DESCRIPTION,   features=datasets.Features(
                   {
                       'predictions': datasets.Value('string',   id='sequence'),
                       'references': datasets.Value('string',   id='sequence'),
                   }),   codebase_urls=['https://github.com/jitsi/jiwer/'],   reference_urls=[
                   'https://en.wikipedia.org/wiki/Word_error_rate',
               ],   )




       def     UpperCamelCase  (      self,   lowerCamelCase=None,   lowerCamelCase=None,   lowerCamelCase=False) ->     Optional[Any]:




           """simple docstring"""

           if concatenate_texts:
               return compute_measures(lowerCamelCase,   lowerCamelCase)["wer"]
           else:
               _lowercase :							Dict   	=	0
               _lowercase :							Optional[int]   	=	0
               for prediction, reference in zip(lowerCamelCase,   lowerCamelCase):
                   _lowercase :							List[Any]   	=	compute_measures(lowerCamelCase,   lowerCamelCase)
                   incorrect += measures["substitutions"] + measures["deletions"] + measures["insertions"]
                   total += measures["substitutions"] + measures["deletions"] + measures["hits"]
               return incorrect / total


