A depthwise separable convolution is a practical replacement for a standard convolution when a convnet needs to be smaller and less costly to run. It first finds spatial patterns independently in each input channel, then uses a 1 × 1 pointwise convolution to mix information across channels. In Keras, the layer is called SeparableConv2D. section 9.4
Use one in an R/Keras convnet
A convnet can place `layer_separable_conv_2d(32, 3, padding = "same", use_bias = FALSE)` after batch normalization and a ReLU activation. Here, `32` sets the output-channel count and `3` sets the spatial kernel size. A larger dogs-versus-cats model repeats two separable convolutions per block, then pools and adds a residual connection. section 9.5
Figure 9.4 Depthwise separable convolution: a depthwise convolution followed by a pointwise convolution
Follow the two stages in order: separate spatial filtering for each channel, then pointwise mixing across channels. section 9.4
Separating these jobs encodes an assumption: spatial locations in intermediate activations are strongly related, while different channels are relatively independent. When that assumption fits the data, the layer can use fewer parameters and computations than regular convolution while retaining comparable representational power. This is especially useful for small models trained from scratch on limited data. section 9.4
inputs <- keras_input(shape = c(180, 180, 3))
x <- inputs |>
layer_rescaling(scale = 1 / 255) |> #1
layer_conv_2d(filters = 32, kernel_size = 5, use_bias = FALSE) #2
for (size in c(32, 64, 128, 256, 512)) { #3
residual <- x
x <- x |>
layer_batch_normalization() |>
layer_activation("relu") |>
layer_separable_conv_2d(size, 3, padding = "same", use_bias = FALSE) |>
layer_batch_normalization() |>
layer_activation("relu") |>
layer_separable_conv_2d(size, 3, padding = "same", use_bias = FALSE) |>
layer_max_pooling_2d(pool_size = 3, strides = 2, padding = "same")
residual <- residual |>
layer_conv_2d(size, 1, strides = 2, padding = "same", use_bias = FALSE)
x <- layer_add(x, residual)
}
outputs <- x |>
layer_global_average_pooling_2d() |>
layer_dropout(0.5) |> #4
layer_dense(1, activation = "sigmoid")
model <- keras_model(inputs, outputs)
Inspect how separable convolutions sit alongside batch normalization, pooling, and residual connections in a mini Xception-like architecture. section 9.5
In the dogs-versus-cats comparison, the Xception-like model has 721,857 trainable parameters and reaches 89.0% test accuracy, versus 1,569,089 parameters and 82.9% accuracy for the earlier model. The improvement belongs to the combined architecture choices; it is not an isolated measurement of the separable layers. section 9.5

