Image segmentation is a crucial task in computer vision, where the goal is to classify each pixel in an image into meaningful categories. Over the years, fully-convolutional networks (FCNs) have become the go-to architecture for this task. With over four years of experience working with Python and Keras, I’ve found composable FCNs to be a flexible and powerful way to build segmentation models.
In this tutorial, I’ll guide you through how to implement image segmentation using composable fully-convolutional networks in Keras. I’ll provide complete code examples for each step, making it easy to follow along and customize for your own projects.
What Are Composable Fully-Convolutional Networks in Keras?
Composable FCNs are networks built by combining smaller convolutional blocks to form a larger segmentation model. This modular approach allows you to easily experiment with different architectures by stacking or reusing blocks.
Using Keras, you can define these blocks as functions and compose them to create complex models. This method greatly simplifies building segmentation networks and enhances readability and maintainability.
Building Blocks: Convolutional Block in Keras
A convolutional block usually consists of convolution layers, batch normalization, and activation functions. Here’s a simple reusable convolutional block I use often:
from tensorflow.keras.layers import Conv2D, BatchNormalization, Activation
def conv_block(x, filters, kernel_size=3, padding='same', strides=1):
x = Conv2D(filters, kernel_size, strides=strides, padding=padding)(x)
x = BatchNormalization()(x)
x = Activation('relu')(x)
return xThis block applies a convolution followed by normalization and ReLU activation. It’s the fundamental building unit for our composable FCN.
Encoder Module: Downsample with Composable FCN in Keras
The encoder reduces spatial dimensions while increasing feature depth, capturing context.
from tensorflow.keras.layers import MaxPooling2D
def encoder_block(x, filters):
x = conv_block(x, filters)
x = conv_block(x, filters)
p = MaxPooling2D((2, 2))(x)
return x, pThis block applies two convolutional blocks and then downsamples using max pooling. It returns both the feature map before pooling (for skip connections) and the pooled output.
Decoder Module: Upsample with Composable FCN in Keras
The decoder restores spatial resolution using upsampling and combines features from the encoder via skip connections.
from tensorflow.keras.layers import Conv2DTranspose, Concatenate
def decoder_block(x, skip_features, filters):
x = Conv2DTranspose(filters, (2, 2), strides=2, padding='same')(x)
x = Concatenate()([x, skip_features])
x = conv_block(x, filters)
x = conv_block(x, filters)
return xHere, we use transpose convolution for upsampling, concatenate the encoder features, and apply convolutional blocks to refine the output.
Compose the FCN Model in Keras
Now, let’s compose the encoder and decoder blocks into a full FCN model for segmentation.
from tensorflow.keras.layers import Input, Conv2D
from tensorflow.keras.models import Model
def build_fcn_model(input_shape, num_classes):
inputs = Input(input_shape)
# Encoder
s1, p1 = encoder_block(inputs, 64)
s2, p2 = encoder_block(p1, 128)
s3, p3 = encoder_block(p2, 256)
s4, p4 = encoder_block(p3, 512)
# Bottleneck
b1 = conv_block(p4, 1024)
b1 = conv_block(b1, 1024)
# Decoder
d1 = decoder_block(b1, s4, 512)
d2 = decoder_block(d1, s3, 256)
d3 = decoder_block(d2, s2, 128)
d4 = decoder_block(d3, s1, 64)
# Output layer
outputs = Conv2D(num_classes, 1, padding='same', activation='softmax')(d4)
model = Model(inputs, outputs, name='Composable_FCN')
return modelThis model uses four encoder and decoder blocks with a bottleneck layer in between. The final output layer predicts the class for each pixel.
Train the Composable FCN Model in Keras
To train the model, compile it with an appropriate loss and optimizer. For multi-class segmentation, categorical cross-entropy is common.
model = build_fcn_model((256, 256, 3), num_classes=3)
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
model.summary()You would then train the model on your labeled dataset using model.fit(). Make sure your labels are one-hot encoded for multi-class segmentation.
Use the Model for Prediction
After training, use the model to predict segmentation masks for new images.
import numpy as np
from tensorflow.keras.preprocessing.image import load_img, img_to_array
def preprocess_image(image_path, target_size=(256, 256)):
image = load_img(image_path, target_size=target_size)
image = img_to_array(image) / 255.0
image = np.expand_dims(image, axis=0)
return image
image = preprocess_image('sample_image.jpg')
pred_mask = model.predict(image)
pred_mask = np.argmax(pred_mask, axis=-1)[0]I executed the above example code and added the screenshot below.

This code loads and preprocesses an image, then uses the model to predict the segmentation mask.
Composable fully-convolutional networks in Keras provide a modular and intuitive way to build powerful segmentation models. The composable blocks make it easy to experiment and scale your models for complex tasks.
If you want to dive deeper, try adding dropout, experimenting with different activation functions, or integrating attention mechanisms. The modular nature of composable FCNs means you can build exactly what your project needs.
Other Python Keras tutorials you may like:
- Image Classification with BigTransfer (BiT) Using Keras
- Image Segmentation with a U-Net-Like Architecture in Keras
- Multiclass Semantic Segmentation Using DeepLabV3+ in Keras
- Highly Accurate Boundary Segmentation Using BASNet in Keras

I am Bijay Kumar, a Microsoft MVP in SharePoint. Apart from SharePoint, I started working on Python, Machine learning, and artificial intelligence for the last 5 years. During this time I got expertise in various Python libraries also like Tkinter, Pandas, NumPy, Turtle, Django, Matplotlib, Tensorflow, Scipy, Scikit-Learn, etc… for various clients in the United States, Canada, the United Kingdom, Australia, New Zealand, etc. Check out my profile.