def myDenseNetv2Dropout(input_shape, dropout_rate=0.3): """ """ bn_axis = -1 if K.image_data_format() == 'channels_last' else 1 input_tensor = Input(shape=input_shape) #48, 240, 360, 1 x = Conv3D(16, (3, 3, 3), strides=(1, 2, 2), use_bias=False, padding='same', name='block0_conv1')(input_tensor) #[48, 120, 180] x = BatchNormalization(axis=bn_axis, epsilon=1.001e-5, name='block0_bn1')(x) x = Activation('relu', name='block0_relu1')(x) x = Conv3D(16, (3, 3, 3), strides=(1, 1, 1), use_bias=False, padding='same', name='block0_conv2')(x) #[48, 120, 180] x = _denseBlock(x, [16, 16], 'block_11') #[48, 120, 180] x = _transit_block(x, 16, 'block13') #[48, 120, 180] x = SpatialDropout3D(dropout_rate)(x) x = MaxPooling3D((2, 2, 2), strides=(2, 2, 2), padding='same')(x) #[24, 60, 90] x = _denseBlock(x, [24, 24, 24], 'block_21') #[24, 60, 90] x = _transit_block(x, 24, 'block23') #[24, 60, 90] x = SpatialDropout3D(dropout_rate)(x) x = MaxPooling3D((2, 2, 2), strides=(2, 2, 2), padding='same')(x) #[12, 30, 45] x = _denseBlock(x, [32, 32, 32, 32], 'block_31') #[12, 30, 45] x = SpatialDropout3D(dropout_rate)(x) x = MaxPooling3D((2, 2, 2), strides=(2, 2, 2), padding='same')(x) #[6, 15, 23] x = BatchNormalization(axis=bn_axis, epsilon=1.001e-5, name='block_final_bn')(x) x = Activation('relu', name='block_final_relu')(x) ##############above are bae#################### x = _denseBlock(x, [32, 32], 'EGFR_block_11') x = MaxPooling3D((1, 2, 2), strides=(1, 2, 2), padding='same')(x) #[6, 8, 12, 64] x = SpatialDropout3D(dropout_rate)(x) x = _transit_block(x, 64, 'EGFR_block_12') #[6, 8, 12, 64] x = GlobalAveragePooling3D()(x) x = Dense(1, activation='sigmoid', name='EGFR_global_pred')(x) # create model model = Model(input_tensor, x, name='myDense') plot_model(model, 'myDenseNetv2.png', show_shapes=True) return model
def __init__(self, modelnet, args): # TODO: Define a suitable model, and either `.compile` it, or prepare # optimizer and loss manually. inp = Input(shape=(modelnet.H, modelnet.W, modelnet.D, modelnet.C)) hidden = Conv3D(24, (3,3,3), activation=None, padding='same')(inp) hidden = SpatialDropout3D(0.4)(hidden) hidden = BatchNormalization()(hidden) hidden = Activation(tf.nn.relu)(hidden) hidden = Conv3D(24, (3,3,3), activation=None, padding='same')(hidden) hidden = SpatialDropout3D(0.4)(hidden) hidden = BatchNormalization()(hidden) hidden = Activation(tf.nn.relu)(hidden) hidden = MaxPooling3D((2,2,2))(hidden) hidden = Conv3D(48, (3,3,3), activation=None)(hidden) hidden = BatchNormalization()(hidden) hidden = Activation(tf.nn.relu)(hidden) hidden = Conv3D(48, (3,3,3), activation=None)(hidden) hidden = BatchNormalization()(hidden) hidden = Activation(tf.nn.relu)(hidden) hidden = MaxPooling3D((2,2,2))(hidden) hidden = Conv3D(96, (3,3,3), activation=None)(hidden) hidden = BatchNormalization()(hidden) hidden = Activation(tf.nn.relu)(hidden) hidden = Conv3D(96, (3,3,3), activation=None)(hidden) hidden = BatchNormalization()(hidden) hidden = Activation(tf.nn.relu)(hidden) hidden = MaxPooling3D((2,2,2))(hidden) hidden = GlobalAveragePooling3D()(hidden) output = Dense(len(modelnet.LABELS), activation=tf.nn.softmax)(hidden) self.model = tf.keras.Model(inputs=inp, outputs=output) self.model.compile( optimizer=tf.optimizers.Adam(), loss=tf.losses.SparseCategoricalCrossentropy(), metrics=[tf.metrics.SparseCategoricalAccuracy(name="accuracy")] ) self.tb_callback=tf.keras.callbacks.TensorBoard(args.logdir, update_freq=1000, profile_batch=1) self.tb_callback.on_train_end = lambda *_: None
def up_stage(inputs, skip, filters, kernel_size=3, activation="relu", padding="SAME"): up = UpSampling3D()(inputs) up = Conv3D(filters, 2, activation=activation, padding=padding)(up) up = GroupNormalization()(up) merge = concatenate([skip, up]) merge = GroupNormalization()(merge) convu = Conv3D(filters, kernel_size, activation=activation, padding=padding)(merge) convu = GroupNormalization()(convu) convu = Conv3D(filters, kernel_size, activation=activation, padding=padding)(convu) convu = GroupNormalization()(convu) convu = SpatialDropout3D(0.5)(convu, training=True) return convu
def create_context_module(input_layer, n_level_filters, dropout_rate=0.3, data_format="channels_last"): layer1 = ReflectionPadding3D()(input_layer) convolution1 = create_convolution_block(input_layer=layer1, n_filters=n_level_filters) dropout = SpatialDropout3D(rate=dropout_rate, data_format=data_format)(convolution1) layer2 = ReflectionPadding3D()(dropout) convolution2 = create_convolution_block(input_layer=layer2, n_filters=n_level_filters) return convolution2
def _conv_block(x, filters): bn_scale = PARAMS['bn_scale'] activation = PARAMS['activation'] kernel_initializer = PARAMS['kernel_initializer'] weight_decay = PARAMS['weight_decay'] bottleneck = PARAMS['bottleneck'] dropout_rate = PARAMS['dropout_rate'] x = BatchNormalization(scale=bn_scale, axis=-1)(x) x = activation()(x) x = Conv3D(filters * bottleneck, kernel_size=(1, 1, 1), padding='same', use_bias=False, kernel_initializer=kernel_initializer, kernel_regularizer=l2_penalty(weight_decay))(x) if dropout_rate is not None: x = SpatialDropout3D(dropout_rate)(x) x = BatchNormalization(scale=bn_scale, axis=-1)(x) x = activation()(x) x = Conv3D(filters, kernel_size=(3, 3, 3), padding='same', use_bias=True, kernel_initializer=kernel_initializer, kernel_regularizer=l2_penalty(weight_decay))(x) return x
def get_small_3d_unet(input_shape): img_input = Input(input_shape) conv1 = conv_block_simple_3D(img_input, 32, "conv1_1") conv1 = conv_block_simple_3D(conv1, 32, "conv1_2") pool1 = MaxPooling3D((2, 2, 2), strides=(2, 2, 2), padding="same", name="pool1", data_format='channels_first')(conv1) conv2 = conv_block_simple_3D(pool1, 64, "conv2_1") conv2 = conv_block_simple_3D(conv2, 64, "conv2_2") conv2 = conv_block_simple_3D(conv2, 64, "conv2_3") up3 = concatenate( [UpSampling3D(data_format='channels_first')(conv2), conv1], axis=1) conv3 = conv_block_simple_3D(up3, 32, "conv3_1") conv3 = conv_block_simple_3D(conv3, 32, "conv3_2") conv3 = SpatialDropout3D(rate=0.2, data_format='channels_first')(conv3) prediction = Conv3D(1, (1, 1, 1), activation="sigmoid", name="prediction", data_format='channels_first')(conv3) model = Model(img_input, prediction) return model
def get_model(input_shape): return Sequential([ InputLayer(input_shape=input_shape), Conv3D(16, (4, 3, 3), activation='relu', bias_regularizer=l2(0.0001), kernel_regularizer=l2(0.0001), name="conv3d_0"), SpatialDropout3D(0.4), MaxPooling3D(), Conv3D(32, (3, 3, 3), activation='relu', bias_regularizer=l2(0.0001), kernel_regularizer=l2(0.0001), name="conv3d_1"), SpatialDropout3D(0.4), MaxPooling3D(), Conv3D(64, (1, 3, 3), activation='relu', bias_regularizer=l2(0.0001), kernel_regularizer=l2(0.0001), name="conv3d_2"), SpatialDropout3D(0.35), MaxPooling3D(), Flatten(), Dense(256, activation='relu', bias_regularizer=l2(0.0001), kernel_regularizer=l2(0.0001), name="dense_0"), Dropout(0.5), Dense(128, activation='relu', bias_regularizer=l2(0.0001), kernel_regularizer=l2(0.0001), name="dense_1"), Dropout(0.25), Dense(2, activation='softmax', bias_regularizer=l2(0.0001), kernel_regularizer=l2(0.0001), name="softmax") ])
def get_simple_3d_unet(input_shape): img_input = Input(input_shape) conv1 = conv_block_simple_3D(img_input, 32, "conv1_1") conv1 = conv_block_simple_3D(conv1, 32, "conv1_2") pool1 = MaxPooling3D((2, 2, 2), strides=(2, 2, 2), padding="same", name="pool1", data_format='channels_first')(conv1) conv2 = conv_block_simple_3D(pool1, 64, "conv2_1") conv2 = conv_block_simple_3D(conv2, 64, "conv2_2") pool2 = MaxPooling3D((2, 2, 2), strides=(2, 2, 2), padding="same", name="pool2", data_format='channels_first')(conv2) conv3 = conv_block_simple_3D(pool2, 128, "conv3_1") conv3 = conv_block_simple_3D(conv3, 128, "conv3_2") pool3 = MaxPooling3D((2, 2, 2), strides=(2, 2, 2), padding="same", name="pool3", data_format='channels_first')(conv3) conv4 = conv_block_simple_3D(pool3, 256, "conv4_1") conv4 = conv_block_simple_3D(conv4, 256, "conv4_2") conv4 = conv_block_simple_3D(conv4, 256, "conv4_3") up5 = concatenate( [UpSampling3D(data_format='channels_first')(conv4), conv3], axis=1) conv5 = conv_block_simple_3D(up5, 128, "conv5_1") conv5 = conv_block_simple_3D(conv5, 128, "conv5_2") up6 = concatenate( [UpSampling3D(data_format='channels_first')(conv5), conv2], axis=1) conv6 = conv_block_simple_3D(up6, 64, "conv6_1") conv6 = conv_block_simple_3D(conv6, 64, "conv6_2") up7 = concatenate( [UpSampling3D(data_format='channels_first')(conv6), conv1], axis=1) conv7 = conv_block_simple_3D(up7, 32, "conv7_1") conv7 = conv_block_simple_3D(conv7, 32, "conv7_2") conv7 = SpatialDropout3D(rate=0.2, data_format='channels_first')(conv7) prediction = Conv3D(1, (1, 1, 1), activation="sigmoid", name="prediction", data_format='channels_first')(conv7) model = Model(img_input, prediction) return model
def dropout_vnet(input_shape=(280, 280, 280, 1), kernel_size=3, activation="relu", padding="SAME", **kwargs): inputs = Input(input_shape) conv1, pool1 = down_stage(inputs, 16, kernel_size=kernel_size, activation=activation, padding=padding) conv2, pool2 = down_stage(pool1, 32, kernel_size=kernel_size, activation=activation, padding=padding) conv3, pool3 = down_stage(pool2, 64, kernel_size=kernel_size, activation=activation, padding=padding) conv4, _ = down_stage(pool3, 128, kernel_size=kernel_size, activation=activation, padding=padding) conv4 = SpatialDropout3D(0.5)(conv4, training=True) conv5 = up_stage(conv4, conv3, 64, kernel_size=kernel_size, activation=activation, padding=padding) conv6 = up_stage(conv5, conv2, 32, kernel_size=kernel_size, activation=activation, padding=padding) conv7 = up_stage(conv6, conv1, 16, kernel_size=kernel_size, activation=activation, padding=padding) conv8 = end_stage(conv7, kernel_size=kernel_size, activation=activation, padding=padding) return Model(inputs=inputs, outputs=conv8)
def create_context_module(input_layer, n_level_filters, dropout_rate=0.3, data_format="channels_first"): convolution1 = create_convolution_block(input_layer=input_layer, n_filters=n_level_filters) dropout = SpatialDropout3D(rate=dropout_rate, data_format=data_format)(convolution1) convolution2 = create_convolution_block(input_layer=dropout, n_filters=n_level_filters) return convolution2
def up_stage(inputs, skip, filters, kernel_size=3, activation="relu", padding="SAME"): """decoding block of the VNet model. Parameters ---------- inputs: tf.layer for encoding stage. filters: list or tuple of four ints, the shape of the input data. Omit the batch dimension, and include the number of channels. kernal_size: int, size of the kernal of conv layers. Default kernal size is set to be 3. activation: str or optimizer object, the non-linearity to use. All tf.activations are allowed to use Returns ---------- decoded module. """ up = UpSampling3D()(inputs) up = Conv3D(filters, 2, activation=activation, padding=padding)(up) up = GroupNormalization()(up) merge = concatenate([skip, up]) merge = GroupNormalization()(merge) convu = Conv3D(filters, kernel_size, activation=activation, padding=padding)(merge) convu = GroupNormalization()(convu) convu = Conv3D(filters, kernel_size, activation=activation, padding=padding)(convu) convu = GroupNormalization()(convu) convu = SpatialDropout3D(0.5)(convu, training=True) return convu
def _get_dropout_layer(self, layer_idx): if layer_idx in self.dropout_contraction_levels: dropout_level = self.dropout_levels[ self.dropout_contraction_levels.index(layer_idx)] if self.spatial_dropout: if self.image_shape is None or len(self.image_shape) < 3: return SpatialDropout2D( dropout_level, name="{}_l{}_dropout".format(self.name, layer_idx) if self.name else None) else: return SpatialDropout3D( dropout_level, name="{}_l{}_dropout".format(self.name, layer_idx) if self.name else None) else: return Dropout( dropout_level, name="{}_l{}_dropout".format(self.name, layer_idx) if self.name else None) else: return None
def residual_block_3d(input, number_of_filters): block = convB_3d_layer(input, number_of_filters) block = SpatialDropout3D(rate=0.3, data_format=data_format)(block) block = convB_3d_layer(block, number_of_filters) return (block)
def __init__(self, input_shape=(4, 160, 192, 128), output_channels=3, l2_reg_weight=1e-5, weight_L2=0.1, weight_KL=0.1, dice_e=1e-8, test_mode=True, n_gpu=1, GL_weight=1, VL_weight=0.1, **kwargs): super().__init__(**kwargs) self.c, self.H, self.W, self.D = input_shape self.n = self.c * self.H * self.W * self.D assert len(input_shape) == 4, "Input shape must be a 4-tuple" if test_mode is not True: assert (self.c % 4) == 0, "The no. of channels must be divisible by 4" assert (self.H % 16) == 0 and (self.W % 16) == 0 and ( self.D % 16) == 0, "All the input dimensions must be divisible by 16" self.l2_regularizer = l2( l2_reg_weight) if l2_reg_weight is not None else None self.input_shape_p = input_shape self.output_channels = output_channels self.l2_reg_weight = l2_reg_weight self.weight_L2 = weight_L2 self.weight_KL = weight_KL self.dice_e = dice_e self.GL_weight = GL_weight self.VL_weight = VL_weight self.LossVAE = LossVAE(weight_L2, weight_KL, self.n) ## The Initial Block self.Input_x1 = Conv3D(filters=32, kernel_size=(3, 3, 3), strides=1, padding='same', kernel_regularizer=self.l2_regularizer, data_format='channels_first', name='Input_x1') ## Dropout (0.2) self.spatial_dropout = SpatialDropout3D(0.2, data_format='channels_first') ## Green Block x1 (output filters = 32) self.x1 = green_block(32, regularizer=self.l2_regularizer, name='x1') self.Enc_DownSample_32 = Conv3D(filters=32, kernel_size=(3, 3, 3), strides=2, padding='same', kernel_regularizer=self.l2_regularizer, data_format='channels_first', name='Enc_DownSample_32') ## Green Block x2 (output filters = 64) self.Enc_64_1 = green_block(64, regularizer=self.l2_regularizer, name='Enc_64_1') self.x2 = green_block(64, regularizer=self.l2_regularizer, name='x2') self.Enc_DownSample_64 = Conv3D(filters=64, kernel_size=(3, 3, 3), strides=2, padding='same', kernel_regularizer=self.l2_regularizer, data_format='channels_first', name='Enc_DownSample_64') ## Green Blocks x2 (output filters = 128) self.Enc_128_1 = green_block(128, regularizer=self.l2_regularizer, name='Enc_128_1') self.x3 = green_block(128, regularizer=self.l2_regularizer, name='x3') self.Enc_DownSample_128 = Conv3D( filters=128, kernel_size=(3, 3, 3), strides=2, padding='same', kernel_regularizer=self.l2_regularizer, data_format='channels_first', name='Enc_DownSample_128') ## Green Blocks x4 (output filters = 256) self.Enc_256_1 = green_block(256, regularizer=self.l2_regularizer, name='Enc_256_1') self.Enc_256_2 = green_block(256, regularizer=self.l2_regularizer, name='Enc_256_2') self.Enc_256_3 = green_block(256, regularizer=self.l2_regularizer, name='Enc_256_3') self.x4 = green_block(256, regularizer=self.l2_regularizer, name='x4') # ------------------------------------------------------------------------- # Decoder # ------------------------------------------------------------------------- ## GT (Groud Truth) Part # ------------------------------------------------------------------------- ### Green Block x1 (output filters=128) self.Dec_GT_ReduceDepth_128 = Conv3D( filters=128, kernel_size=(1, 1, 1), strides=1, kernel_regularizer=self.l2_regularizer, data_format='channels_first', name='Dec_GT_ReduceDepth_128') self.Dec_GT_UpSample_128 = UpSampling3D(size=2, data_format='channels_first', name='Dec_GT_UpSample_128') self.Input_Dec_GT_128 = Add(name='Input_Dec_GT_128') self.Dec_GT_128 = green_block(128, regularizer=self.l2_regularizer, name='Dec_GT_128') ### Green Block x1 (output filters=64) self.Dec_GT_ReduceDepth_64 = Conv3D( filters=64, kernel_size=(1, 1, 1), strides=1, kernel_regularizer=self.l2_regularizer, data_format='channels_first', name='Dec_GT_ReduceDepth_64') self.Dec_GT_UpSample_64 = UpSampling3D(size=2, data_format='channels_first', name='Dec_GT_UpSample_64') self.Input_Dec_GT_64 = Add(name='Input_Dec_GT_64') self.Dec_GT_64 = green_block(64, regularizer=self.l2_regularizer, name='Dec_GT_64') ### Green Block x1 (output filters=32) self.Dec_GT_ReduceDepth_32 = Conv3D( filters=32, kernel_size=(1, 1, 1), strides=1, kernel_regularizer=self.l2_regularizer, data_format='channels_first', name='Dec_GT_ReduceDepth_32') self.Dec_GT_UpSample_32 = UpSampling3D(size=2, data_format='channels_first', name='Dec_GT_UpSample_32') self.Input_Dec_GT_32 = Add(name='Input_Dec_GT_32') self.Dec_GT_32 = green_block(32, regularizer=self.l2_regularizer, name='Dec_GT_32') ### Blue Block x1 (output filters=32) self.Input_Dec_GT_Output = Conv3D( filters=32, kernel_size=(3, 3, 3), strides=1, padding='same', kernel_regularizer=self.l2_regularizer, data_format='channels_first', name='Input_Dec_GT_Output') ### Output Block self.Dec_GT_Output = Conv3D(filters=self.output_channels, kernel_size=(1, 1, 1), strides=1, kernel_regularizer=self.l2_regularizer, data_format='channels_first', activation='sigmoid', name='Dec_GT_Output') ## VAE (Variational Auto Encoder) Part # ------------------------------------------------------------------------- ### VD Block (Reducing dimensionality of the data) self.Dec_VAE_VD_GN = GroupNormalization(groups=8, axis=1, name='Dec_VAE_VD_GN') self.Dec_VAE_VD_relu = Activation('relu', name='Dec_VAE_VD_relu') self.Dec_VAE_VD_Conv3D = Conv3D(filters=16, kernel_size=(3, 3, 3), strides=2, padding='same', kernel_regularizer=self.l2_regularizer, data_format='channels_first', name='Dec_VAE_VD_Conv3D') # Not mentioned in the paper, but the author used a Flattening layer here. self.Dec_VAE_VD_Flatten = Flatten(name='Dec_VAE_VD_Flatten') self.Dec_VAE_VD_Dense = Dense(256, name='Dec_VAE_VD_Dense') ### VDraw Block (Sampling) self.Dec_VAE_VDraw_Mean = Dense(128, name='Dec_VAE_VDraw_Mean') self.Dec_VAE_VDraw_Var = Dense(128, name='Dec_VAE_VDraw_Var') # self.Dec_VAE_VDraw_Sampling = Lambda(sampling, name='Dec_VAE_VDraw_Sampling') self.Dec_VAE_VDraw_Sampling = sampling() ### VU Block (Upsizing back to a depth of 256) c1 = 1 self.VU_Dense1 = Dense( (c1) * (self.H // 16) * (self.W // 16) * (self.D // 16)) self.VU_relu = Activation('relu') self.VU_reshape = Reshape( ((c1), (self.H // 16), (self.W // 16), (self.D // 16))) self.Dec_VAE_ReduceDepth_256 = Conv3D( filters=256, kernel_size=(1, 1, 1), strides=1, kernel_regularizer=self.l2_regularizer, data_format='channels_first', name='Dec_VAE_ReduceDepth_256') self.Dec_VAE_UpSample_256 = UpSampling3D(size=2, data_format='channels_first', name='Dec_VAE_UpSample_256') ### Green Block x1 (output filters=128) self.Dec_VAE_ReduceDepth_128 = Conv3D( filters=128, kernel_size=(1, 1, 1), strides=1, kernel_regularizer=self.l2_regularizer, data_format='channels_first', name='Dec_VAE_ReduceDepth_128') self.Dec_VAE_UpSample_128 = UpSampling3D(size=2, data_format='channels_first', name='Dec_VAE_UpSample_128') self.Dec_VAE_128 = green_block(128, regularizer=self.l2_regularizer, name='Dec_VAE_128') ### Green Block x1 (output filters=64) self.Dec_VAE_ReduceDepth_64 = Conv3D( filters=64, kernel_size=(1, 1, 1), strides=1, kernel_regularizer=self.l2_regularizer, data_format='channels_first', name='Dec_VAE_ReduceDepth_64') self.Dec_VAE_UpSample_64 = UpSampling3D(size=2, data_format='channels_first', name='Dec_VAE_UpSample_64') self.Dec_VAE_64 = green_block(64, regularizer=self.l2_regularizer, name='Dec_VAE_64') ### Green Block x1 (output filters=32) self.Dec_VAE_ReduceDepth_32 = Conv3D( filters=32, kernel_size=(1, 1, 1), strides=1, kernel_regularizer=self.l2_regularizer, data_format='channels_first', name='Dec_VAE_ReduceDepth_32') self.Dec_VAE_UpSample_32 = UpSampling3D(size=2, data_format='channels_first', name='Dec_VAE_UpSample_32') self.Dec_VAE_32 = green_block(32, regularizer=self.l2_regularizer, name='Dec_VAE_32') ### Blue Block x1 (output filters=32) self.Input_Dec_VAE_Output = Conv3D( filters=32, kernel_size=(3, 3, 3), strides=1, padding='same', kernel_regularizer=self.l2_regularizer, data_format='channels_first', name='Input_Dec_VAE_Output') ### Output Block self.Dec_VAE_Output = Conv3D(filters=self.c, kernel_size=(1, 1, 1), strides=1, kernel_regularizer=self.l2_regularizer, data_format='channels_first', name='Dec_VAE_Output')
def SE_U_Net_3D(image_shape, activation='elu', feature_maps=[32, 64, 128, 256], depth=3, drop_values=[0.1, 0.1, 0.1, 0.1], spatial_dropout=False, batch_norm=False, k_init='he_normal', loss_type="bce", optimizer="sgd", lr=0.001, n_classes=1): """Create 3D U-Net with squeeze-excite blocks. Reference `Squeeze and Excitation Networks <https://arxiv.org/abs/1709.01507>`_. Parameters ---------- image_shape : 3D tuple Dimensions of the input image. activation : str, optional Keras available activation type. feature_maps : array of ints, optional Feature maps to use on each level. Must have the same length as the ``depth+1``. depth : int, optional Depth of the network. drop_values : float, optional Dropout value to be fixed. spatial_dropout : bool, optional Use spatial dropout instead of the `normal` dropout. batch_norm : bool, optional Make batch normalization. k_init : string, optional Kernel initialization for convolutional layers. loss_type : str, optional Loss type to use, three type available: ``bce`` (Binary Cross Entropy) , ``w_bce`` (Weighted BCE, based on weigth maps) and ``w_bce_dice`` (Weighted loss: ``weight1*BCE + weight2*Dice``). optimizer : str, optional Optimizer used to minimize the loss function. Posible options: ``sgd`` or ``adam``. lr : float, optional Learning rate value. n_classes: int, optional Number of classes. Returns ------- model : Keras model Model containing the U-Net. Calling this function with its default parameters returns the following network: .. image:: img/unet_3d.png :width: 100% :align: center Image created with `PlotNeuralNet <https://github.com/HarisIqbal88/PlotNeuralNet>`_. """ if len(feature_maps) != depth + 1: raise ValueError("feature_maps dimension must be equal depth+1") if len(drop_values) != depth + 1: raise ValueError("'drop_values' dimension must be equal depth+1") #dinamic_dim = (None,)*(len(image_shape)-1) + (image_shape[-1],) #inputs = Input(dinamic_dim) x = Input(image_shape) inputs = x if loss_type == "w_bce": weights = Input(image_shape) # List used to access layers easily to make the skip connections of the U-Net l = [] # ENCODER for i in range(depth): x = Conv3D(feature_maps[i], (3, 3, 3), activation=None, kernel_initializer=k_init, padding='same')(x) x = BatchNormalization()(x) if batch_norm else x x = Activation(activation)(x) x = squeeze_excite_block(x) if spatial_dropout and drop_values[i] > 0: x = SpatialDropout3D(drop_values[i])(x) elif drop_values[i] > 0 and not spatial_dropout: x = Dropout(drop_values[i])(x) x = Conv3D(feature_maps[i], (3, 3, 3), activation=None, kernel_initializer=k_init, padding='same')(x) x = BatchNormalization()(x) if batch_norm else x x = Activation(activation)(x) x = squeeze_excite_block(x) l.append(x) x = MaxPooling3D((2, 2, 2))(x) # BOTTLENECK x = Conv3D(feature_maps[depth], (3, 3, 3), activation=None, kernel_initializer=k_init, padding='same')(x) x = BatchNormalization()(x) if batch_norm else x x = Activation(activation)(x) if spatial_dropout and drop_values[depth] > 0: x = SpatialDropout3D(drop_values[depth])(x) elif drop_values[depth] > 0 and not spatial_dropout: x = Dropout(drop_values[depth])(x) x = Conv3D(feature_maps[depth], (3, 3, 3), activation=None, kernel_initializer=k_init, padding='same')(x) x = BatchNormalization()(x) if batch_norm else x x = Activation(activation)(x) # DECODER for i in range(depth - 1, -1, -1): x = Conv3DTranspose(feature_maps[i], (2, 2, 2), strides=(2, 2, 2), padding='same')(x) x = concatenate([x, l[i]]) x = Conv3D(feature_maps[i], (3, 3, 3), activation=None, kernel_initializer=k_init, padding='same')(x) x = BatchNormalization()(x) if batch_norm else x x = Activation(activation)(x) x = squeeze_excite_block(x) if spatial_dropout and drop_values[i] > 0: x = SpatialDropout3D(drop_values[i])(x) elif drop_values[i] > 0 and not spatial_dropout: x = Dropout(drop_values[i])(x) x = Conv3D(feature_maps[i], (3, 3, 3), activation=None, kernel_initializer=k_init, padding='same')(x) x = BatchNormalization()(x) if batch_norm else x x = Activation(activation)(x) x = squeeze_excite_block(x) outputs = Conv3D(n_classes, (1, 1, 1), activation='sigmoid')(x) # Loss type if loss_type == "w_bce": model = Model(inputs=[inputs, weights], outputs=[outputs]) else: model = Model(inputs=[inputs], outputs=[outputs]) # Select the optimizer if optimizer == "sgd": opt = tf.keras.optimizers.SGD(lr=lr, momentum=0.99, decay=0.0, nesterov=False) elif optimizer == "adam": opt = tf.keras.optimizers.Adam(lr=lr, beta_1=0.9, beta_2=0.999, epsilon=None, decay=0.0, amsgrad=False) else: raise ValueError("Error: optimizer value must be 'sgd' or 'adam'") # Compile the model if loss_type == "bce": if n_classes > 1: model.compile(optimizer=opt, loss='categorical_crossentropy', metrics=[jaccard_index_softmax]) else: model.compile(optimizer=opt, loss='binary_crossentropy', metrics=[jaccard_index]) elif loss_type == "w_bce": model.compile(optimizer=opt, loss=binary_crossentropy_weighted(weights), metrics=[jaccard_index]) elif loss_type == "w_bce_dice": model.compile(optimizer=opt, loss=weighted_bce_dice_loss(w_dice=0.66, w_bce=0.33), metrics=[jaccard_index]) else: raise ValueError("'loss_type' must be 'bce', 'w_bce' or 'w_bce_dice'") return model
def create_model_3D(self, input_shape, n_labels=2): # Input layer inputs = Input(input_shape) # Cache contracting normalized conv layers # for later copy & concatenate links contracting_convs = {c: [] for c in self.feature_maps.keys()} all_middle_chains = [] all_chains = [] for stride, feature_map in self.feature_maps.items(): # Start the CNN Model chain with adding the inputs as first tensor cnn_chain = inputs # Contracting layers for i in range(0, len(feature_map)): neurons = feature_map[i] cnn_chain = conv_layer_3D(cnn_chain, neurons, self.conv_layer_activation, self.inst_norm, self.inst_norm_params) cnn_chain = conv_layer_3D(cnn_chain, neurons, self.conv_layer_activation, self.inst_norm, self.inst_norm_params) cnn_chain = SpatialDropout3D(self.dropout)(cnn_chain) contracting_convs[stride].append(cnn_chain) cnn_chain = MaxPooling3D(pool_size=(stride, stride, stride))(cnn_chain) # Middle Layer neurons = feature_map[-1] cnn_chain = conv_layer_3D(cnn_chain, neurons, self.conv_layer_activation, self.inst_norm, self.inst_norm_params) cnn_chain = conv_layer_3D(cnn_chain, neurons, self.conv_layer_activation, self.inst_norm, self.inst_norm_params) all_middle_chains.append(cnn_chain) cnn_chain1 = concatenate(all_middle_chains) cnn_chain1 = LayerNormalization(**self.layer_norm_params)(cnn_chain1) for stride, feature_map in self.feature_maps.items(): # Start the CNN Model chain with adding the inputs as first tensor cnn_chain = cnn_chain1 # Expanding Layers for i in reversed(range(0, len(feature_map))): neurons = feature_map[i] cnn_chain = Conv3DTranspose(neurons, (stride, stride, stride), strides=(stride, stride, stride), padding='same')(cnn_chain) cnn_chain = SpatialDropout3D(self.dropout)(cnn_chain) cnn_chain = concatenate( [cnn_chain, contracting_convs[stride][i]], axis=-1) cnn_chain = conv_layer_3D(cnn_chain, neurons, self.conv_layer_activation, self.inst_norm, self.inst_norm_params) cnn_chain = conv_layer_3D(cnn_chain, neurons, self.conv_layer_activation, self.inst_norm, self.inst_norm_params) all_chains.append(cnn_chain) # Output Layer conv_out = Conv3D(n_labels, (1, 1, 1), activation=self.activation)(concatenate(all_chains, axis=-1)) # Create Model with associated input and output layers model = Model(inputs=[inputs], outputs=[conv_out]) # Return model return model
def create_model(conv_1,conv_2,conv_3,conv_4,conv_5,activation,initializer,conv_dropout,cnv_drp_rate, filt_size,pool_size,l2_penalty,ff1,ff2,ff3,ff4,batch_norm,mom,ffdrop,drp_rate, padding): """creates convolutional neural network with tensorflow keras layers in 3 distinct blocks""" model=Sequential() model.add(Conv3D(conv_1,filt_size,input_shape=(125,145,125,1),activation=activation, kernel_initializer=initializer,kernel_regularizer=l2(l2_penalty), name='conv_1',padding=padding)) model.add(Conv3D(conv_2,filt_size,activation=activation, kernel_initializer=initializer,kernel_regularizer=l2(l2_penalty), name='conv_2',padding=padding)) if conv_dropout == True: model.add(SpatialDropout3D(cnv_drp_rate,name='spatial_dropout_1')) model.add(MaxPooling3D(pool_size,name='max_pool_1')) model.add(Conv3D(conv_3,filt_size,activation=activation, kernel_initializer=initializer,kernel_regularizer=l2(l2_penalty), name='conv_3',padding=padding)) model.add(Conv3D(conv_4,filt_size,activation=activation, kernel_initializer=initializer,kernel_regularizer=l2(l2_penalty), name='conv_4',padding=padding)) if conv_dropout == True: model.add(SpatialDropout3D(cnv_drp_rate,name='spatial_dropout_2')) model.add(MaxPooling3D(pool_size,name='max_pool_2')) model.add(Conv3D(conv_5,filt_size,activation=activation, kernel_initializer=initializer,kernel_regularizer=l2(l2_penalty), name='conv_5',padding=padding)) if conv_dropout == True: model.add(SpatialDropout3D(cnv_drp_rate,name='spatial_dropout_3')) model.add(MaxPooling3D(pool_size,name='max_pool_3')) model.add(Flatten(name='flatten')) model.add(Dense(ff1,activation=activation, kernel_initializer=initializer,kernel_regularizer=l2(l2_penalty), name='dense_1')) if batch_norm==True: model.add(BatchNormalization(momentum=mom,name='batch_norm_1')) if ffdrop==True: model.add(Dropout(drp_rate,name='dense_dropout_1')) model.add(Dense(ff2,activation=activation, kernel_initializer=initializer,kernel_regularizer=l2(l2_penalty), name='dense_2')) if batch_norm==True: model.add(BatchNormalization(momentum=mom,name='batch_norm_2')) if ffdrop==True: model.add(Dropout(drp_rate,name='dense_dropout_2')) model.add(Dense(ff3,activation=activation, kernel_initializer=initializer,kernel_regularizer=l2(l2_penalty), name='dense_3')) if batch_norm==True: model.add(BatchNormalization(momentum=mom,name='batch_norm_3')) if ffdrop==True: model.add(Dropout(drp_rate,name='dense_dropout_3')) model.add(Dense(ff4,activation=activation, kernel_initializer=initializer,kernel_regularizer=l2(l2_penalty), name='dense_4')) model.add(Dense(1,activation='sigmoid',name='prediction')) return(model)
def build_model(input_shape=(4, 160, 192, 128), output_channels=3, weight_L2=0.1, weight_KL=0.1, dice_e=1e-8): """ build_model(input_shape=(4, 160, 192, 128), output_channels=3, weight_L2=0.1, weight_KL=0.1) ------------------------------------------- Creates the model used in the BRATS2018 winning solution by Myronenko A. (https://arxiv.org/pdf/1810.11654.pdf) Parameters ---------- `input_shape`: A 4-tuple, optional. Shape of the input image. Must be a 4D image of shape (c, H, W, D), where, each of H, W and D are divisible by 2^4, and c is divisible by 4. Defaults to the crop size used in the paper, i.e., (4, 160, 192, 128). `output_channels`: An integer, optional. The no. of channels in the output. Defaults to 3 (BraTS 2018 format). `weight_L2`: A real number, optional The weight to be given to the L2 loss term in the loss function. Adjust to get best results for your task. Defaults to 0.1. `weight_KL`: A real number, optional The weight to be given to the KL loss term in the loss function. Adjust to get best results for your task. Defaults to 0.1. `dice_e`: Float, optional A small epsilon term to add in the denominator of dice loss to avoid dividing by zero and possible gradient explosion. This argument will be passed to loss_gt function. Returns ------- `model`: A keras.models.Model instance The created model. """ c, H, W, D = input_shape assert len(input_shape) == 4, "Input shape must be a 4-tuple" assert (c % 4) == 0, "The no. of channels must be divisible by 4" assert (H % 16) == 0 and (W % 16) == 0 and (D % 16) == 0, \ "All the input dimensions must be divisible by 16" # ------------------------------------------------------------------------- # Encoder # ------------------------------------------------------------------------- ## Input Layer inp = Input(input_shape) ## The Initial Block x = Conv3D( filters=32, kernel_size=(3, 3, 3), strides=1, padding='same', data_format='channels_first', name='Input_x1')(inp) ## Dropout (0.2) x = SpatialDropout3D(0.2, data_format='channels_first')(x) ## Green Block x1 (output filters = 32) x1 = green_block(x, 32, name='x1') x = Conv3D( filters=32, kernel_size=(3, 3, 3), strides=2, padding='same', data_format='channels_first', name='Enc_DownSample_32')(x1) ## Green Block x2 (output filters = 64) x = green_block(x, 64, name='Enc_64_1') x2 = green_block(x, 64, name='x2') x = Conv3D( filters=64, kernel_size=(3, 3, 3), strides=2, padding='same', data_format='channels_first', name='Enc_DownSample_64')(x2) ## Green Blocks x2 (output filters = 128) x = green_block(x, 128, name='Enc_128_1') x3 = green_block(x, 128, name='x3') x = Conv3D( filters=128, kernel_size=(3, 3, 3), strides=2, padding='same', data_format='channels_first', name='Enc_DownSample_128')(x3) ## Green Blocks x4 (output filters = 256) x = green_block(x, 256, name='Enc_256_1') x = green_block(x, 256, name='Enc_256_2') x = green_block(x, 256, name='Enc_256_3') x4 = green_block(x, 256, name='x4') # ------------------------------------------------------------------------- # Decoder # ------------------------------------------------------------------------- ## GT (Groud Truth) Part # ------------------------------------------------------------------------- ### Green Block x1 (output filters=128) x = Conv3D( filters=128, kernel_size=(1, 1, 1), strides=1, data_format='channels_first', name='Dec_GT_ReduceDepth_128')(x4) x = UpSampling3D( size=2, data_format='channels_first', name='Dec_GT_UpSample_128')(x) x = Add(name='Input_Dec_GT_128')([x, x3]) x = green_block(x, 128, name='Dec_GT_128') ### Green Block x1 (output filters=64) x = Conv3D( filters=64, kernel_size=(1, 1, 1), strides=1, data_format='channels_first', name='Dec_GT_ReduceDepth_64')(x) x = UpSampling3D( size=2, data_format='channels_first', name='Dec_GT_UpSample_64')(x) x = Add(name='Input_Dec_GT_64')([x, x2]) x = green_block(x, 64, name='Dec_GT_64') ### Green Block x1 (output filters=32) x = Conv3D( filters=32, kernel_size=(1, 1, 1), strides=1, data_format='channels_first', name='Dec_GT_ReduceDepth_32')(x) x = UpSampling3D( size=2, data_format='channels_first', name='Dec_GT_UpSample_32')(x) x = Add(name='Input_Dec_GT_32')([x, x1]) x = green_block(x, 32, name='Dec_GT_32') ### Blue Block x1 (output filters=32) x = Conv3D( filters=32, kernel_size=(3, 3, 3), strides=1, padding='same', data_format='channels_first', name='Input_Dec_GT_Output')(x) ### Output Block out_GT = Conv3D( filters=output_channels, # No. of tumor classes is 3 kernel_size=(1, 1, 1), strides=1, data_format='channels_first', activation='sigmoid', name='Dec_GT_Output')(x) ## VAE (Variational Auto Encoder) Part # ------------------------------------------------------------------------- ### VD Block (Reducing dimensionality of the data) x = GroupNormalization(groups=8, axis=1, name='Dec_VAE_VD_GN')(x4) x = Activation('relu', name='Dec_VAE_VD_relu')(x) x = Conv3D( filters=16, kernel_size=(3, 3, 3), strides=2, padding='same', data_format='channels_first', name='Dec_VAE_VD_Conv3D')(x) # Not mentioned in the paper, but the author used a Flattening layer here. x = Flatten(name='Dec_VAE_VD_Flatten')(x) x = Dense(256, name='Dec_VAE_VD_Dense')(x) ### VDraw Block (Sampling) z_mean = Dense(128, name='Dec_VAE_VDraw_Mean')(x) z_var = Dense(128, name='Dec_VAE_VDraw_Var')(x) x = Lambda(sampling, name='Dec_VAE_VDraw_Sampling')([z_mean, z_var]) ### VU Block (Upsizing back to a depth of 256) x = Dense((c//4) * (H//16) * (W//16) * (D//16))(x) x = Activation('relu')(x) x = Reshape(((c//4), (H//16), (W//16), (D//16)))(x) x = Conv3D( filters=256, kernel_size=(1, 1, 1), strides=1, data_format='channels_first', name='Dec_VAE_ReduceDepth_256')(x) x = UpSampling3D( size=2, data_format='channels_first', name='Dec_VAE_UpSample_256')(x) ### Green Block x1 (output filters=128) x = Conv3D( filters=128, kernel_size=(1, 1, 1), strides=1, data_format='channels_first', name='Dec_VAE_ReduceDepth_128')(x) x = UpSampling3D( size=2, data_format='channels_first', name='Dec_VAE_UpSample_128')(x) x = green_block(x, 128, name='Dec_VAE_128') ### Green Block x1 (output filters=64) x = Conv3D( filters=64, kernel_size=(1, 1, 1), strides=1, data_format='channels_first', name='Dec_VAE_ReduceDepth_64')(x) x = UpSampling3D( size=2, data_format='channels_first', name='Dec_VAE_UpSample_64')(x) x = green_block(x, 64, name='Dec_VAE_64') ### Green Block x1 (output filters=32) x = Conv3D( filters=32, kernel_size=(1, 1, 1), strides=1, data_format='channels_first', name='Dec_VAE_ReduceDepth_32')(x) x = UpSampling3D( size=2, data_format='channels_first', name='Dec_VAE_UpSample_32')(x) x = green_block(x, 32, name='Dec_VAE_32') ### Blue Block x1 (output filters=32) x = Conv3D( filters=32, kernel_size=(3, 3, 3), strides=1, padding='same', data_format='channels_first', name='Input_Dec_VAE_Output')(x) ### Output Block out_VAE = Conv3D( filters=4, kernel_size=(1, 1, 1), strides=1, data_format='channels_first', name='Dec_VAE_Output')(x) # Build and Compile the model out = out_GT model = Model(inp, outputs=[out, out_VAE]) # Create the model model.compile( Adam(lr=1e-4), [loss_gt(dice_e), loss_VAE(input_shape, z_mean, z_var, weight_L2=weight_L2, weight_KL=weight_KL)], metrics=[dice_coefficient] ) return model
def create_unet_model3D(input_image_size, n_labels=1, layers=4, lowest_resolution=16, convolution_kernel_size=(5, 5, 5), deconvolution_kernel_size=(5, 5, 5), pool_size=(2, 2, 2), strides=(1, 1, 1), mode='classification', output_activation='tanh', activation='relu', init_lr=0.0001, dropout=0.2, dropout_type='spatial', batchnorm=False): """ Create a 3D Unet model Example ------- unet_model = create_unet_model3D( (128,128,128,1), 1, 4) """ layers = np.arange(layers) number_of_classification_labels = n_labels inputs = Input(shape=input_image_size) ## ENCODING PATH ## encoding_convolution_layers = [] pool = None conv_tot = 0 for i in range(len(layers)): number_of_filters = lowest_resolution * 2**(layers[i]) conv_tot += 1 if i == 0: conv = Conv3D(filters=number_of_filters, kernel_size=convolution_kernel_size, activation=activation, padding='same', name='conv3d_' + str(conv_tot))(inputs) else: conv = Conv3D(filters=number_of_filters, kernel_size=convolution_kernel_size, activation=activation, padding='same', name='conv3d_' + str(conv_tot))(pool) if dropout is not None: if dropout_type is 'spatial': conv = SpatialDropout3D(dropout)(conv) else: conv = Dropout(dropout)(conv) if batchnorm is True: conv = BatchNormalization(axis=4)(conv) conv_tot += 1 encoding_convolution_layers.append( Conv3D(filters=number_of_filters, kernel_size=convolution_kernel_size, activation=activation, padding='same', name='conv3d_' + str(conv_tot))(conv)) if i < len(layers) - 1: pool = MaxPooling3D(pool_size=pool_size, name='pool_' + str(i))( encoding_convolution_layers[i]) ## DECODING PATH ## outputs = encoding_convolution_layers[len(layers) - 1] conv_tot += 1 print(conv_tot) for j in range(1, len(layers)): if j < len(layers) - 1: decon_kernel_size = deconvolution_kernel_size else: decon_kernel_size = deconvolution_kernel_size number_of_filters = lowest_resolution * 2**(len(layers) - layers[j] - 1) tmp_deconv = Conv3DTranspose(filters=number_of_filters, kernel_size=decon_kernel_size, padding='same', name='trans_' + str(j))(outputs) tmp_deconv = UpSampling3D(size=pool_size, name='upsamp_' + str(j))(tmp_deconv) outputs = Concatenate(axis=4, name='concat_' + str(j))( [tmp_deconv, encoding_convolution_layers[len(layers) - j - 1]]) conv_tot += 1 outputs = Conv3D(filters=number_of_filters, kernel_size=convolution_kernel_size, activation=activation, padding='same', name='conv3d_' + str(conv_tot))(outputs) if dropout is not None: if dropout_type is 'spatial': outputs = SpatialDropout3D(dropout)(outputs) else: outputs = Dropout(dropout)(outputs) if batchnorm is True: outputs = BatchNormalization(axis=4)(outputs) conv_tot += 1 outputs = Conv3D(filters=number_of_filters, kernel_size=convolution_kernel_size, activation=activation, padding='same', name='conv3d_' + str(conv_tot))(outputs) if dropout is not None: if dropout_type is 'spatial': outputs = SpatialDropout3D(dropout)(outputs) else: outputs = Dropout(dropout)(outputs) if batchnorm is True: outputs = BatchNormalization(axis=4)(outputs) if mode == 'classification': if number_of_classification_labels == 1: outputs = Conv3D(filters=number_of_classification_labels, kernel_size=(1, 1, 1), activation='sigmoid')(outputs) else: outputs = Conv3D(filters=number_of_classification_labels, kernel_size=(1, 1, 1), activation='softmax')(outputs) unet_model = Model(inputs=inputs, outputs=outputs) if number_of_classification_labels == 1: unet_model.compile(loss=jaccard_distance, optimizer=opt.Adam(lr=init_lr), metrics=[ 'binary_accuracy', 'binary_crossentropy', dice_coefficient_bin ]) else: unet_model.compile( loss='categorical_crossentropy', optimizer=opt.Adam(lr=init_lr), metrics=['categorical_accuracy', 'categorical_crossentropy']) elif mode == 'regression': conv_tot += 1 outputs = Conv3D(filters=1, kernel_size=(1, 1, 1), activation=output_activation, name='conv3d_' + str(conv_tot))(outputs) unet_model = Model(inputs=inputs, outputs=outputs) unet_model.compile(loss='mse', optimizer=opt.Adam(lr=init_lr), metrics=[correlation, correlation_gm, mse_gm]) else: raise ValueError( 'mode must be either `classification` or `regression`') return unet_model
def vnet(n_classes=1, input_shape=(128, 128, 128, 1), kernel_size=3, activation="relu", padding="SAME", **kwargs): """Instantiate a 3D VNet Architecture. VNet model: a 3D deep neural network model adapted from https://arxiv.org/pdf/1606.04797.pdf adatptations include groupnorm and spatial dropout. Parameters ---------- n_classes: int, number of classes to classify. For binary applications, use a value of 1. input_shape: list or tuple of four ints, the shape of the input data. Omit the batch dimension, and include the number of channels. kernal_size: int, size of the kernal of conv layers. Default kernal size is set to be 3. activation: str or optimizer object, the non-linearity to use. All tf.activations are allowed to use Returns ---------- Model object. """ inputs = Input(input_shape) conv1, pool1 = down_stage(inputs, 16, kernel_size=kernel_size, activation=activation, padding=padding) conv2, pool2 = down_stage(pool1, 32, kernel_size=kernel_size, activation=activation, padding=padding) conv3, pool3 = down_stage(pool2, 64, kernel_size=kernel_size, activation=activation, padding=padding) conv4, _ = down_stage(pool3, 128, kernel_size=kernel_size, activation=activation, padding=padding) conv4 = SpatialDropout3D(0.5)(conv4, training=True) conv5 = up_stage( conv4, conv3, 64, kernel_size=kernel_size, activation=activation, padding=padding, ) conv6 = up_stage( conv5, conv2, 32, kernel_size=kernel_size, activation=activation, padding=padding, ) conv7 = up_stage( conv6, conv1, 16, kernel_size=kernel_size, activation=activation, padding=padding, ) conv8 = end_stage( conv7, n_classes=n_classes, kernel_size=kernel_size, activation=activation, padding=padding, ) return Model(inputs=inputs, outputs=conv8)