


'''simple docstring'''


import json
import logging
import os
import re
import sys
from dataclasses import dataclass, field
from typing import Any, Dict, List, Optional, Union

import datasets
import numpy as np
import torch
import torchaudio
from packaging import version
from torch import nn

import transformers
from transformers import (
    HfArgumentParser,
    Trainer,
    TrainingArguments,
    WavaVecaCTCTokenizer,
    WavaVecaFeatureExtractor,
    WavaVecaForCTC,
    WavaVecaProcessor,
    is_apex_available,
    set_seed,
)
from transformers.trainer_utils import get_last_checkpoint, is_main_process


if is_apex_available():
	from apex import amp


if version.parse(version.parse(torch.__version__).base_version) >= version.parse('1.6'):
	lowerCamelCase__    	=     True
	from torch.cuda.amp import autocast

lowerCamelCase__    	=     logging.getLogger(__name__)






def  __lowerCAmelCase (__lowerCAmelCase=None      , __lowerCAmelCase=None   ):
		return field(default_factory=lambda: default      , metadata=__lowerCAmelCase   )






@dataclass
class 	lowerCAmelCase__			:
			lowerCAmelCase :	str          =     field(
			    metadata={"help": "Path to pretrained model or model identifier from huggingface.co/models"}	)
			lowerCAmelCase :	Optional[str]          =     field(
			    default=UpperCAmelCase__    ,       metadata={"help": "Where do you want to store the pretrained models downloaded from huggingface.co"}    ,       )
			lowerCAmelCase :	Optional[bool]          =     field(
			    default=UpperCAmelCase__    ,       metadata={"help": "Whether to freeze the feature extractor layers of the model."}	)
			lowerCAmelCase :	Optional[float]          =     field(
			    default=0.1    ,       metadata={"help": "The dropout ratio for the attention probabilities."}	)
			lowerCAmelCase :	Optional[float]          =     field(
			    default=0.1    ,       metadata={"help": "The dropout ratio for activations inside the fully connected layer."}	)
			lowerCAmelCase :	Optional[float]          =     field(
			    default=0.1    ,       metadata={
			        "help": "The dropout probabilitiy for all fully connected layers in the embeddings, encoder, and pooler."
			    }    ,       )
			lowerCAmelCase :	Optional[float]          =     field(
			    default=0.1    ,       metadata={"help": "The dropout probabilitiy for all 1D convolutional layers in feature extractor."}    ,       )
			lowerCAmelCase :	Optional[float]          =     field(
			    default=0.05    ,       metadata={
			        "help": (
			            "Propability of each feature vector along the time axis to be chosen as the start of the vector"
			            "span to be masked. Approximately ``mask_time_prob * sequence_length // mask_time_length`` feature"
			            "vectors will be masked along the time axis. This is only relevant if ``apply_spec_augment is True``."
			        )
			    }    ,       )
			lowerCAmelCase :	Optional[float]          =     field(default=0.0    ,       metadata={"help": "The LayerDrop probability."}	)






@dataclass
class 	lowerCAmelCase__			:
			lowerCAmelCase :	Optional[str]          =     field(
			    default=UpperCAmelCase__    ,       metadata={"help": "The configuration name of the dataset to use (via the datasets library)."}	)
			lowerCAmelCase :	Optional[str]          =     field(
			    default="train+validation"    ,       metadata={
			        "help": "The name of the training data set split to use (via the datasets library). Defaults to 'train'"
			    }    ,       )
			lowerCAmelCase :	bool          =     field(
			    default=UpperCAmelCase__    ,       metadata={"help": "Overwrite the cached preprocessed datasets or not."}	)
			lowerCAmelCase :	Optional[int]          =     field(
			    default=UpperCAmelCase__    ,       metadata={"help": "The number of processes to use for the preprocessing."}    ,       )
			lowerCAmelCase :	Optional[int]          =     field(
			    default=UpperCAmelCase__    ,       metadata={
			        "help": (
			            "For debugging purposes or quicker training, truncate the number of training examples to this "
			            "value if set."
			        )
			    }    ,       )
			lowerCAmelCase :	Optional[int]          =     field(
			    default=UpperCAmelCase__    ,       metadata={
			        "help": (
			            "For debugging purposes or quicker training, truncate the number of validation examples to this "
			            "value if set."
			        )
			    }    ,       )
			lowerCAmelCase :	List[str]          =     list_field(
			    default=[",", "?", ".", "!", "-", ";", ":", "\"\"", "%", "'", "\"", "�"]    ,       metadata={"help": "A list of characters to remove from the transcripts."}    ,       )






