Keras Basics — Models, Layers, and Tensors
Keras Basics
3 min read
Published Nov 17 2025, updated Aug 17 2026
Guide Sections
Guide Comments
Keras models are built from layers, and layers operate on tensors.
What a Tensor Is
A tensor is just an N-dimensional array (a generalisation of scalars, vectors, and matrices).
Examples:
- Scalar → 0D tensor
- Vector → 1D tensor
- Matrix → 2D tensor
- Image → 3D tensor (height × width × channels)
- Batch of images → 4D tensor (batch × H × W × C)
In Keras/TensorFlow, your input data will always be a tensor or converted into one.
You don’t usually work with tensors manually, Keras handles it for you, but you must know your input shape.
What a Layer Is
A layer is a transformation applied to data.
Examples:
Denselayer → uses weights + bias to turn one tensor into anotherConv2Dlayer → performs convolution on imagesLSTMlayer → processes sequencesDropout→ randomly drops activations to reduce overfittingBatchNormalization→ stabilises trainingFlatten→ converts 2D/3D tensors into 1D tensors
Each layer takes a tensor, applies a transformation, outputs another tensor.
What a Model Is
A Keras model is just a connected stack (or graph) of layers.
Two main types:
- Sequential API → simple stacks
- Functional API → flexible graphs
Sequential API (Simple Models)
Use Sequential when the architecture is linear:
input → layer → layer → layer → outputExample: Simple feed-forward network
from tensorflow import kerasfrom tensorflow.keras import layersmodel = keras.Sequential([ layers.Dense(64, activation='relu', input_shape=(784,)), layers.Dense(10, activation='softmax')])model.summary()Output:
Model: "sequential"┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┓┃ Layer (type) ┃ Output Shape ┃ Param # ┃┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━┩│ dense (Dense) │ (None, 64) │ 50,240 │├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤│ dense_1 (Dense) │ (None, 10) │ 650 │└──────────────────────────────────────┴─────────────────────────────┴─────────────────┘ Total params: 50,890 (198.79 KB) Trainable params: 50,890 (198.79 KB) Non-trainable params: 0 (0.00 B)Output explanation:
- Each layer's type
- Output shape
- Number of parameters
- Total trainable parameters
Sequential is perfect for:
- Small MLPs
- Basic CNNs
- Many educational models
But it cannot do:
- Multi-input networks
- Multi-output networks
- Skip connections
- Complex architectures
Functional API (Flexible and Modern)
Functional API is recommended for most real projects.
Example:
from tensorflow import kerasfrom tensorflow.keras import layersinputs = keras.Input(shape=(784,))x = layers.Dense(64, activation='relu')(inputs)outputs = layers.Dense(10, activation='softmax')(x)model = keras.Model(inputs, outputs)model.summary()Output:
Model: "functional"┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┓┃ Layer (type) ┃ Output Shape ┃ Param # ┃┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━┩│ input_layer (InputLayer) │ (None, 784) │ 0 │├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤│ dense (Dense) │ (None, 64) │ 50,240 │├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤│ dense_1 (Dense) │ (None, 10) │ 650 │└──────────────────────────────────────┴─────────────────────────────┴─────────────────┘ Total params: 50,890 (198.79 KB) Trainable params: 50,890 (198.79 KB) Non-trainable params: 0 (0.00 B)Why use Functional API?
- You can create flexible, non-linear topologies
- You can reuse layers
- You can build multi-branch / multi-output models
- You can build architectures like ResNet, U-Net, Transformers
Input Shapes
You must know the shape of your data.
Some examples from test data:
- MNIST image (28×28 grayscale) - (batch, 28, 28)
- CIFAR-10 image (32×32 RGB) - (batch, 32, 32, 3)
- Flattened MNIST - (batch, 784)
Almost all training bugs come from incorrect input shapes.
Layers: The Most Common Types
Dense (Fully Connected)
layers.Dense(64, activation='relu')Used for:
- Classification (MLP)
- Regression
- Final layers in CNNs / RNNs
Convolutional Layers (Images)
layers.Conv2D(32, kernel_size=3, activation='relu')layers.MaxPooling2D(pool_size=2)Recurrent Layers (Sequences)
layers.LSTM(64)layers.GRU(64)Preprocessing Layers
layers.Normalization()layers.Rescaling(1./255)layers.TextVectorization()Regularisation
layers.Dropout(0.5)layers.BatchNormalization()Model Summary
Every time you build a model:
model.summary()You get:
- Layer names
- Output shapes
- Parameter counts
- Total number of weights
This instantly tells you:
- Did you pass the right input shape?
- Did a Flatten layer go missing?
- Does the architecture look correct?
Example: End-to-End Mini Model with Real Data
We won't train it fully yet, this is just to show shape and flow.
Using MNIST data:
from tensorflow.keras import datasetsfrom tensorflow import kerasfrom tensorflow.keras import layers(x_train, y_train), (x_test, y_test) = datasets.mnist.load_data()x_train = x_train.reshape(-1, 28*28) / 255.0Build model:
model = keras.Sequential([ layers.Dense(128, activation='relu', input_shape=(784,)), layers.Dense(10, activation='softmax')])Check structure:
model.summary()Output:
Model: "sequential"┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┓┃ Layer (type) ┃ Output Shape ┃ Param # ┃┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━┩│ dense (Dense) │ (None, 128) │ 100,480 │├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤│ dense_1 (Dense) │ (None, 10) │ 1,290 │└──────────────────────────────────────┴─────────────────────────────┴─────────────────┘ Total params: 101,770 (397.54 KB) Trainable params: 101,770 (397.54 KB) Non-trainable params: 0 (0.00 B)This confirms the tensor shapes flow correctly.
Debugging Common Shape Errors
Error: Expected shape (None, 784) but got (None, 28, 28)
Fix:
Add a flatten layer:
layers.Flatten(input_shape=(28,28))Error: Input shape mismatch between Functional layers
Fix:
Ensure you apply layers to the same tensor objects.