class_docstr: ### Description
     The network estimates dense displacement fields from a pair
     of moving and fixed images:
  
         Hu et al., Label-driven weakly-supervised learning for
         multimodal deformable image registration, arXiv:1711.01666
         https://arxiv.org/abs/1711.01666
  
         Hu et al., Weakly-Supervised Convolutional Neural Networks for
         Multimodal Image Registration, Medical Image Analysis (2018)
         https://doi.org/10.1016/j.media.2018.07.002
  
     see also:
         https://github.com/YipengHu/label-reg
  
  ### Building blocks
  [DOWN CONV]         - Convolutional layer + Residual Unit + Downsampling (Max pooling)
  [CONV]              - Convolutional layer
  [UP CONV]           - Upsampling + Sum + Residual Unit
  [FUSION]            - Multi-scale displacement fields fusion
  [DISPtoDEF]         - (Smoothing if required) Conversion to deformation field (adding base grid)
  
  
  ### Diagram
  INPUT PAIR -->  [DOWN CONV]              [UP CONV] --> [CONV] --[FUSION] --> [DISPtoDEF] --> DENSE FIELD
                      |                        |                     |
                  [DOWN CONV]              [UP CONV] --> [CONV] -----|
                      |                        |                     |
                  [DOWN CONV]              [UP CONV] --> [CONV] -----|
                      |                        |                     |
                  [DOWN CONV]              [UP CONV] --> [CONV] -----|
                       |                       |                     |
                       -------- [CONV]------------------ [CONV]-------
  
  
  ### Constraints
     - input spatial rank should be either 2 or 3 (2D or 3D images only)
     - fixed image size should be divisible by 16
docstr: :param decay: float, regularisation decay
  :param smoothing: float, smoothing factor for dense displacement field
  :param disp_w_initializer: initialisation of the displacement fields
  :param disp_b_initializer: initialisation of the displacement fields
  :param acti_func: activation function to use
  :param multi_scale_fusion: True/False indicating whether to use
      multiscale feature fusion.
  :param name: layer name
docstr_tok: [":","param","decay",":","float",",","regularisation","decay",":","param","smoothing",":","float",",","smoothing","factor","for","dense","displacement","field",":","param","disp_w_initializer",":","initialisation","of","the","displacement","fields",":","param","disp_b_initializer",":","initialisation","of","the","displacement","fields",":","param","acti_func",":","activation","function","to","use",":","param","multi_scale_fusion",":","True\/False","indicating","whether","to","use","multiscale","feature","fusion",".",":","param","name",":","layer","name"]
code: def __init__(
      self,
      decay=0.0,
      smoothing=0,
      disp_w_initializer=None,
      disp_b_initializer=None,
      acti_func="relu",
      multi_scale_fusion=True,
      name="inet-dense",
  ):
      """
  
      :param decay: float, regularisation decay
      :param smoothing: float, smoothing factor for dense displacement field
      :param disp_w_initializer: initialisation of the displacement fields
      :param disp_b_initializer: initialisation of the displacement fields
      :param acti_func: activation function to use
      :param multi_scale_fusion: True/False indicating whether to use
          multiscale feature fusion.
      :param name: layer name
      """
      BaseNet.__init__(self, name=name)
  
      # self.fea = [40, 80, 160, 320, 640]
      # self.fea = [32, 64, 128, 256, 512]
      self.fea = [30, 60, 120, 240, 480]
      # self.fea = [16, 32, 64, 128, 256]
      self.k_conv = 3
      self.multi_scale_fusion = multi_scale_fusion
  
      self.down_res_param = {
          "w_initializer": GlorotUniform.get_instance(""),
          "w_regularizer": regularizers.l2_regularizer(decay),
          "acti_func": acti_func,
      }
  
      self.up_res_param = {
          "acti_func": acti_func,
          "w_initializer": GlorotUniform.get_instance(""),
          "w_regularizer": regularizers.l2_regularizer(decay),
          "is_residual_upsampling": True,
          "type_string": "bn_acti_conv",
      }
  
      # displacement initialiser & regulariser
      if disp_w_initializer is None:
          disp_b_initializer = tf.constant_initializer(0.0)
          # disp_w_initializer = tf.random_normal_initializer(0, 1e-4)
      if disp_b_initializer is None:
          disp_b_initializer = tf.constant_initializer(0.0)
          # disp_w_initializer = tf.random_normal_initializer(0, 0.0)
      self.disp_param = {
          "w_initializer": disp_w_initializer,
          "w_regularizer": regularizers.l2_regularizer(decay),
          "b_initializer": disp_b_initializer,
          "b_regularizer": None,
      }
  
      if smoothing > 0:
          self.smoothing_func = _smoothing_func(smoothing)
      else:
          self.smoothing_func = None
  
imports: from __future__ import absolute_import, print_function
  import numpy
  import tensorflow
  from tensorflow.contrib.layers.python.layers import regularizers
  from niftynet.engine.application_initializer import GlorotUniform
  from niftynet.layer.convolution import ConvolutionalLayer
  from niftynet.layer.downsample_res_block import DownBlock
  from niftynet.layer.grid_warper import _create_affine_features
  from niftynet.layer.layer_util import infer_spatial_rank, check_spatial_dims
  from niftynet.layer.linear_resize import LinearResizeLayer
  from niftynet.layer.spatial_gradient import SpatialGradientLayer
  from niftynet.layer.upsample_res_block import UpBlock
  from niftynet.network.base_net import BaseNet
label_desc: Use image node_id 1 to create a new INetDense object from inherited base classes: BaseNet with example: obj = INetDense(decay, smoothing, disp_w_initializer, disp_b_initializer, acti_func, multi_scale_fusion, name)