@dataclass
class 	lowerCAmelCase__			:
			lowerCAmelCase :	WavaVecaProcessor
			lowerCAmelCase :	Union[bool, str]          =     True
			lowerCAmelCase :	Optional[int]          =     None
			lowerCAmelCase :	Optional[int]          =     None
			lowerCAmelCase :	Optional[int]          =     None
			lowerCAmelCase :	Optional[int]          =     None




			def __call__(		self  :     List[Any]	,  lowerCamelCase__  :     List[Dict[str, Union[List[int], torch.Tensor]]] )   ->Dict[str, torch.Tensor]:



					'''simple docstring'''







					_UpperCAmelCase		:       Optional[Any]								=      [{"input_values": feature["input_values"]} for feature in features]
					_UpperCAmelCase		:       List[Any]								=      [{"input_ids": feature["labels"]} for feature in features]

					_UpperCAmelCase		:       List[str]								=      self.processor.pad(
					    lowerCamelCase__	,  padding=self.padding	,  max_length=self.max_length	,  pad_to_multiple_of=self.pad_to_multiple_of	,  return_tensors="pt"	,  )
					_UpperCAmelCase		:       str								=      self.processor.pad(
					    labels=lowerCamelCase__	,  padding=self.padding	,  max_length=self.max_length_labels	,  pad_to_multiple_of=self.pad_to_multiple_of_labels	,  return_tensors="pt"	,  )

					# replace padding with -100 to ignore loss correctly
					_UpperCAmelCase		:       Any								=      labels_batch["input_ids"].masked_fill(labels_batch.attention_mask.ne(1 )	,  -1_00 )

					_UpperCAmelCase		:       Any								=      labels

					return batch






class 	lowerCAmelCase__			(			UpperCAmelCase__	):




			def 							lowerCAmelCase__    (		self  :     Optional[Any]	,  lowerCamelCase__  :     nn.Module	,  lowerCamelCase__  :     Dict[str, Union[torch.Tensor, Any]] )   ->torch.Tensor:



					'''simple docstring'''







					model.train()
					_UpperCAmelCase		:       Optional[int]								=      self._prepare_inputs(lowerCamelCase__ )

					if self.use_amp:
							with autocast():
									_UpperCAmelCase		:       Tuple								=      self.compute_loss(lowerCamelCase__	,  lowerCamelCase__ )
					else:
							_UpperCAmelCase		:       Union[str, Any]								=      self.compute_loss(lowerCamelCase__	,  lowerCamelCase__ )

					if self.args.n_gpu > 1:
							if model.module.config.ctc_loss_reduction == "mean":
									_UpperCAmelCase		:       Any								=      loss.mean()
							elif model.module.config.ctc_loss_reduction == "sum":
									_UpperCAmelCase		:       Optional[Any]								=      loss.sum() / (inputs["labels"] >= 0).sum()
							else:
									raise ValueError(F"""{model.config.ctc_loss_reduction} is not valid. Choose one of ['mean', 'sum']""" )

					if self.args.gradient_accumulation_steps > 1:
							_UpperCAmelCase		:       int								=      loss / self.args.gradient_accumulation_steps

					if self.use_amp:
							self.scaler.scale(lowerCamelCase__ ).backward()
					elif self.use_apex:
							with amp.scale_loss(lowerCamelCase__	,  self.optimizer ) as scaled_loss:
									scaled_loss.backward()
					elif self.deepspeed:
							self.deepspeed.backward(lowerCamelCase__ )
					else:
							loss.backward()

					return loss.detach()






