def fcn8_decoder(convs, n_classes):
f1, f2, f3, f4, p5 = convs
n = 4096
c6 = tf.keras.layers.Conv2D(
n, (7, 7), activation='relu', padding='same',
name="conv6")(p5)
c7 = tf.keras.layers.Conv2D(
n, (1, 1), activation='relu', padding='same',
name="conv7")(c6)
f5 = c7
# upsample the output of the encoder
# then crop extra pixels that were introduced
o = tf.keras.layers.Conv2DTranspose(n_classes, kernel_size=(
4, 4), strides=(2, 2), use_bias=False)(f5)
o = tf.keras.layers.Cropping2D(cropping=(1, 1))(o)
# load the pool 4 prediction and do a 1x1
# convolution to reshape it to the same shape of `o` above
o2 = f4
o2 = (tf.keras.layers.Conv2D(n_classes, (1, 1),
activation='relu',
padding='same'))(o2)
# add the results of the upsampling and pool 4 prediction
o = tf.keras.layers.Add()([o, o2])
# upsample the resulting tensor of the operation you just did
o = (tf.keras.layers.Conv2DTranspose(
n_classes, kernel_size=(4, 4), strides=(2, 2),
use_bias=False))(o)
o = tf.keras.layers.Cropping2D(cropping=(1, 1))(o)
# load the pool 3 prediction and do a 1x1
# convolution to reshape it to the same shape of `o` above
o2 = f3
o2 = (tf.keras.layers.Conv2D(n_classes, (1, 1),
activation='relu',
padding='same'))(o2)
# add the results of the upsampling and pool 3 prediction
o = tf.keras.layers.Add()([o, o2])
# upsample up to the size of the original image
o = tf.keras.layers.Conv2DTranspose(
n_classes, kernel_size=(8, 8), strides=(8, 8),
use_bias=False)(o)
# append a softmax to get the class probabilities
o = tf.keras.layers.Activation('softmax')(o)
return o