text: from keras.models import Sequential, Model, load_model
  from keras.callbacks import EarlyStopping, ModelCheckpoint
  from keras.layers import Conv2D, BatchNormalization, Activation, MaxPooling2D, Dropout, Conv2DTranspose, Input, Flatten
  from keras.layers.merge import concatenate, add
  
  def conv2d_block(input_tensor, n_filters, kernel_size=3, batchnorm=True, name='', actfun='relu'):
  
      # first layer
      x = Conv2D(filters=n_filters, kernel_size=(kernel_size, kernel_size), kernel_initializer="he_normal",
                 padding="same")(input_tensor)
      if batchnorm:
          x = BatchNormalization()(x)
      x = Activation(actfun)(x)
      # second layer
      x = Conv2D(filters=n_filters, kernel_size=(kernel_size, kernel_size), kernel_initializer="he_normal",
                 padding="same", name=name)(x)
      if batchnorm:
          x = BatchNormalization()(x)
      x = Activation(actfun)(x)
      return x
  
  def get_unet(input_img, n_filters=32, dropout=0.5, batchnorm=True, actfun='relu'):
      # contracting path
      c1 = conv2d_block(input_img, n_filters=n_filters*1, kernel_size=3, batchnorm=batchnorm, actfun=actfun, name='c1')
      p1 = MaxPooling2D((2, 2)) (c1)
      p1 = Dropout(dropout*0.5)(p1)
      print('Contract1')
      c2 = conv2d_block(p1, n_filters=n_filters*2, kernel_size=3, batchnorm=batchnorm,name='c2', actfun=actfun)
      p2 = MaxPooling2D((2, 2)) (c2)
      p2 = Dropout(dropout)(p2)
      print('Contract2')
      c3 = conv2d_block(p2, n_filters=n_filters*4, kernel_size=3, batchnorm=batchnorm,name='c3', actfun=actfun)
      p3 = MaxPooling2D((2, 2)) (c3)
      p3 = Dropout(dropout)(p3)
      print('Contract3')
      c4 = conv2d_block(p3, n_filters=n_filters*8, kernel_size=3, batchnorm=batchnorm,name='c4', actfun=actfun)
      p4 = MaxPooling2D(pool_size=(2, 2)) (c4)
      p4 = Dropout(dropout)(p4)
      print('Contract4')
      c5 = conv2d_block(p4, n_filters=n_filters*16, kernel_size=3, batchnorm=batchnorm,name='c5', actfun=actfun)
      
      # expansive path
      u6 = Conv2DTranspose(n_filters*8, (3, 3), strides=(2, 2), padding='same') (c5)
      u6 = concatenate([u6, c4])
      u6 = Dropout(dropout)(u6)
      c6 = conv2d_block(u6, n_filters=n_filters*8, kernel_size=3, batchnorm=batchnorm, actfun=actfun)
      print('Expand1')
      u7 = Conv2DTranspose(n_filters*4, (3, 3), strides=(2, 2), padding='same') (c6)
      u7 = concatenate([u7, c3])
      u7 = Dropout(dropout)(u7)
      c7 = conv2d_block(u7, n_filters=n_filters*4, kernel_size=3, batchnorm=batchnorm, actfun=actfun)
      print('Expand2')
      u8 = Conv2DTranspose(n_filters*2, (3, 3), strides=(2, 2), padding='same') (c7)
      u8 = concatenate([u8, c2])
      u8 = Dropout(dropout)(u8)
      c8 = conv2d_block(u8, n_filters=n_filters*2, kernel_size=3, batchnorm=batchnorm, actfun=actfun)
      print('Expand3')
      u9 = Conv2DTranspose(n_filters*1, (3, 3), strides=(2, 2), padding='same') (c8)
      u9 = concatenate([u9, c1], axis=3)
      u9 = Dropout(dropout)(u9)
      c9 = conv2d_block(u9, n_filters=n_filters*1, kernel_size=3, batchnorm=batchnorm, name='extractforautoencoder', actfun=actfun)
      print('Expand4')
      outputs = Conv2D(1, (1, 1), activation='sigmoid') (c9)
      model = Model(inputs=[input_img], outputs=[outputs])
      return model