def  __lowerCAmelCase ():
		# See all possible arguments in src/transformers/training_args.py
		# or by passing the --help flag to this script.
		# We now keep distinct sets of args, for a cleaner separation of concerns.

		_UpperCAmelCase		:       Optional[int]								=      HfArgumentParser((ModelArguments, DataTrainingArguments, TrainingArguments)   )
		if len(sys.argv   ) == 2 and sys.argv[1].endswith(".json"   ):
				# If we pass only one argument to the script and it's the path to a json file,
				# let's parse it to get our arguments.
				_UpperCAmelCase		:       int								=      parser.parse_json_file(json_file=os.path.abspath(sys.argv[1]   )   )
		else:
				_UpperCAmelCase		:       Dict								=      parser.parse_args_into_dataclasses()

		# Detecting last checkpoint.
		_UpperCAmelCase		:       List[str]								=      None
		if os.path.isdir(training_args.output_dir   ) and training_args.do_train and not training_args.overwrite_output_dir:
				_UpperCAmelCase		:       List[str]								=      get_last_checkpoint(training_args.output_dir   )
				if last_checkpoint is None and len(os.listdir(training_args.output_dir   )   ) > 0:
						raise ValueError(
						    F"""Output directory ({training_args.output_dir}) already exists and is not empty. """
						    "Use --overwrite_output_dir to overcome."   )
				elif last_checkpoint is not None:
						logger.info(
						    F"""Checkpoint detected, resuming training at {last_checkpoint}. To avoid this behavior, change """
						    "the `--output_dir` or add `--overwrite_output_dir` to train from scratch."   )

    # Setup logging
		logging.basicConfig(
		    format="%(asctime)s - %(levelname)s - %(name)s - %(message)s"      , datefmt="%m/%d/%Y %H:%M:%S"      , handlers=[logging.StreamHandler(sys.stdout   )]      , )
		logger.setLevel(logging.INFO if is_main_process(training_args.local_rank   ) else logging.WARN   )

		# Log on each process the small summary:
		logger.warning(
		    F"""Process rank: {training_args.local_rank}, device: {training_args.device}, n_gpu: {training_args.n_gpu}"""
		    + F"""distributed training: {bool(training_args.local_rank != -1   )}, 16-bits training: {training_args.fpaa}"""   )
		# Set the verbosity to info of the Transformers logger (on main process only):
		if is_main_process(training_args.local_rank   ):
				transformers.utils.logging.set_verbosity_info()
		logger.info("Training/evaluation parameters %s"      , __lowerCAmelCase   )

		# Set seed before initializing model.
		set_seed(training_args.seed   )

		# Get the datasets:
		_UpperCAmelCase		:       Union[str, Any]								=      datasets.load_dataset(
		    "common_voice"      , data_args.dataset_config_name      , split=data_args.train_split_name   )
		_UpperCAmelCase		:       List[str]								=      datasets.load_dataset("common_voice"      , data_args.dataset_config_name      , split="test"   )

		# Create and save tokenizer
		_UpperCAmelCase		:       Dict								=      F"""[{''.join(data_args.chars_to_ignore   )}]"""

		def remove_special_characters(__lowerCAmelCase   ):
				_UpperCAmelCase		:       List[str]								=      re.sub(__lowerCAmelCase      , ""      , batch["sentence"]   ).lower() + " "
				return batch

		_UpperCAmelCase		:       str								=      train_dataset.map(__lowerCAmelCase      , remove_columns=["sentence"]   )
		_UpperCAmelCase		:       List[str]								=      eval_dataset.map(__lowerCAmelCase      , remove_columns=["sentence"]   )

		def extract_all_chars(__lowerCAmelCase   ):
				_UpperCAmelCase		:       str								=      " ".join(batch["text"]   )
				_UpperCAmelCase		:       Dict								=      list(set(__lowerCAmelCase   )   )
				return {"vocab": [vocab], "all_text": [all_text]}

		_UpperCAmelCase		:       Tuple								=      train_dataset.map(
		    __lowerCAmelCase      , batched=__lowerCAmelCase      , batch_size=-1      , keep_in_memory=__lowerCAmelCase      , remove_columns=train_dataset.column_names      , )
		_UpperCAmelCase		:       List[str]								=      train_dataset.map(
		    __lowerCAmelCase      , batched=__lowerCAmelCase      , batch_size=-1      , keep_in_memory=__lowerCAmelCase      , remove_columns=eval_dataset.column_names      , )

		_UpperCAmelCase		:       List[Any]								=      list(set(vocab_train["vocab"][0]   ) | set(vocab_test["vocab"][0]   )   )
		_UpperCAmelCase		:       Dict								=      {v: k for k, v in enumerate(__lowerCAmelCase   )}
		_UpperCAmelCase		:       Dict								=      vocab_dict[" "]
		del vocab_dict[" "]
		_UpperCAmelCase		:       Tuple								=      len(__lowerCAmelCase   )
		_UpperCAmelCase		:       List[Any]								=      len(__lowerCAmelCase   )

		with open("vocab.json"      , "w"   ) as vocab_file:
				json.dump(__lowerCAmelCase      , __lowerCAmelCase   )

		# Load pretrained model and tokenizer
		#
		# Distributed training:
		# The .from_pretrained methods guarantee that only one local process can concurrently
		# download model & vocab.
		_UpperCAmelCase		:       Tuple								=      WavaVecaCTCTokenizer(
		    "vocab.json"      , unk_token="[UNK]"      , pad_token="[PAD]"      , word_delimiter_token="|"      , )
		_UpperCAmelCase		:       List[Any]								=      WavaVecaFeatureExtractor(
		    feature_size=1      , sampling_rate=16_000      , padding_value=0.0      , do_normalize=__lowerCAmelCase      , return_attention_mask=__lowerCAmelCase   )
		_UpperCAmelCase		:       List[Any]								=      WavaVecaProcessor(feature_extractor=__lowerCAmelCase      , tokenizer=__lowerCAmelCase   )
		_UpperCAmelCase		:       List[Any]								=      WavaVecaForCTC.from_pretrained(
		    model_args.model_name_or_path      , cache_dir=model_args.cache_dir      , activation_dropout=model_args.activation_dropout      , attention_dropout=model_args.attention_dropout      , hidden_dropout=model_args.hidden_dropout      , feat_proj_dropout=model_args.feat_proj_dropout      , mask_time_prob=model_args.mask_time_prob      , gradient_checkpointing=training_args.gradient_checkpointing      , layerdrop=model_args.layerdrop      , ctc_loss_reduction="mean"      , pad_token_id=processor.tokenizer.pad_token_id      , vocab_size=len(processor.tokenizer   )      , )

		if data_args.max_train_samples is not None:
				_UpperCAmelCase		:       int								=      min(len(__lowerCAmelCase   )      , data_args.max_train_samples   )
				_UpperCAmelCase		:       Optional[int]								=      train_dataset.select(range(__lowerCAmelCase   )   )

		if data_args.max_val_samples is not None:
				_UpperCAmelCase		:       List[Any]								=      eval_dataset.select(range(data_args.max_val_samples   )   )

		_UpperCAmelCase		:       Union[str, Any]								=      torchaudio.transforms.Resample(48_000      , 16_000   )

		# Preprocessing the datasets.
		# We need to read the aduio files as arrays and tokenize the targets.
		def speech_file_to_array_fn(__lowerCAmelCase   ):
				_UpperCAmelCase		:       Optional[Any]								=      torchaudio.load(batch["path"]   )
				_UpperCAmelCase		:       int								=      resampler(__lowerCAmelCase   ).squeeze().numpy()
				_UpperCAmelCase		:       str								=      16_000
				_UpperCAmelCase		:       Tuple								=      batch["text"]
				return batch

		_UpperCAmelCase		:       List[str]								=      train_dataset.map(
		    __lowerCAmelCase      , remove_columns=train_dataset.column_names      , num_proc=data_args.preprocessing_num_workers      , )
		_UpperCAmelCase		:       Tuple								=      eval_dataset.map(
		    __lowerCAmelCase      , remove_columns=eval_dataset.column_names      , num_proc=data_args.preprocessing_num_workers      , )

		def prepare_dataset(__lowerCAmelCase   ):
				# check that all files have the correct sampling rate
				assert (
				    len(set(batch["sampling_rate"]   )   ) == 1
				), F"""Make sure all inputs have the same sampling rate of {processor.feature_extractor.sampling_rate}."""

				_UpperCAmelCase		:       Optional[Any]								=      processor(
				    audio=batch["speech"]      , text=batch["target_text"]      , sampling_rate=batch["sampling_rate"][0]   )
				batch.update(__lowerCAmelCase   )
				return batch

		_UpperCAmelCase		:       int								=      train_dataset.map(
		    __lowerCAmelCase      , remove_columns=train_dataset.column_names      , batch_size=training_args.per_device_train_batch_size      , batched=__lowerCAmelCase      , num_proc=data_args.preprocessing_num_workers      , )
		_UpperCAmelCase		:       Tuple								=      eval_dataset.map(
		    __lowerCAmelCase      , remove_columns=eval_dataset.column_names      , batch_size=training_args.per_device_train_batch_size      , batched=__lowerCAmelCase      , num_proc=data_args.preprocessing_num_workers      , )

		# Metric
		_UpperCAmelCase		:       List[Any]								=      datasets.load_metric("wer"   )

		def compute_metrics(__lowerCAmelCase   ):
				_UpperCAmelCase		:       Optional[Any]								=      pred.predictions
				_UpperCAmelCase		:       Optional[int]								=      np.argmax(__lowerCAmelCase      , axis=-1   )

				_UpperCAmelCase		:       Any								=      processor.tokenizer.pad_token_id

				_UpperCAmelCase		:       List[Any]								=      processor.batch_decode(__lowerCAmelCase   )
				# we do not want to group tokens when computing the metrics
				_UpperCAmelCase		:       Optional[int]								=      processor.batch_decode(pred.label_ids      , group_tokens=__lowerCAmelCase   )

				_UpperCAmelCase		:       str								=      wer_metric.compute(predictions=__lowerCAmelCase      , references=__lowerCAmelCase   )

				return {"wer": wer}

		if model_args.freeze_feature_extractor:
				model.freeze_feature_extractor()

		# Data collator
		_UpperCAmelCase		:       str								=      DataCollatorCTCWithPadding(processor=__lowerCAmelCase      , padding=__lowerCAmelCase   )

		# Initialize our Trainer
		_UpperCAmelCase		:       Optional[int]								=      CTCTrainer(
		    model=__lowerCAmelCase      , data_collator=__lowerCAmelCase      , args=__lowerCAmelCase      , compute_metrics=__lowerCAmelCase      , train_dataset=train_dataset if training_args.do_train else None      , eval_dataset=eval_dataset if training_args.do_eval else None      , tokenizer=processor.feature_extractor      , )

		# Training
		if training_args.do_train:
				if last_checkpoint is not None:
						_UpperCAmelCase		:       Dict								=      last_checkpoint
				elif os.path.isdir(model_args.model_name_or_path   ):
						_UpperCAmelCase		:       Optional[Any]								=      model_args.model_name_or_path
				else:
						_UpperCAmelCase		:       Dict								=      None

				# Save the feature_extractor and the tokenizer
				if is_main_process(training_args.local_rank   ):
						processor.save_pretrained(training_args.output_dir   )

				_UpperCAmelCase		:       Optional[Any]								=      trainer.train(resume_from_checkpoint=__lowerCAmelCase   )
				trainer.save_model()

				_UpperCAmelCase		:       List[Any]								=      train_result.metrics
				_UpperCAmelCase		:       str								=      (
				    data_args.max_train_samples if data_args.max_train_samples is not None else len(__lowerCAmelCase   )
				)
				_UpperCAmelCase		:       Tuple								=      min(__lowerCAmelCase      , len(__lowerCAmelCase   )   )

				trainer.log_metrics("train"      , __lowerCAmelCase   )
				trainer.save_metrics("train"      , __lowerCAmelCase   )
				trainer.save_state()

		# Evaluation
		_UpperCAmelCase		:       Optional[Any]								=      {}
		if training_args.do_eval:
				logger.info("*** Evaluate ***"   )
				_UpperCAmelCase		:       Tuple								=      trainer.evaluate()
				_UpperCAmelCase		:       Optional[Any]								=      data_args.max_val_samples if data_args.max_val_samples is not None else len(__lowerCAmelCase   )
				_UpperCAmelCase		:       int								=      min(__lowerCAmelCase      , len(__lowerCAmelCase   )   )

				trainer.log_metrics("eval"      , __lowerCAmelCase   )
				trainer.save_metrics("eval"      , __lowerCAmelCase   )

		return results


