Make this Python code for building the mtl model look more elegant:
"def build_model(input_shape, num_classes):
    num_filter = 16
    # Encoder
    inputs = Input(input_shape)
    conv1 = Conv2D(num_filter * 1, 3, activation="linear", padding="same", strides=1)(inputs)
    bn1 = BatchNormalization()(conv1)
    relu1 = Activation("relu")(bn1)
    conv2 = Conv2D(num_filter * 1, 3, activation="linear", padding="same", strides=1)(relu1)
    bn2 = BatchNormalization()(conv2)
    relu2 = Activation("relu")(bn2)
    down1 = MaxPooling2D(pool_size=(2, 2), strides=2)(relu2)
    conv3 = Conv2D(num_filter * 2, 3, activation="linear", padding="same", strides=1)(down1)
    bn3 = BatchNormalization()(conv3)
    relu3 = Activation("relu")(bn3)
    conv4 = Conv2D(num_filter * 2, 3, activation="linear", padding="same", strides=1)(relu3)
    bn4 = BatchNormalization()(conv4)
    relu4 = Activation("relu")(bn4)
    down2 = MaxPooling2D(pool_size=(2, 2), strides=2)(relu4)
    conv5 = Conv2D(num_filter * 4, 3, activation="linear", padding="same", strides=1)(down2)
    bn5 = BatchNormalization()(conv5)
    relu5 = Activation("relu")(bn5)
    conv6 = Conv2D(num_filter * 4, 3, activation="linear", padding="same", strides=1)(relu5)
    bn6 = BatchNormalization()(conv6)
    relu6 = Activation("relu")(bn6)
    down3 = MaxPooling2D(pool_size=(2, 2), strides=2)(relu6)
    conv7 = Conv2D(num_filter * 8, 3, activation="linear", padding="same", strides=1)(down3)
    bn7 = BatchNormalization()(conv7)
    relu7 = Activation("relu")(bn7)
    conv8 = Conv2D(num_filter * 8, 3, activation="linear", padding="same", strides=1)(relu7)
    bn8 = BatchNormalization()(conv8)
    relu8 = Activation("relu")(bn8)
    # Middle
    down4 = MaxPooling2D(pool_size=(2, 2), strides=2)(relu8)
    conv9 = Conv2D(num_filter * 16, 3, activation="linear", padding="same", strides=1)(down4)
    bn9 = BatchNormalization()(conv9)
    relu9 = Activation("relu")(bn9)
    conv10 = Conv2D(num_filter * 16, 3, activation="linear", padding="same", strides=1)(relu9)
    bn10 = BatchNormalization()(conv10)
    relu10 = Activation("relu")(bn10)
    up1 = UpSampling2D(size=(2, 2), interpolation="bilinear")(relu10)
    # Decoder (Done)
    concat1 = concatenate([up1, relu8], axis=-1)  
    conv11 = Conv2D(num_filter * 8, 3, activation="linear", padding="same", strides=1)(concat1)
    bn11 = BatchNormalization()(conv11)
    relu11 = Activation("relu")(bn11)
    conv12 = Conv2D(num_filter * 8, 3, activation="linear", padding="same", strides=1)(relu11)
    bn12 = BatchNormalization()(conv12)
    relu12 = Activation("relu")(bn12)
    up2 = UpSampling2D(size=(2, 2), interpolation="bilinear")(relu12)
    concat2 = concatenate([up2, relu6], axis=-1)  
    conv13 = Conv2D(num_filter * 4, 3, activation="linear", padding="same", strides=1)(concat2)
    bn13 = BatchNormalization()(conv13)
    relu13 = Activation("relu")(bn13)
    conv14 = Conv2D(num_filter * 4, 3, activation="linear", padding="same", strides=1)(relu13)
    bn14 = BatchNormalization()(conv14)
    relu14 = Activation("relu")(bn14)
    up3 = UpSampling2D(size=(2, 2), interpolation="bilinear")(relu14)
    concat3 = concatenate([up3, relu4], axis=-1) 
    conv15 = Conv2D(num_filter * 2, 3, activation="linear", padding="same", strides=1)(concat3)
    bn15 = BatchNormalization()(conv15)
    relu15 = Activation("relu")(bn15)
    conv16 = Conv2D(num_filter * 2, 3, activation="linear", padding="same", strides=1)(relu15)
    bn16 = BatchNormalization()(conv16)
    relu16 = Activation("relu")(bn16)
    up4 = UpSampling2D(size=(2, 2), interpolation="bilinear")(relu16)
    concat4 = concatenate([up4, relu2], axis=-1) 
    conv17 = Conv2D(num_filter * 1, 3, activation="linear", padding="same", strides=1)(concat4)
    bn17 = BatchNormalization()(conv17)
    relu17 = Activation("relu")(bn17)
    conv18 = Conv2D(num_filter * 1, 3, activation="linear", padding="same", strides=1)(relu17)
    bn18 = BatchNormalization()(conv18)
    relu18 = Activation("relu")(bn18)
    # Segmentation branch
    segmentation_output = Conv2D(1, 1, activation="sigmoid", name="segmentation_output")(relu18) 
    # Classification branch
    gap1 = GlobalAveragePooling2D()(relu8)
    gap2 = GlobalAveragePooling2D()(relu10)
    gap3 = GlobalAveragePooling2D()(relu12)
    conv20 = Conv2D(num_filter * 4, 3, activation="linear", padding="same", strides=1)(segmentation_output)
    bn20 = BatchNormalization()(conv20)
    relu20 = Activation("relu")(bn20)
    down5 = MaxPooling2D(pool_size=(4, 4), strides=4)(relu20)
    conv21 = Conv2D(num_filter * 4, 3, activation="linear", padding="same", strides=1)(down5)
    bn21 = BatchNormalization()(conv21)
    relu21 = Activation("relu")(bn21)
    down6 = MaxPooling2D(pool_size=(4, 4), strides=4)(relu21)
    conv22 = Conv2D(num_filter * 1, 3, activation="linear", padding="same", strides=1)(down6)
    bn22 = BatchNormalization()(conv22)
    relu22 = Activation("relu")(bn22)
    down7 = MaxPooling2D(pool_size=(4, 4), strides=4)(relu22)
    flatten1 = Flatten()(down7)
    concat5 = concatenate([gap1, gap2, gap3, flatten1], axis=-1)
    # FC layers
    fc1 = Dense(1024, activation="relu")(concat5)
    dropout1 = Dropout(0.5)(fc1)
    fc2 = Dense(1024, activation="relu")(dropout1)
    dropout2 = Dropout(0.5)(fc2)
    classification_output = Dense(num_classes, activation="softmax", name="classification_output")(dropout2)
    # Define the model
    model = Model(inputs=inputs, outputs=[classification_output, segmentation_output])
    return model"