class_docstr: Create a U-Net from a given architecture.
code: def __init__(
      self,
      encoder,
      n_out,
      img_size,
      blur=False,
      blur_final=True,
      self_attention=False,
      y_range=None,
      last_cross=True,
      bottle=False,
      act_cls=defaults.activation,
      init=nn.init.kaiming_normal_,
      norm_type=None,
      **kwargs,
  ):
      imsize = img_size
      sizes = model_sizes(encoder, size=imsize)
      sz_chg_idxs = list(reversed(_get_sz_change_idxs(sizes)))
      self.sfs = hook_outputs(
          [encoder[i] for i in sz_chg_idxs], detach=False
      )
      x = dummy_eval(encoder, imsize).detach()
  
      ni = sizes[-1][1]
      middle_conv = nn.Sequential(
          ConvLayer(
              ni, ni * 2, act_cls=act_cls, norm_type=norm_type, **kwargs
          ),
          ConvLayer(
              ni * 2, ni, act_cls=act_cls, norm_type=norm_type, **kwargs
          ),
      ).eval()
      x = middle_conv(x)
      layers = [encoder, BatchNorm(ni), nn.ReLU(), middle_conv]
  
      for i, idx in enumerate(sz_chg_idxs):
          not_final = i != len(sz_chg_idxs) - 1
          up_in_c, x_in_c = int(x.shape[1]), int(sizes[idx][1])
          do_blur = blur and (not_final or blur_final)
          sa = self_attention and (i == len(sz_chg_idxs) - 3)
          unet_block = UnetBlock(
              up_in_c,
              x_in_c,
              self.sfs[i],
              final_div=not_final,
              blur=do_blur,
              self_attention=sa,
              act_cls=act_cls,
              init=init,
              norm_type=norm_type,
              **kwargs,
          ).eval()
          layers.append(unet_block)
          x = unet_block(x)
  
      ni = x.shape[1]
      if imsize != sizes[0][-2:]:
          layers.append(
              PixelShuffle_ICNR(
                  ni, act_cls=act_cls, norm_type=norm_type
              )
          )
      layers.append(ResizeToOrig())
      if last_cross:
          layers.append(MergeLayer(dense=True))
          ni += in_channels(encoder)
          layers.append(
              ResBlock(
                  1,
                  ni,
                  ni // 2 if bottle else ni,
                  act_cls=act_cls,
                  norm_type=norm_type,
                  **kwargs,
              )
          )
      layers += [
          ConvLayer(
              ni,
              n_out,
              ks=1,
              act_cls=None,
              norm_type=norm_type,
              **kwargs,
          )
      ]
      apply_init(nn.Sequential(layers[3], layers[-2]), init)
      # apply_init(nn.Sequential(layers[2]), init)
      if y_range is not None:
          layers.append(SigmoidRange(*y_range))
      layers.append(ToTensorBase())
      super().__init__(*layers)
  
file_path: fastai/fastai/vision/models/unet.py
imports: from __future__ import annotations
  from ...torch_basics import *
  from ...callback.hook import *
label_desc: Use image node_id 1 to create a new DynamicUnet object from inherited base classes: SequentialEx with example: obj = DynamicUnet(encoder, n_out, img_size, blur, blur_final, _attention, y_range, last_cross, bottle, act_cls, init, norm_type)