A single perceptron computes a weighted sum of inputs plus a bias, passes it through an activation, and outputs a value — essentially logistic regression with a step/sigmoid activation. It can only draw a straight-line decision boundary.
A Multi-Layer Perceptron (MLP) stacks several such layers with non-linear activations in between — this is what lets it approximate curved, complex decision boundaries a single perceptron can't.
Squashes to (0,1). Saturates for large |x| → gradients near zero → slows/stalls learning in deep nets ("vanishing gradient"). Mostly reserved for binary output layers now.
Squashes to (−1,1), zero-centered (a bit better than sigmoid for hidden layers) — but still saturates at the extremes, same vanishing-gradient issue.
max(0, x). No saturation on the positive side, cheap to compute, gradient is either 0 or 1 — the default choice for hidden layers in most modern networks.
Allows a small non-zero slope for x<0 (e.g. 0.01x) instead of a hard zero — fixes the "dying ReLU" problem where a neuron gets stuck always outputting 0.
Converts a vector of raw scores into probabilities that sum to 1 — used in the output layer for multi-class classification, not hidden layers.
Forward pass: input flows layer by layer — each layer computes weighted sum + activation — until it produces a prediction, which is compared to the true label via the loss function.
Backward pass: the error is propagated backward through the network using the chain rule — each layer asks "how much did I contribute to the final error, and in which direction should my weights move to reduce it?" Gradients flow from the output layer back to the input layer, layer by layer, each one reusing the gradient computed by the layer after it.
| Loss | Use when | Why |
|---|---|---|
| MSE (Mean Squared Error) | Regression — continuous target | Penalizes larger errors more heavily; smooth gradient everywhere. |
| Cross-Entropy | Classification (binary or multi-class) | Directly measures the distance between predicted and true probability distributions; pairs naturally with sigmoid/softmax outputs and produces well-behaved gradients for classification. |
| Optimizer | Idea | Practical note |
|---|---|---|
| SGD | Update weights using the gradient from one (or a mini-batch of) example(s) | Simple, but noisy path and can be slow to converge, especially in narrow/steep valleys. |
| Momentum | Adds a "velocity" term that accumulates past gradients | Smooths out the noisy zig-zag path and speeds convergence, like a ball rolling downhill gaining momentum. |
| RMSProp | Divides the learning rate by a running average of recent squared gradients per-parameter | Adapts step size per parameter — bigger steps for rarely-updated weights, smaller for frequently-large-gradient ones. |
| Adam | Combines Momentum (first moment) + RMSProp (second moment) | The default go-to optimizer in practice — fast convergence, works well with little tuning across many problem types. |
In deep networks, gradients are products of many layers' local derivatives (chain rule). If those local derivatives are consistently <1 (e.g. sigmoid/tanh saturation), the product shrinks toward zero as it propagates back — early layers barely learn (vanishing). If they're consistently >1, the product explodes (exploding), causing unstable, huge weight updates.
| Problem | Common fixes |
|---|---|
| Vanishing gradient | ReLU-family activations, careful weight initialization (He/Xavier), batch normalization, residual/skip connections (as in ResNets), LSTM/GRU gating for sequence models. |
| Exploding gradient | Gradient clipping (cap the gradient norm), smaller learning rate, careful weight initialization. |
Normalizes each layer's inputs (per mini-batch) to have roughly zero mean and unit variance, then applies a learned scale/shift — keeps activations in a stable, well-behaved range as they flow through the network.
During training, randomly "switches off" a fraction of neurons (e.g. 20–50%) on each forward pass, forcing the network not to rely too heavily on any single neuron or co-adapted group of neurons.
# Keras from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Dense, Dropout, BatchNormalization model = Sequential([ Dense(64, activation='relu', input_shape=(n_features,)), BatchNormalization(), Dropout(0.3), Dense(32, activation='relu'), Dense(1, activation='sigmoid') # binary classification ]) model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy']) model.fit(X_train, y_train, epochs=20, batch_size=32, validation_split=0.2)
# PyTorch import torch.nn as nn model = nn.Sequential( nn.Linear(n_features, 64), nn.ReLU(), nn.BatchNorm1d(64), nn.Dropout(0.3), nn.Linear(64, 32), nn.ReLU(), nn.Linear(32, 1), nn.Sigmoid() ) criterion = nn.BCELoss() optimizer = torch.optim.Adam(model.parameters(), lr=0.001)