A network can run perfectly, produce tensors of the expected shape, and still be mathematically incapable of learning the task you gave it. A ReLU output may be asked to behave like a probability. A softmax may be used where several labels can be true. A loss may quietly expect logits while receiving probabilities.
Activation functions and loss functions do different jobs, but those jobs meet at the output layer. An activation changes a representation; a loss turns predictions and targets into the objective used for training. Choosing them together prevents a surprising number of silent mistakes.
Activation Functions
1. ReLU
For :
At zero, frameworks choose a convenient subgradient, usually 0. ReLU is cheap and keeps a non-saturating derivative on its positive side. It does not guarantee that half the units will be active, and a unit that receives only negative pre-activations can stop learning.
Typical use: hidden layers in convolutional and dense networks.
2. Leaky ReLU
Leaky ReLU keeps a small derivative on the negative side. This reduces the risk of permanently inactive units but does not make it impossible. Parametric ReLU learns rather than fixing it.
Typical use: a ReLU alternative when negative-side gradient flow helps.
3. Sigmoid
Sigmoid maps a logit to and is a natural output transformation for a binary event or independent multilabel targets. A number in this range can be interpreted as a model probability, but it is not automatically calibrated. Calibration has to be checked on representative held-out data.
Large positive or negative inputs saturate the function and produce small derivatives. For that reason, sigmoid is less common in ordinary hidden layers.
4. Tanh
Tanh is zero-centered and maps to , but it also saturates at large magnitudes. In recurrent networks it is commonly used for candidate values and hidden-state updates, while sigmoid usually controls the gates themselves. It also appears in small networks where a bounded output is useful.
5. Softmax
For logits :
The outputs are positive and sum to one. The full Jacobian is:
This covers both cases: when and otherwise.
For numerical stability, compute exp(z - max(z)), or use a library function. During training, prefer a cross-entropy operation that accepts logits so the framework can combine log-softmax and negative log-likelihood stably.
Typical use: one-of- classification. It is not appropriate when several labels may be true independently; use one sigmoid per label for that case.
6. ELU
ELU has negative outputs and a smooth negative branch. The left derivative at zero is , while the right derivative is 1, so the function is differentiable at zero only when . It costs more to evaluate than ReLU and does not replace normalization or regularization by itself.
7. SELU
The standard constants are approximately and . SELU was designed for self-normalizing feed-forward networks, but that behavior depends on conditions including standardized inputs, LeCun-normal initialization, sufficiently wide layers, and AlphaDropout when dropout is used. It is not an automatic normalization guarantee for any architecture.
8. GELU
GELU weights an input by a Gaussian cumulative probability:
It is smooth and widely used in transformer feed-forward blocks. As with every activation, its value is empirical and architectural rather than universal.
Loss Functions
1. Mean Squared Error
For predictions:
MSE is common for regression and corresponds to a Gaussian-noise assumption when variance is treated appropriately. It is convex in the predictions and in the parameters of an ordinary linear model, but not generally in the parameters of a neural network. Squaring makes it sensitive to large residuals.
2. Binary Cross-Entropy
Binary cross-entropy is non-negative and unbounded above. Use it for a binary target or independently modeled multilabel targets. In training code, pass logits to a stable operation such as BinaryCrossentropy(from_logits=True) rather than manually applying sigmoid and taking logarithms.
3. Categorical Cross-Entropy
For a one-hot target and a categorical distribution :
Use sparse categorical cross-entropy when the target is an integer class index. Softmax and categorical cross-entropy are normally combined from logits for numerical stability.
4. Focal Loss
For the probability assigned to the true class:
The focusing parameter reduces the contribution of well-classified examples, while can adjust class weighting. Focal loss was introduced for dense object detection. It can help with some imbalanced datasets, but it does not automatically correct bad labels, sampling bias, probability calibration, or a mismatch between the metric and training objective.
5. Huber Loss
Let . For threshold :
The derivative with respect to the prediction is:
Huber loss is quadratic near zero and linear for large residuals, so it is less sensitive to outliers than MSE. The choice of should reflect the scale of the target or residuals.
6. Hinge Loss
For label and score :
Hinge loss trains a margin rather than a probability and is associated with support-vector machines. A score trained with hinge loss should not be presented as a calibrated probability without an additional calibration step.
TensorFlow Examples
import tensorflow as tf
x = tf.constant([-2.0, 0.0, 2.0])
relu = tf.nn.relu(x)leaky_relu = tf.nn.leaky_relu(x, alpha=0.01)sigmoid = tf.nn.sigmoid(x)tanh = tf.nn.tanh(x)softmax = tf.nn.softmax(x)elu_alpha_1 = tf.nn.elu(x) # tf.nn.elu fixes alpha at 1selu = tf.nn.selu(x)gelu = tf.nn.gelu(x)
y_true = tf.constant([[1.0], [0.0]])logits = tf.constant([[1.2], [-0.7]])
bce = tf.keras.losses.BinaryCrossentropy(from_logits=True)print("Binary cross-entropy:", float(bce(y_true, logits)))
predictions = tf.constant([[2.5], [-0.2]])targets = tf.constant([[3.0], [0.0]])
print("MSE:", float(tf.keras.losses.MeanSquaredError()(targets, predictions)))print("Huber:", float(tf.keras.losses.Huber(delta=1.0)(targets, predictions)))For ELU with a configurable , implement the two branches explicitly or use a Keras layer whose documented API exposes that parameter. Accepting an alpha argument and then calling tf.nn.elu would be misleading because tf.nn.elu uses .
Stable NumPy softmax looks like this:
import numpy as np
def softmax(values, axis=-1): shifted = values - np.max(values, axis=axis, keepdims=True) exponentials = np.exp(shifted) return exponentials / np.sum(exponentials, axis=axis, keepdims=True)Choosing the Output and Loss Together
| Task | Model output | Training loss |
|---|---|---|
| Real-valued regression | Linear value | MSE, MAE, Huber, or a suitable likelihood |
| Binary classification | One logit | Binary cross-entropy from logits |
| Independent multilabel classification | One logit per label | Binary cross-entropy from logits |
| Mutually exclusive multiclass classification | One logit per class | Categorical cross-entropy from logits |
| Margin-based binary classification | Unbounded score | Hinge loss with targets |
Hidden-layer activations such as ReLU, ELU, or GELU do not pair directly with a particular loss. The important pairing is between the output representation, target encoding, and loss.
Conclusion
Activation and loss functions are not interchangeable ingredients. Hidden activations shape gradient flow and representation; the output and loss encode what the model is claiming about its target. Choose that claim first, use a stable combined loss implementation, and check the assumptions against the data.