parameters: (nb_features,
               input_shape,
               nb_levels,
               conv_size,
               nb_labels,
               name=None,
               prefix=None,
               feat_mult=1,
               pool_size=2,
               use_skip_connections=False,
               padding='same',
               dilation_rate_mult=1,
               activation='elu',
               use_residuals=False,
               final_pred_activation='softmax',
               nb_conv_per_level=2,
               layer_nb_feats=None,
               batch_norm=None,
               conv_dropout=0,
               input_model=None)
return_statement: return model
docstring: Fully Convolutional Decoder
  
      Parameters:
          ...
          use_skip_connections (bool): if true, turns an Enc-Dec to a U-Net.
              If true, input_tensor and tensors are required.
              It assumes a particular naming of layers. conv_enc...
docstring_summary: Fully Convolutional Decoder
docstring_tokens: Fully Convolutional Decoder
function: def conv_dec(nb_features,
               input_shape,
               nb_levels,
               conv_size,
               nb_labels,
               name=None,
               prefix=None,
               feat_mult=1,
               pool_size=2,
               use_skip_connections=False,
               padding='same',
               dilation_rate_mult=1,
               activation='elu',
               use_residuals=False,
               final_pred_activation='softmax',
               nb_conv_per_level=2,
               layer_nb_feats=None,
               batch_norm=None,
               conv_dropout=0,
               input_model=None):
      """
      Fully Convolutional Decoder
  
      Parameters:
          ...
          use_skip_connections (bool): if true, turns an Enc-Dec to a U-Net.
              If true, input_tensor and tensors are required.
              It assumes a particular naming of layers. conv_enc...
      """
  
      # naming
      model_name = name
      if prefix is None:
          prefix = model_name
  
      # if using skip connections, make sure need to use them.
      if use_skip_connections:
          assert input_model is not None, "is using skip connections, tensors dictionary is required"
  
      # first layer: input
      input_name = '%s_input' % prefix
      if input_model is None:
          input_tensor = KL.Input(shape=input_shape, name=input_name)
          last_tensor = input_tensor
      else:
          input_tensor = input_model.input
          last_tensor = input_model.output
          input_shape = last_tensor.shape.as_list()[1:]
  
      # vol size info
      ndims = len(input_shape) - 1
      input_shape = tuple(input_shape)
      if isinstance(pool_size, int):
          pool_size = (pool_size,) * ndims
  
      # prepare layers
      convL = getattr(KL, 'Conv%dD' % ndims)
      conv_kwargs = {'padding': padding, 'activation': activation}
      upsample = getattr(KL, 'UpSampling%dD' % ndims)
  
      # up arm:
      # nb_levels - 1 layers of Deconvolution3D
      #    (approx via up + conv + ReLu) + merge + conv + ReLu + conv + ReLu
      lfidx = 0
      for level in range(nb_levels - 1):
          nb_lvl_feats = np.round(nb_features*feat_mult**(nb_levels-2-level)).astype(int)
          conv_kwargs['dilation_rate'] = dilation_rate_mult**(nb_levels-2-level)
  
          # upsample matching the max pooling layers size
          name = '%s_up_%d' % (prefix, nb_levels + level)
          last_tensor = upsample(size=pool_size, name=name)(last_tensor)
          up_tensor = last_tensor
  
          # merge layers combining previous layer
          # TODO: add Cropping3D or Cropping2D if 'valid' padding
          if use_skip_connections:
              conv_name = '%s_conv_downarm_%d_%d' % (prefix, nb_levels - 2 - level, nb_conv_per_level - 1)
              cat_tensor = input_model.get_layer(conv_name).output
              name = '%s_merge_%d' % (prefix, nb_levels + level)
              last_tensor = KL.concatenate([cat_tensor, last_tensor], axis=ndims+1, name=name)
  
          # convolution layers
          for conv in range(nb_conv_per_level):
              if layer_nb_feats is not None:
                  nb_lvl_feats = layer_nb_feats[lfidx]
                  lfidx += 1
  
              name = '%s_conv_uparm_%d_%d' % (prefix, nb_levels + level, conv)
              if conv < (nb_conv_per_level-1) or (not use_residuals):
                  last_tensor = convL(nb_lvl_feats, conv_size, **conv_kwargs, name=name)(last_tensor)
              else:
                  last_tensor = convL(nb_lvl_feats, conv_size, padding=padding, name=name)(last_tensor)
  
              if conv_dropout > 0:
                  name = '%s_dropout_uparm_%d_%d' % (prefix, level, conv)
                  noise_shape = [None, *[1]*ndims, nb_lvl_feats]
                  last_tensor = KL.Dropout(conv_dropout, noise_shape=noise_shape)(last_tensor)
  
          # residual block
          if use_residuals:
  
              # the "add" layer is the original input
              # However, it may not have the right number of features to be added
              add_layer = up_tensor
              nb_feats_in = add_layer.get_shape()[-1]
              nb_feats_out = last_tensor.get_shape()[-1]
              if nb_feats_in > 1 and nb_feats_out > 1 and (nb_feats_in != nb_feats_out):
                  name = '%s_expand_up_merge_%d' % (prefix, level)
                  add_layer = convL(nb_lvl_feats, conv_size, **conv_kwargs, name=name)(add_layer)
  
                  if conv_dropout > 0:
                      name = '%s_dropout_up_merge_%d_%d' % (prefix, level, conv)
                      noise_shape = [None, *[1]*ndims, nb_lvl_feats]
                      last_tensor = KL.Dropout(conv_dropout, noise_shape=noise_shape)(last_tensor)
  
              name = '%s_res_up_merge_%d' % (prefix, level)
              last_tensor = KL.add([last_tensor, add_layer], name=name)
  
              name = '%s_res_up_merge_act_%d' % (prefix, level)
              last_tensor = KL.Activation(activation, name=name)(last_tensor)
  
          if batch_norm is not None:
              name = '%s_bn_up_%d' % (prefix, level)
              last_tensor = KL.BatchNormalization(axis=batch_norm, name=name)(last_tensor)
  
      # Compute likelyhood prediction (no activation yet)
      name = '%s_likelihood' % prefix
      last_tensor = convL(nb_labels, 1, activation=None, name=name)(last_tensor)
      like_tensor = last_tensor
  
      # output prediction layer
      # we use a softmax to compute P(L_x|I) where x is each location
      if final_pred_activation == 'softmax':
          print("using final_pred_activation %s for %s" % (final_pred_activation, model_name))
          name = '%s_prediction' % prefix
          softmax_lambda_fcn = lambda x: keras.activations.softmax(x, axis=ndims + 1)
          pred_tensor = KL.Lambda(softmax_lambda_fcn, name=name)(last_tensor)
  
      # otherwise create a layer that does nothing.
      else:
          name = '%s_prediction' % prefix
          pred_tensor = KL.Activation('linear', name=name)(like_tensor)
  
      # create the model and retun
      model = Model(inputs=input_tensor, outputs=pred_tensor, name=model_name)
      return model
