Keras
2D input
2D output
machine learning
neural networks

Keras 2D input to 2D output

ML System Design practice on Codemia

Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.

Practice ML system design

Introduction

The phrase "2D input to 2D output" can mean two different things in Keras. Sometimes it means a standard tabular tensor shaped like (batch, features) mapped to (batch, targets). Other times it means an image-like grid shaped like (height, width) or (height, width, channels) mapped to another 2D grid.

The architecture depends on which meaning you have in mind. Dense layers are a natural fit for vector-style 2D tensors, while convolutional layers are the usual choice for image-to-image problems.

Case 1: Matrix-Like Input and Matrix-Like Output

If each sample is just a feature vector and each prediction is another vector, Keras already handles this naturally with dense layers.

python
1import tensorflow as tf
2from tensorflow import keras
3from tensorflow.keras import layers
4
5model = keras.Sequential([
6    layers.Input(shape=(8,)),
7    layers.Dense(32, activation="relu"),
8    layers.Dense(16, activation="relu"),
9    layers.Dense(4)
10])
11
12model.compile(optimizer="adam", loss="mse")
13model.summary()

Input shape here is (batch_size, 8) and output shape is (batch_size, 4). That is already "2D to 2D" in the linear algebra sense.

Use this pattern when the spatial relationship between features does not matter.

Case 2: Image-Like 2D Input to Image-Like 2D Output

If each sample is a 2D grid and you want another 2D grid out, a convolutional model is usually the correct answer. For example, an image denoiser or segmentation head often preserves height and width.

python
1import tensorflow as tf
2from tensorflow import keras
3from tensorflow.keras import layers
4
5inputs = keras.Input(shape=(64, 64, 1))
6x = layers.Conv2D(16, kernel_size=3, padding="same", activation="relu")(inputs)
7x = layers.Conv2D(16, kernel_size=3, padding="same", activation="relu")(x)
8outputs = layers.Conv2D(1, kernel_size=1, padding="same")(x)
9
10model = keras.Model(inputs, outputs)
11model.compile(optimizer="adam", loss="mse")
12model.summary()

This model maps a 64 x 64 x 1 input to a 64 x 64 x 1 output. The spatial dimensions stay the same because the convolutions use padding="same".

Why Flattening Changes the Problem

You could flatten a 2D image into a vector, pass it through dense layers, and reshape it back:

python
1inputs = keras.Input(shape=(16, 16))
2x = layers.Flatten()(inputs)
3x = layers.Dense(128, activation="relu")(x)
4x = layers.Dense(16 * 16)(x)
5outputs = layers.Reshape((16, 16))(x)
6
7model = keras.Model(inputs, outputs)

This works, but it throws away local spatial structure during the dense part of the network. For real image-like tasks, convolutional layers usually learn more efficiently because they preserve neighborhood information.

Choosing the Right Output Layer

The final layer depends on the task:

  • regression-style grid output often uses a linear final layer
  • binary mask output often uses sigmoid
  • multi-class per-pixel output often uses softmax over channels

So "2D output" is not enough information by itself. You also need to know whether the output represents continuous values, one class per location, or something else.

Common Pitfalls

  • Confusing (batch, features) with spatial 2D image data. Both are "2D" in a shape listing, but they imply different architectures.
  • Using dense layers for image-to-image tasks that would be better modeled with convolutions.
  • Forgetting the channel dimension on image-like data. Keras often expects (height, width, channels).
  • Changing the spatial size accidentally by using pooling or convolutions without appropriate padding.
  • Picking the wrong final activation for the target type.

Summary

  • "2D input to 2D output" can mean vector-to-vector or grid-to-grid.
  • Dense layers are appropriate for ordinary feature vectors.
  • Convolutional layers are usually the right choice for image-like 2D data.
  • Preserve spatial dimensions with padding="same" when the output should match the input size.
  • Always choose the model shape and final activation based on the structure of the target, not just the number of tensor dimensions.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

ML System Design practice on Codemia

Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.

Practice ML system design

All Rights Reserved.