if __name__ == "__main__":
	main()







'''simple docstring'''


from typing import Tuple, Union

from ...modeling_outputs import BackboneOutput
from ...modeling_utils import PreTrainedModel
from ...utils import is_timm_available, is_torch_available, requires_backends
from ...utils.backbone_utils import BackboneMixin
from .configuration_timm_backbone import TimmBackboneConfig


if is_timm_available():
						import timm


if is_torch_available():
						from torch import Tensor






class 	lowerCAmelCase__			(			UpperCAmelCase__    ,       UpperCAmelCase__	):
			lowerCAmelCase :	int          =     "pixel_values"
			lowerCAmelCase :	Dict          =     False
			lowerCAmelCase :	Union[str, Any]          =     TimmBackboneConfig




			def __init__(		self  :     List[str]	,  lowerCamelCase__  :     Dict	,  **lowerCamelCase__  :     str )   ->Dict:



					'''simple docstring'''







					requires_backends(self	,  "timm" )
					super().__init__(lowerCamelCase__ )
					_UpperCAmelCase		:       Any								=      config

					if config.backbone is None:
							raise ValueError("backbone is not set in the config. Please set it to a timm model name." )

					if config.backbone not in timm.list_models():
							raise ValueError(F"""backbone {config.backbone} is not supported by timm.""" )

					if hasattr(lowerCamelCase__	,  "out_features" ) and config.out_features is not None:
							raise ValueError("out_features is not supported by TimmBackbone. Please use out_indices instead." )

					_UpperCAmelCase		:       Optional[Any]								=      getattr(lowerCamelCase__	,  "use_pretrained_backbone"	,  lowerCamelCase__ )
					if pretrained is None:
							raise ValueError("use_pretrained_backbone is not set in the config. Please set it to True or False." )

					# We just take the final layer by default. This matches the default for the transformers models.
					_UpperCAmelCase		:       int								=      config.out_indices if getattr(lowerCamelCase__	,  "out_indices"	,  lowerCamelCase__ ) is not None else (-1,)

					_UpperCAmelCase		:       List[Any]								=      timm.create_model(
					    config.backbone	,  pretrained=lowerCamelCase__	,  features_only=config.features_only	,  in_chans=config.num_channels	,  out_indices=lowerCamelCase__	,  **lowerCamelCase__	,  )
					# These are used to control the output of the model when called. If output_hidden_states is True, then
					# return_layers is modified to include all layers.
					_UpperCAmelCase		:       List[str]								=      self._backbone.return_layers
					_UpperCAmelCase		:       Optional[int]								=      {layer["module"]: str(lowerCamelCase__ ) for i, layer in enumerate(self._backbone.feature_info.info )}
					super()._init_backbone(lowerCamelCase__ )




			@classmethod
			def 							lowerCAmelCase__    (		cls  :     List[str]	,  lowerCamelCase__  :     str	,  *lowerCamelCase__  :     Tuple	,  **lowerCamelCase__  :     Optional[Any] )   ->Optional[Any]:



					'''simple docstring'''







					requires_backends(cls	,  ["vision", "timm"] )
					from ...models.timm_backbone import TimmBackboneConfig

					_UpperCAmelCase		:       Any								=      kwargs.pop("config"	,  TimmBackboneConfig() )

					_UpperCAmelCase		:       Dict								=      kwargs.pop("use_timm_backbone"	,  lowerCamelCase__ )
					if not use_timm:
							raise ValueError("use_timm_backbone must be True for timm backbones" )

					_UpperCAmelCase		:       str								=      kwargs.pop("num_channels"	,  config.num_channels )
					_UpperCAmelCase		:       Dict								=      kwargs.pop("features_only"	,  config.features_only )
					_UpperCAmelCase		:       str								=      kwargs.pop("use_pretrained_backbone"	,  config.use_pretrained_backbone )
					_UpperCAmelCase		:       Optional[Any]								=      kwargs.pop("out_indices"	,  config.out_indices )
					_UpperCAmelCase		:       Dict								=      TimmBackboneConfig(
					    backbone=lowerCamelCase__	,  num_channels=lowerCamelCase__	,  features_only=lowerCamelCase__	,  use_pretrained_backbone=lowerCamelCase__	,  out_indices=lowerCamelCase__	,  )
					return super()._from_config(lowerCamelCase__	,  **lowerCamelCase__ )




			def 							lowerCAmelCase__    (		self  :     Tuple	,  lowerCamelCase__  :     str )   ->Optional[int]:



					'''simple docstring'''







					pass






			def 							lowerCAmelCase__    (		self  :     Union[str, Any]	,  lowerCamelCase__  :     Tuple	,  lowerCamelCase__  :     Union[str, Any]=None	,  lowerCamelCase__  :     List[Any]=None	,  lowerCamelCase__  :     Union[str, Any]=None	,  **lowerCamelCase__  :     Dict )   ->Union[BackboneOutput, Tuple[Tensor, ...]]:



					'''simple docstring'''







					_UpperCAmelCase		:       Any								=      return_dict if return_dict is not None else self.config.use_return_dict
					_UpperCAmelCase		:       Optional[int]								=      (
					    output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states
					)
					_UpperCAmelCase		:       Dict								=      output_attentions if output_attentions is not None else self.config.output_attentions

					if output_attentions:
							raise ValueError("Cannot output attentions for timm backbones at the moment" )

					if output_hidden_states:
							# We modify the return layers to include all the stages of the backbone
							_UpperCAmelCase		:       Optional[int]								=      self._all_layers
							_UpperCAmelCase		:       List[str]								=      self._backbone(lowerCamelCase__	,  **lowerCamelCase__ )
							_UpperCAmelCase		:       List[Any]								=      self._return_layers
							_UpperCAmelCase		:       Tuple								=      tuple(hidden_states[i] for i in self.out_indices )
					else:
							_UpperCAmelCase		:       Any								=      self._backbone(lowerCamelCase__	,  **lowerCamelCase__ )
							_UpperCAmelCase		:       Tuple								=      None

					_UpperCAmelCase		:       Dict								=      tuple(lowerCamelCase__ )
					_UpperCAmelCase		:       Optional[Any]								=      tuple(lowerCamelCase__ ) if hidden_states is not None else None

					if not return_dict:
							_UpperCAmelCase		:       Dict								=      (feature_maps,)
							if output_hidden_states:
									_UpperCAmelCase		:       List[str]								=      output + (hidden_states,)
							return output

					return BackboneOutput(feature_maps=lowerCamelCase__	,  hidden_states=lowerCamelCase__	,  attentions=lowerCamelCase__ )



