Aluode/PerceptionLabPortable
0
1# coding=utf-82# Copyright 2021 NVIDIA The HuggingFace Inc. team. All rights reserved.3#4# Licensed under the Apache License, Version 2.0 (the "License");5# you may not use this file except in compliance with the License.6# You may obtain a copy of the License at7#8# http://www.apache.org/licenses/LICENSE-2.09#10# Unless required by applicable law or agreed to in writing, software11# distributed under the License is distributed on an "AS IS" BASIS,12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.13# See the License for the specific language governing permissions and14# limitations under the License.15"""PyTorch SegFormer model."""16 17import math18from typing import Optional, Union19 20import torch21from torch import nn22from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss23 24from ...activations import ACT2FN25from ...modeling_outputs import BaseModelOutput, ImageClassifierOutput, SemanticSegmenterOutput26from ...modeling_utils import PreTrainedModel27from ...pytorch_utils import find_pruneable_heads_and_indices, prune_linear_layer28from ...utils import auto_docstring, logging29from .configuration_segformer import SegformerConfig30 31 32logger = logging.get_logger(__name__)33 34 35class SegFormerImageClassifierOutput(ImageClassifierOutput):36 """37 Base class for outputs of image classification models.38 39 Args:40 loss (`torch.FloatTensor` of shape `(1,)`, *optional*, returned when `labels` is provided):41 Classification (or regression if config.num_labels==1) loss.42 logits (`torch.FloatTensor` of shape `(batch_size, config.num_labels)`):43 Classification (or regression if config.num_labels==1) scores (before SoftMax).44 hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`):45 Tuple of `torch.FloatTensor` (one for the output of the embeddings, if the model has an embedding layer, +46 one for the output of each stage) of shape `(batch_size, num_channels, height, width)`. Hidden-states (also47 called feature maps) of the model at the output of each stage.48 attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`):49 Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_heads, patch_size,50 sequence_length)`.51 52 Attentions weights after the attention softmax, used to compute the weighted average in the self-attention53 heads.54 """55 56 loss: Optional[torch.FloatTensor] = None57 logits: Optional[torch.FloatTensor] = None58 hidden_states: Optional[tuple[torch.FloatTensor]] = None59 attentions: Optional[tuple[torch.FloatTensor]] = None60 61 62# Copied from transformers.models.beit.modeling_beit.drop_path63def drop_path(input: torch.Tensor, drop_prob: float = 0.0, training: bool = False) -> torch.Tensor:64 """65 Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks).66 67 Comment by Ross Wightman: This is the same as the DropConnect impl I created for EfficientNet, etc networks,68 however, the original name is misleading as 'Drop Connect' is a different form of dropout in a separate paper...69 See discussion: https://github.com/tensorflow/tpu/issues/494#issuecomment-532968956 ... I've opted for changing the70 layer and argument names to 'drop path' rather than mix DropConnect as a layer name and use 'survival rate' as the71 argument.72 """73 if drop_prob == 0.0 or not training:74 return input75 keep_prob = 1 - drop_prob76 shape = (input.shape[0],) + (1,) * (input.ndim - 1) # work with diff dim tensors, not just 2D ConvNets77 random_tensor = keep_prob + torch.rand(shape, dtype=input.dtype, device=input.device)78 random_tensor.floor_() # binarize79 output = input.div(keep_prob) * random_tensor80 return output81 82 83# Copied from transformers.models.convnext.modeling_convnext.ConvNextDropPath with ConvNext->Segformer84class SegformerDropPath(nn.Module):85 """Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks)."""86 87 def __init__(self, drop_prob: Optional[float] = None) -> None:88 super().__init__()89 self.drop_prob = drop_prob90 91 def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:92 return drop_path(hidden_states, self.drop_prob, self.training)93 94 def extra_repr(self) -> str:95 return f"p={self.drop_prob}"96 97 98class SegformerOverlapPatchEmbeddings(nn.Module):99 """Construct the overlapping patch embeddings."""100 101 def __init__(self, patch_size, stride, num_channels, hidden_size):102 super().__init__()103 self.proj = nn.Conv2d(104 num_channels,105 hidden_size,106 kernel_size=patch_size,107 stride=stride,108 padding=patch_size // 2,109 )110 111 self.layer_norm = nn.LayerNorm(hidden_size)112 113 def forward(self, pixel_values):114 embeddings = self.proj(pixel_values)115 _, _, height, width = embeddings.shape116 # (batch_size, num_channels, height, width) -> (batch_size, num_channels, height*width) -> (batch_size, height*width, num_channels)117 # this can be fed to a Transformer layer118 embeddings = embeddings.flatten(2).transpose(1, 2)119 embeddings = self.layer_norm(embeddings)120 return embeddings, height, width121 122 123class SegformerEfficientSelfAttention(nn.Module):124 """SegFormer's efficient self-attention mechanism. Employs the sequence reduction process introduced in the [PvT125 paper](https://huggingface.co/papers/2102.12122)."""126 127 def __init__(self, config, hidden_size, num_attention_heads, sequence_reduction_ratio):128 super().__init__()129 self.hidden_size = hidden_size130 self.num_attention_heads = num_attention_heads131 132 if self.hidden_size % self.num_attention_heads != 0:133 raise ValueError(134 f"The hidden size ({self.hidden_size}) is not a multiple of the number of attention "135 f"heads ({self.num_attention_heads})"136 )137 138 self.attention_head_size = int(self.hidden_size / self.num_attention_heads)139 self.all_head_size = self.num_attention_heads * self.attention_head_size140 141 self.query = nn.Linear(self.hidden_size, self.all_head_size)142 self.key = nn.Linear(self.hidden_size, self.all_head_size)143 self.value = nn.Linear(self.hidden_size, self.all_head_size)144 145 self.dropout = nn.Dropout(config.attention_probs_dropout_prob)146 147 self.sr_ratio = sequence_reduction_ratio148 if sequence_reduction_ratio > 1:149 self.sr = nn.Conv2d(150 hidden_size, hidden_size, kernel_size=sequence_reduction_ratio, stride=sequence_reduction_ratio151 )152 self.layer_norm = nn.LayerNorm(hidden_size)153 154 def forward(155 self,156 hidden_states,157 height,158 width,159 output_attentions=False,160 ):161 batch_size, seq_length, _ = hidden_states.shape162 query_layer = (163 self.query(hidden_states)164 .view(batch_size, -1, self.num_attention_heads, self.attention_head_size)165 .transpose(1, 2)166 )167 168 if self.sr_ratio > 1:169 batch_size, seq_len, num_channels = hidden_states.shape170 # Reshape to (batch_size, num_channels, height, width)171 hidden_states = hidden_states.permute(0, 2, 1).reshape(batch_size, num_channels, height, width)172 # Apply sequence reduction173 hidden_states = self.sr(hidden_states)174 # Reshape back to (batch_size, seq_len, num_channels)175 hidden_states = hidden_states.reshape(batch_size, num_channels, -1).permute(0, 2, 1)176 hidden_states = self.layer_norm(hidden_states)177 178 key_layer = (179 self.key(hidden_states)180 .view(batch_size, -1, self.num_attention_heads, self.attention_head_size)181 .transpose(1, 2)182 )183 value_layer = (184 self.value(hidden_states)185 .view(batch_size, -1, self.num_attention_heads, self.attention_head_size)186 .transpose(1, 2)187 )188 189 # Take the dot product between "query" and "key" to get the raw attention scores.190 attention_scores = torch.matmul(query_layer, key_layer.transpose(-1, -2))191 192 attention_scores = attention_scores / math.sqrt(self.attention_head_size)193 194 # Normalize the attention scores to probabilities.195 attention_probs = nn.functional.softmax(attention_scores, dim=-1)196 197 # This is actually dropping out entire tokens to attend to, which might198 # seem a bit unusual, but is taken from the original Transformer paper.199 attention_probs = self.dropout(attention_probs)200 201 context_layer = torch.matmul(attention_probs, value_layer)202 203 context_layer = context_layer.permute(0, 2, 1, 3).contiguous()204 new_context_layer_shape = context_layer.size()[:-2] + (self.all_head_size,)205 context_layer = context_layer.view(new_context_layer_shape)206 207 outputs = (context_layer, attention_probs) if output_attentions else (context_layer,)208 209 return outputs210 211 212class SegformerSelfOutput(nn.Module):213 def __init__(self, config, hidden_size):214 super().__init__()215 self.dense = nn.Linear(hidden_size, hidden_size)216 self.dropout = nn.Dropout(config.hidden_dropout_prob)217 218 def forward(self, hidden_states, input_tensor):219 hidden_states = self.dense(hidden_states)220 hidden_states = self.dropout(hidden_states)221 return hidden_states222 223 224class SegformerAttention(nn.Module):225 def __init__(self, config, hidden_size, num_attention_heads, sequence_reduction_ratio):226 super().__init__()227 self.self = SegformerEfficientSelfAttention(228 config=config,229 hidden_size=hidden_size,230 num_attention_heads=num_attention_heads,231 sequence_reduction_ratio=sequence_reduction_ratio,232 )233 self.output = SegformerSelfOutput(config, hidden_size=hidden_size)234 self.pruned_heads = set()235 236 def prune_heads(self, heads):237 if len(heads) == 0:238 return239 heads, index = find_pruneable_heads_and_indices(240 heads, self.self.num_attention_heads, self.self.attention_head_size, self.pruned_heads241 )242 243 # Prune linear layers244 self.self.query = prune_linear_layer(self.self.query, index)245 self.self.key = prune_linear_layer(self.self.key, index)246 self.self.value = prune_linear_layer(self.self.value, index)247 self.output.dense = prune_linear_layer(self.output.dense, index, dim=1)248 249 # Update hyper params and store pruned heads250 self.self.num_attention_heads = self.self.num_attention_heads - len(heads)251 self.self.all_head_size = self.self.attention_head_size * self.self.num_attention_heads252 self.pruned_heads = self.pruned_heads.union(heads)253 254 def forward(self, hidden_states, height, width, output_attentions=False):255 self_outputs = self.self(hidden_states, height, width, output_attentions)256 257 attention_output = self.output(self_outputs[0], hidden_states)258 outputs = (attention_output,) + self_outputs[1:] # add attentions if we output them259 return outputs260 261 262class SegformerDWConv(nn.Module):263 def __init__(self, dim=768):264 super().__init__()265 self.dwconv = nn.Conv2d(dim, dim, 3, 1, 1, bias=True, groups=dim)266 267 def forward(self, hidden_states, height, width):268 batch_size, seq_len, num_channels = hidden_states.shape269 hidden_states = hidden_states.transpose(1, 2).view(batch_size, num_channels, height, width)270 hidden_states = self.dwconv(hidden_states)271 hidden_states = hidden_states.flatten(2).transpose(1, 2)272 273 return hidden_states274 275 276class SegformerMixFFN(nn.Module):277 def __init__(self, config, in_features, hidden_features=None, out_features=None):278 super().__init__()279 out_features = out_features or in_features280 self.dense1 = nn.Linear(in_features, hidden_features)281 self.dwconv = SegformerDWConv(hidden_features)282 if isinstance(config.hidden_act, str):283 self.intermediate_act_fn = ACT2FN[config.hidden_act]284 else:285 self.intermediate_act_fn = config.hidden_act286 self.dense2 = nn.Linear(hidden_features, out_features)287 self.dropout = nn.Dropout(config.hidden_dropout_prob)288 289 def forward(self, hidden_states, height, width):290 hidden_states = self.dense1(hidden_states)291 hidden_states = self.dwconv(hidden_states, height, width)292 hidden_states = self.intermediate_act_fn(hidden_states)293 hidden_states = self.dropout(hidden_states)294 hidden_states = self.dense2(hidden_states)295 hidden_states = self.dropout(hidden_states)296 return hidden_states297 298 299class SegformerLayer(nn.Module):300 """This corresponds to the Block class in the original implementation."""301 302 def __init__(self, config, hidden_size, num_attention_heads, drop_path, sequence_reduction_ratio, mlp_ratio):303 super().__init__()304 self.layer_norm_1 = nn.LayerNorm(hidden_size)305 self.attention = SegformerAttention(306 config,307 hidden_size=hidden_size,308 num_attention_heads=num_attention_heads,309 sequence_reduction_ratio=sequence_reduction_ratio,310 )311 self.drop_path = SegformerDropPath(drop_path) if drop_path > 0.0 else nn.Identity()312 self.layer_norm_2 = nn.LayerNorm(hidden_size)313 mlp_hidden_size = int(hidden_size * mlp_ratio)314 self.mlp = SegformerMixFFN(config, in_features=hidden_size, hidden_features=mlp_hidden_size)315 316 def forward(self, hidden_states, height, width, output_attentions=False):317 self_attention_outputs = self.attention(318 self.layer_norm_1(hidden_states), # in Segformer, layernorm is applied before self-attention319 height,320 width,321 output_attentions=output_attentions,322 )323 324 attention_output = self_attention_outputs[0]325 outputs = self_attention_outputs[1:] # add self attentions if we output attention weights326 327 # first residual connection (with stochastic depth)328 attention_output = self.drop_path(attention_output)329 hidden_states = attention_output + hidden_states330 331 mlp_output = self.mlp(self.layer_norm_2(hidden_states), height, width)332 333 # second residual connection (with stochastic depth)334 mlp_output = self.drop_path(mlp_output)335 layer_output = mlp_output + hidden_states336 337 outputs = (layer_output,) + outputs338 339 return outputs340 341 342class SegformerEncoder(nn.Module):343 def __init__(self, config):344 super().__init__()345 self.config = config346 347 # stochastic depth decay rule348 drop_path_decays = [349 x.item() for x in torch.linspace(0, config.drop_path_rate, sum(config.depths), device="cpu")350 ]351 352 # patch embeddings353 embeddings = []354 for i in range(config.num_encoder_blocks):355 embeddings.append(356 SegformerOverlapPatchEmbeddings(357 patch_size=config.patch_sizes[i],358 stride=config.strides[i],359 num_channels=config.num_channels if i == 0 else config.hidden_sizes[i - 1],360 hidden_size=config.hidden_sizes[i],361 )362 )363 self.patch_embeddings = nn.ModuleList(embeddings)364 365 # Transformer blocks366 blocks = []367 cur = 0368 for i in range(config.num_encoder_blocks):369 # each block consists of layers370 layers = []371 if i != 0:372 cur += config.depths[i - 1]373 for j in range(config.depths[i]):374 layers.append(375 SegformerLayer(376 config,377 hidden_size=config.hidden_sizes[i],378 num_attention_heads=config.num_attention_heads[i],379 drop_path=drop_path_decays[cur + j],380 sequence_reduction_ratio=config.sr_ratios[i],381 mlp_ratio=config.mlp_ratios[i],382 )383 )384 blocks.append(nn.ModuleList(layers))385 386 self.block = nn.ModuleList(blocks)387 388 # Layer norms389 self.layer_norm = nn.ModuleList(390 [nn.LayerNorm(config.hidden_sizes[i]) for i in range(config.num_encoder_blocks)]391 )392 393 def forward(394 self,395 pixel_values: torch.FloatTensor,396 output_attentions: Optional[bool] = False,397 output_hidden_states: Optional[bool] = False,398 return_dict: Optional[bool] = True,399 ) -> Union[tuple, BaseModelOutput]:400 all_hidden_states = () if output_hidden_states else None401 all_self_attentions = () if output_attentions else None402 403 batch_size = pixel_values.shape[0]404 405 hidden_states = pixel_values406 for idx, x in enumerate(zip(self.patch_embeddings, self.block, self.layer_norm)):407 embedding_layer, block_layer, norm_layer = x408 # first, obtain patch embeddings409 hidden_states, height, width = embedding_layer(hidden_states)410 # second, send embeddings through blocks411 for i, blk in enumerate(block_layer):412 layer_outputs = blk(hidden_states, height, width, output_attentions)413 hidden_states = layer_outputs[0]414 if output_attentions:415 all_self_attentions = all_self_attentions + (layer_outputs[1],)416 # third, apply layer norm417 hidden_states = norm_layer(hidden_states)418 # fourth, optionally reshape back to (batch_size, num_channels, height, width)419 if idx != len(self.patch_embeddings) - 1 or (420 idx == len(self.patch_embeddings) - 1 and self.config.reshape_last_stage421 ):422 hidden_states = hidden_states.reshape(batch_size, height, width, -1).permute(0, 3, 1, 2).contiguous()423 if output_hidden_states:424 all_hidden_states = all_hidden_states + (hidden_states,)425 426 if not return_dict:427 return tuple(v for v in [hidden_states, all_hidden_states, all_self_attentions] if v is not None)428 return BaseModelOutput(429 last_hidden_state=hidden_states,430 hidden_states=all_hidden_states,431 attentions=all_self_attentions,432 )433 434 435@auto_docstring436class SegformerPreTrainedModel(PreTrainedModel):437 config: SegformerConfig438 base_model_prefix = "segformer"439 main_input_name = "pixel_values"440 441 def _init_weights(self, module):442 """Initialize the weights"""443 if isinstance(module, (nn.Linear, nn.Conv2d)):444 # Slightly different from the TF version which uses truncated_normal for initialization445 # cf https://github.com/pytorch/pytorch/pull/5617446 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range)447 if module.bias is not None:448 module.bias.data.zero_()449 elif isinstance(module, nn.Embedding):450 module.weight.data.normal_(mean=0.0, std=self.config.initializer_range)451 if module.padding_idx is not None:452 module.weight.data[module.padding_idx].zero_()453 elif isinstance(module, (nn.LayerNorm, nn.BatchNorm2d)):454 module.bias.data.zero_()455 module.weight.data.fill_(1.0)456 457 458@auto_docstring459class SegformerModel(SegformerPreTrainedModel):460 def __init__(self, config):461 super().__init__(config)462 self.config = config463 464 # hierarchical Transformer encoder465 self.encoder = SegformerEncoder(config)466 467 # Initialize weights and apply final processing468 self.post_init()469 470 def _prune_heads(self, heads_to_prune):471 """472 Prunes heads of the model. heads_to_prune: dict of {layer_num: list of heads to prune in this layer} See base473 class PreTrainedModel474 """475 for layer, heads in heads_to_prune.items():476 self.encoder.layer[layer].attention.prune_heads(heads)477 478 @auto_docstring479 def forward(480 self,481 pixel_values: torch.FloatTensor,482 output_attentions: Optional[bool] = None,483 output_hidden_states: Optional[bool] = None,484 return_dict: Optional[bool] = None,485 ) -> Union[tuple, BaseModelOutput]:486 output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions487 output_hidden_states = (488 output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states489 )490 return_dict = return_dict if return_dict is not None else self.config.use_return_dict491 492 encoder_outputs = self.encoder(493 pixel_values,494 output_attentions=output_attentions,495 output_hidden_states=output_hidden_states,496 return_dict=return_dict,497 )498 sequence_output = encoder_outputs[0]499 500 if not return_dict:501 return (sequence_output,) + encoder_outputs[1:]502 503 return BaseModelOutput(504 last_hidden_state=sequence_output,505 hidden_states=encoder_outputs.hidden_states,506 attentions=encoder_outputs.attentions,507 )508 509 510@auto_docstring(511 custom_intro="""512 SegFormer Model transformer with an image classification head on top (a linear layer on top of the final hidden513 states) e.g. for ImageNet.514 """515)516class SegformerForImageClassification(SegformerPreTrainedModel):517 def __init__(self, config):518 super().__init__(config)519 520 self.num_labels = config.num_labels521 self.segformer = SegformerModel(config)522 523 # Classifier head524 self.classifier = nn.Linear(config.hidden_sizes[-1], config.num_labels)525 526 # Initialize weights and apply final processing527 self.post_init()528 529 @auto_docstring530 def forward(531 self,532 pixel_values: Optional[torch.FloatTensor] = None,533 labels: Optional[torch.LongTensor] = None,534 output_attentions: Optional[bool] = None,535 output_hidden_states: Optional[bool] = None,536 return_dict: Optional[bool] = None,537 ) -> Union[tuple, SegFormerImageClassifierOutput]:538 r"""539 labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*):540 Labels for computing the image classification/regression loss. Indices should be in `[0, ...,541 config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If542 `config.num_labels > 1` a classification loss is computed (Cross-Entropy).543 """544 return_dict = return_dict if return_dict is not None else self.config.use_return_dict545 546 outputs = self.segformer(547 pixel_values,548 output_attentions=output_attentions,549 output_hidden_states=output_hidden_states,550 return_dict=return_dict,551 )552 553 sequence_output = outputs[0]554 555 # convert last hidden states to (batch_size, height*width, hidden_size)556 batch_size = sequence_output.shape[0]557 if self.config.reshape_last_stage:558 # (batch_size, num_channels, height, width) -> (batch_size, height, width, num_channels)559 sequence_output = sequence_output.permute(0, 2, 3, 1)560 sequence_output = sequence_output.reshape(batch_size, -1, self.config.hidden_sizes[-1])561 562 # global average pooling563 sequence_output = sequence_output.mean(dim=1)564 565 logits = self.classifier(sequence_output)566 567 loss = None568 if labels is not None:569 loss = self.loss_function(labels, logits, self.config)570 571 if not return_dict:572 output = (logits,) + outputs[1:]573 return ((loss,) + output) if loss is not None else output574 575 return SegFormerImageClassifierOutput(576 loss=loss,577 logits=logits,578 hidden_states=outputs.hidden_states,579 attentions=outputs.attentions,580 )581 582 583class SegformerMLP(nn.Module):584 """585 Linear Embedding.586 """587 588 def __init__(self, config: SegformerConfig, input_dim):589 super().__init__()590 self.proj = nn.Linear(input_dim, config.decoder_hidden_size)591 592 def forward(self, hidden_states: torch.Tensor):593 hidden_states = hidden_states.flatten(2).transpose(1, 2)594 hidden_states = self.proj(hidden_states)595 return hidden_states596 597 598class SegformerDecodeHead(SegformerPreTrainedModel):599 def __init__(self, config):600 super().__init__(config)601 # linear layers which will unify the channel dimension of each of the encoder blocks to the same config.decoder_hidden_size602 mlps = []603 for i in range(config.num_encoder_blocks):604 mlp = SegformerMLP(config, input_dim=config.hidden_sizes[i])605 mlps.append(mlp)606 self.linear_c = nn.ModuleList(mlps)607 608 # the following 3 layers implement the ConvModule of the original implementation609 self.linear_fuse = nn.Conv2d(610 in_channels=config.decoder_hidden_size * config.num_encoder_blocks,611 out_channels=config.decoder_hidden_size,612 kernel_size=1,613 bias=False,614 )615 self.batch_norm = nn.BatchNorm2d(config.decoder_hidden_size)616 self.activation = nn.ReLU()617 618 self.dropout = nn.Dropout(config.classifier_dropout_prob)619 self.classifier = nn.Conv2d(config.decoder_hidden_size, config.num_labels, kernel_size=1)620 621 self.config = config622 623 def forward(self, encoder_hidden_states: torch.FloatTensor) -> torch.Tensor:624 batch_size = encoder_hidden_states[-1].shape[0]625 626 all_hidden_states = ()627 for encoder_hidden_state, mlp in zip(encoder_hidden_states, self.linear_c):628 if self.config.reshape_last_stage is False and encoder_hidden_state.ndim == 3:629 height = width = int(math.sqrt(encoder_hidden_state.shape[-1]))630 encoder_hidden_state = (631 encoder_hidden_state.reshape(batch_size, height, width, -1).permute(0, 3, 1, 2).contiguous()632 )633 634 # unify channel dimension635 height, width = encoder_hidden_state.shape[2], encoder_hidden_state.shape[3]636 encoder_hidden_state = mlp(encoder_hidden_state)637 encoder_hidden_state = encoder_hidden_state.permute(0, 2, 1)638 encoder_hidden_state = encoder_hidden_state.reshape(batch_size, -1, height, width)639 # upsample640 encoder_hidden_state = nn.functional.interpolate(641 encoder_hidden_state, size=encoder_hidden_states[0].size()[2:], mode="bilinear", align_corners=False642 )643 all_hidden_states += (encoder_hidden_state,)644 645 hidden_states = self.linear_fuse(torch.cat(all_hidden_states[::-1], dim=1))646 hidden_states = self.batch_norm(hidden_states)647 hidden_states = self.activation(hidden_states)648 hidden_states = self.dropout(hidden_states)649 650 # logits are of shape (batch_size, num_labels, height/4, width/4)651 logits = self.classifier(hidden_states)652 653 return logits654 655 656@auto_docstring(657 custom_intro="""658 SegFormer Model transformer with an all-MLP decode head on top e.g. for ADE20k, CityScapes.659 """660)661class SegformerForSemanticSegmentation(SegformerPreTrainedModel):662 def __init__(self, config):663 super().__init__(config)664 self.segformer = SegformerModel(config)665 self.decode_head = SegformerDecodeHead(config)666 667 # Initialize weights and apply final processing668 self.post_init()669 670 @auto_docstring671 def forward(672 self,673 pixel_values: torch.FloatTensor,674 labels: Optional[torch.LongTensor] = None,675 output_attentions: Optional[bool] = None,676 output_hidden_states: Optional[bool] = None,677 return_dict: Optional[bool] = None,678 ) -> Union[tuple, SemanticSegmenterOutput]:679 r"""680 labels (`torch.LongTensor` of shape `(batch_size, height, width)`, *optional*):681 Ground truth semantic segmentation maps for computing the loss. Indices should be in `[0, ...,682 config.num_labels - 1]`. If `config.num_labels > 1`, a classification loss is computed (Cross-Entropy).683 684 Examples:685 686 ```python687 >>> from transformers import AutoImageProcessor, SegformerForSemanticSegmentation688 >>> from PIL import Image689 >>> import requests690 691 >>> image_processor = AutoImageProcessor.from_pretrained("nvidia/segformer-b0-finetuned-ade-512-512")692 >>> model = SegformerForSemanticSegmentation.from_pretrained("nvidia/segformer-b0-finetuned-ade-512-512")693 694 >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg"695 >>> image = Image.open(requests.get(url, stream=True).raw)696 697 >>> inputs = image_processor(images=image, return_tensors="pt")698 >>> outputs = model(**inputs)699 >>> logits = outputs.logits # shape (batch_size, num_labels, height/4, width/4)700 >>> list(logits.shape)701 [1, 150, 128, 128]702 ```"""703 return_dict = return_dict if return_dict is not None else self.config.use_return_dict704 output_hidden_states = (705 output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states706 )707 708 if labels is not None and self.config.num_labels < 1:709 raise ValueError(f"Number of labels should be >=0: {self.config.num_labels}")710 711 outputs = self.segformer(712 pixel_values,713 output_attentions=output_attentions,714 output_hidden_states=True, # we need the intermediate hidden states715 return_dict=return_dict,716 )717 718 encoder_hidden_states = outputs.hidden_states if return_dict else outputs[1]719 720 logits = self.decode_head(encoder_hidden_states)721 722 loss = None723 if labels is not None:724 # upsample logits to the images' original size725 upsampled_logits = nn.functional.interpolate(726 logits, size=labels.shape[-2:], mode="bilinear", align_corners=False727 )728 if self.config.num_labels > 1:729 loss_fct = CrossEntropyLoss(ignore_index=self.config.semantic_loss_ignore_index)730 loss = loss_fct(upsampled_logits, labels)731 elif self.config.num_labels == 1:732 valid_mask = ((labels >= 0) & (labels != self.config.semantic_loss_ignore_index)).float()733 loss_fct = BCEWithLogitsLoss(reduction="none")734 loss = loss_fct(upsampled_logits.squeeze(1), labels.float())735 loss = (loss * valid_mask).mean()736 737 if not return_dict:738 if output_hidden_states:739 output = (logits,) + outputs[1:]740 else:741 output = (logits,) + outputs[2:]742 return ((loss,) + output) if loss is not None else output743 744 return SemanticSegmenterOutput(745 loss=loss,746 logits=logits,747 hidden_states=outputs.hidden_states if output_hidden_states else None,748 attentions=outputs.attentions,749 )750 751 752__all__ = [753 "SegformerDecodeHead",754 "SegformerForImageClassification",755 "SegformerForSemanticSegmentation",756 "SegformerLayer",757 "SegformerModel",758 "SegformerPreTrainedModel",759]760 