class_docstr: LinkNet as described in `"LinkNet: Exploiting Encoder Representations for Efficient Semantic Segmentation"
  <https://arxiv.org/pdf/1707.03718.pdf>`_.
  
  Args:
  ----
      feature extractor: the backbone serving as feature extractor
      fpn_channels: number of channels each extracted feature maps is mapped to
      assume_straight_pages: if True, fit straight bounding boxes only
      exportable: onnx exportable returns only logits
      cfg: the configuration dict of the model
      class_names: list of class names
class_docstr_tok: ["LinkNet","as","described","in","`","``","LinkNet",":","Exploiting","Encoder","Representations","for","Efficient","Semantic","Segmentation","''","<","https",":","\/\/arxiv.org\/pdf\/1707.03718.pdf",">","`","_",".","Args",":","--","--","feature","extractor",":","the","backbone","serving","as","feature","extractor","fpn_channels",":","number","of","channels","each","extracted","feature","maps","is","mapped","to","assume_straight_pages",":","if","True",",","fit","straight","bounding","boxes","only","exportable",":","onnx","exportable","returns","only","logits","cfg",":","the","configuration","dict","of","the","model","class_names",":","list","of","class","names"]
code: def __init__(
      self,
      feat_extractor: IntermediateLayerGetter,
      fpn_channels: int = 64,
      bin_thresh: float = 0.1,
      assume_straight_pages: bool = True,
      exportable: bool = False,
      cfg: Optional[Dict[str, Any]] = None,
      class_names: List[str] = [CLASS_NAME],
  ) -> None:
      super().__init__(cfg=cfg)
  
      self.class_names = class_names
      num_classes: int = len(self.class_names)
  
      self.exportable = exportable
      self.assume_straight_pages = assume_straight_pages
  
      self.feat_extractor = feat_extractor
  
      self.fpn = LinkNetFPN(
          fpn_channels,
          [_shape[1:] for _shape in self.feat_extractor.output_shape],
      )
      self.fpn.build(self.feat_extractor.output_shape)
  
      self.classifier = Sequential(
          [
              layers.Conv2DTranspose(
                  filters=32,
                  kernel_size=3,
                  strides=2,
                  padding="same",
                  use_bias=False,
                  kernel_initializer="he_normal",
                  input_shape=self.fpn.decoders[-1].output_shape[1:],
              ),
              layers.BatchNormalization(),
              layers.Activation("relu"),
              *conv_sequence(
                  32, "relu", True, kernel_size=3, strides=1
              ),
              layers.Conv2DTranspose(
                  filters=num_classes,
                  kernel_size=2,
                  strides=2,
                  padding="same",
                  use_bias=True,
                  kernel_initializer="he_normal",
              ),
          ]
      )
  
      self.postprocessor = LinkNetPostProcessor(
          assume_straight_pages=assume_straight_pages,
          bin_thresh=bin_thresh,
      )
  
imports: from copy import deepcopy
  from typing import Any, Dict, List, Optional, Tuple
  import numpy
  import tensorflow
  from tensorflow import keras
  from tensorflow.keras import Model, Sequential, layers
  from doctr.file_utils import CLASS_NAME
  from doctr.models.classification import resnet18, resnet34, resnet50
  from doctr.models.utils import IntermediateLayerGetter, _bf16_to_float32, conv_sequence, load_pretrained_params
  from doctr.utils.repr import NestedObject
  from .base import LinkNetPostProcessor, _LinkNet
label_desc: Use image node_id 1 to create a new LinkNet object from inherited base classes: _LinkNet, keras with example: obj = LinkNet(feat_extractor, fpn_channels, bin_thresh, assume_straight_pages, exportable, cfg, class_names)