function_tokens: def conv_dec ( nb_features , input_shape , nb_levels , conv_size , nb_labels , name = None , prefix = None , feat_mult = 1 , pool_size = 2 , use_skip_connections = False , padding = 'same' , dilation_rate_mult = 1 , activation = 'elu' , use_residuals = False , final_pred_activation = 'softmax' , nb_conv_per_level = 2 , layer_nb_feats = None , batch_norm = None , conv_dropout = 0 , input_model = None ) : # naming model_name = name if prefix is None : prefix = model_name # if using skip connections, make sure need to use them. if use_skip_connections : assert input_model is not None , "is using skip connections, tensors dictionary is required" # first layer: input input_name = '%s_input' % prefix if input_model is None : input_tensor = KL . Input ( shape = input_shape , name = input_name ) last_tensor = input_tensor else : input_tensor = input_model . input last_tensor = input_model . output input_shape = last_tensor . shape . as_list ( ) [ 1 : ] # vol size info ndims = len ( input_shape ) - 1 input_shape = tuple ( input_shape ) if isinstance ( pool_size , int ) : pool_size = ( pool_size , ) * ndims # prepare layers convL = getattr ( KL , 'Conv%dD' % ndims ) conv_kwargs = { 'padding' : padding , 'activation' : activation } upsample = getattr ( KL , 'UpSampling%dD' % ndims ) # up arm: # nb_levels - 1 layers of Deconvolution3D #    (approx via up + conv + ReLu) + merge + conv + ReLu + conv + ReLu lfidx = 0 for level in range ( nb_levels - 1 ) : nb_lvl_feats = np . round ( nb_features * feat_mult ** ( nb_levels - 2 - level ) ) . astype ( int ) conv_kwargs [ 'dilation_rate' ] = dilation_rate_mult ** ( nb_levels - 2 - level ) # upsample matching the max pooling layers size name = '%s_up_%d' % ( prefix , nb_levels + level ) last_tensor = upsample ( size = pool_size , name = name ) ( last_tensor ) up_tensor = last_tensor # merge layers combining previous layer # TODO: add Cropping3D or Cropping2D if 'valid' padding if use_skip_connections : conv_name = '%s_conv_downarm_%d_%d' % ( prefix , nb_levels - 2 - level , nb_conv_per_level - 1 ) cat_tensor = input_model . get_layer ( conv_name ) . output name = '%s_merge_%d' % ( prefix , nb_levels + level ) last_tensor = KL . concatenate ( [ cat_tensor , last_tensor ] , axis = ndims + 1 , name = name ) # convolution layers for conv in range ( nb_conv_per_level ) : if layer_nb_feats is not None : nb_lvl_feats = layer_nb_feats [ lfidx ] lfidx += 1 name = '%s_conv_uparm_%d_%d' % ( prefix , nb_levels + level , conv ) if conv < ( nb_conv_per_level - 1 ) or ( not use_residuals ) : last_tensor = convL ( nb_lvl_feats , conv_size , * * conv_kwargs , name = name ) ( last_tensor ) else : last_tensor = convL ( nb_lvl_feats , conv_size , padding = padding , name = name ) ( last_tensor ) if conv_dropout > 0 : name = '%s_dropout_uparm_%d_%d' % ( prefix , level , conv ) noise_shape = [ None , * [ 1 ] * ndims , nb_lvl_feats ] last_tensor = KL . Dropout ( conv_dropout , noise_shape = noise_shape ) ( last_tensor ) # residual block if use_residuals : # the "add" layer is the original input # However, it may not have the right number of features to be added add_layer = up_tensor nb_feats_in = add_layer . get_shape ( ) [ - 1 ] nb_feats_out = last_tensor . get_shape ( ) [ - 1 ] if nb_feats_in > 1 and nb_feats_out > 1 and ( nb_feats_in != nb_feats_out ) : name = '%s_expand_up_merge_%d' % ( prefix , level ) add_layer = convL ( nb_lvl_feats , conv_size , * * conv_kwargs , name = name ) ( add_layer ) if conv_dropout > 0 : name = '%s_dropout_up_merge_%d_%d' % ( prefix , level , conv ) noise_shape = [ None , * [ 1 ] * ndims , nb_lvl_feats ] last_tensor = KL . Dropout ( conv_dropout , noise_shape = noise_shape ) ( last_tensor ) name = '%s_res_up_merge_%d' % ( prefix , level ) last_tensor = KL . add ( [ last_tensor , add_layer ] , name = name ) name = '%s_res_up_merge_act_%d' % ( prefix , level ) last_tensor = KL . Activation ( activation , name = name ) ( last_tensor ) if batch_norm is not None : name = '%s_bn_up_%d' % ( prefix , level ) last_tensor = KL . BatchNormalization ( axis = batch_norm , name = name ) ( last_tensor ) # Compute likelyhood prediction (no activation yet) name = '%s_likelihood' % prefix last_tensor = convL ( nb_labels , 1 , activation = None , name = name ) ( last_tensor ) like_tensor = last_tensor # output prediction layer # we use a softmax to compute P(L_x|I) where x is each location if final_pred_activation == 'softmax' : print ( "using final_pred_activation %s for %s" % ( final_pred_activation , model_name ) ) name = '%s_prediction' % prefix softmax_lambda_fcn = lambda x : keras . activations . softmax ( x , axis = ndims + 1 ) pred_tensor = KL . Lambda ( softmax_lambda_fcn , name = name ) ( last_tensor ) # otherwise create a layer that does nothing. else : name = '%s_prediction' % prefix pred_tensor = KL . Activation ( 'linear' , name = name ) ( like_tensor ) # create the model and retun model = Model ( inputs = input_tensor , outputs = pred_tensor , name = model_name ) return model