ReLU Function: Python Examples and Use

Understanding what ReLU does to an input helps when you use it in Python. ReLU is an activation function that returns the larger of zero and its input.

I’ll show how to define a scalar ReLU function and read its output separately from its derivative, including at zero.

TL;DR: ReLU in one line

ReLU returns the larger of zero and its input, so negative values become zero while positive values pass through unchanged.

  • For one Python number, call max with zero and the value.
  • The output is the input when positive, not the number 1.
  • Its derivative is zero below zero and one above zero. The point at zero needs a framework convention.

What is the ReLU function?

ReLU(x) = max(0, x)

The function is linear on either side of zero, but the switch between its branches makes it nonlinear overall. Google’s activation-function guide explains the role of nonlinearity in a neural network.

Some units contribute zero to the next layer for a particular input, a condition called sparse activation.

For input features x₁ through xₙ, the pre-activation can be written as z = w₁x₁ + w₂x₂ + … + wₙxₙ + b. A weight controls the contribution of its feature, while the bias shifts the sum.

For a hand calculation, take features 1 and 2, weights -1 and 1, and bias -0.5. Their weighted sum is (-1 × 1) + (1 × 2) – 0.5 = 0.5, so ReLU returns 0.5. Changing the bias to -1.5 makes the sum -0.5, which the activation maps to zero.

ReLU is often compared with sigmoid because both can follow a weighted sum in a network. Sigmoid compresses every input into a bounded range, while ReLU leaves positive magnitudes unbounded. In sigmoid’s saturated tails, small changes to its input produce small local derivatives.

Choose the output activation for the task. A regression model may need negative predictions, while a classifier that needs probabilities uses a transformation designed for its label setup.

How to implement ReLU in Python step by step

A short Python function makes the rule executable without adding a dependency. The following steps define it, exercise three inputs, and compare its negative branch with Leaky ReLU.

Step 1: Define a scalar ReLU function

Python’s built-in max() accepts two numeric arguments and returns the larger one, making it suitable for the scalar formula.

def relu(value):
    return max(0.0, value)

In this definition, value is the parameter name. A call supplies one argument for that name, and return sends the selected result back to the caller. This small helper is useful for understanding the scalar rule without importing a numerical package.

Step 2: Check negative, zero and positive inputs

Testing one value on each side of zero shows the whole rule, including the boundary. I ran a named Python file with these inputs and printed both ReLU and Leaky ReLU results.

def relu(value):
    return max(0.0, value)


def leaky_relu(value, alpha=0.01):
    return value if value >= 0 else alpha * value


values = [-2.0, 0.0, 3.0]
print("ReLU:", [relu(value) for value in values])
print("Leaky ReLU (alpha=0.01):", [leaky_relu(value) for value in values])
print("ReLU derivative away from zero:", [0 if value < 0 else 1 for value in values])

The exact output is:

ReLU: [0.0, 0.0, 3.0]
Leaky ReLU (alpha=0.01): [-0.02, 0.0, 3.0]
ReLU derivative away from zero: [0, 1]
Terminal output comparing ReLU and Leaky ReLU values
The script prints outputs for negative, zero and positive inputs and lists derivatives only away from zero.

This is the exact output from the named Python file for its three selected inputs.

Step 3: Read the output and derivative separately

The same neuron can receive a positive pre-activation for one example and a negative value for another.

The chain rule combines the activation’s local rate of change with the gradient from the loss. That product controls how much gradient passes backward to earlier operations.

The function is continuous at zero, so its returned value is clear there. Its graph has a corner at that point, which is why the ordinary derivative is undefined even though the output is zero. Autodifferentiation systems need a defined backward-pass convention to compute with that corner.

A framework’s documented backward-pass convention supplies the gradient at x = 0. The scalar helper above computes the forward value. In hand calculations, keep the boundary separate from the two derivative branches.

The derivative here is with respect to z, the activation input. Calculating a weight’s gradient also uses its feature value and the downstream loss gradient, combined for each example in a batch. Batch size changes how many examples contribute before an update, not the pointwise ReLU rule.

The PyTorch ReLU module applies the operation element-wise to tensors. Use the matching framework operation when the model’s values are tensors.

The scalar helper above illustrates one forward calculation. A framework layer records tensor operations so a training library can calculate parameter gradients.

ReLU edge cases and Leaky ReLU

Several surprises come from confusing scalar Python code with array operations, omitting the input, or treating a derivative as an output. These cases change how you write the function or interpret training behavior. A call can fail before any activation is computed.

CaseWhat happensWhat to do
Negative scalar inputReLU returns 0. Its derivative on this branch is 0Use a leaky variant only when retaining a negative-side slope fits the model
Input equals zeroOutput is 0. Ordinary derivative is undefined at the cornerFollow the framework’s documented gradient convention
Positive scalar inputOutput equals the input. Derivative is 1Do not replace the output with 1
Python list or arrayBuilt-in max() compares items as a collection, not element by elementUse a vectorized array or tensor operation
Missing function argumentPython raises a TypeError naming the required parameterPass one numeric value to the scalar helper

For arrays, use an element-wise maximum operation from the library that owns the data. A plain Python list can use a list comprehension that calls the scalar helper for each value. Python’s max() can also accept an iterable, but that form returns one largest member rather than a ReLU result for every member.

Complex numbers have no ordering against 0.0 in Python, so this scalar helper raises a TypeError for them.

I ran the helper without its required value and got this error: TypeError: relu() missing 1 required positional argument: ‘values’. Supply one number when calling this scalar helper. The traceback points to the call that omitted it.

Python TypeError from calling the ReLU helper without its required argument
Terminal window showing the failed function call and traceback.

Leaky ReLU applies αx for x < 0 and keeps x for x ≥ 0.

See the Keras activation API and AskPython’s Leaky ReLU guide for implementation details.

For 0 < α < 1, a negative output keeps its sign with reduced magnitude, while α sets the local slope of that branch.

Choose a variant when measurements give you a reason to alter the negative branch.

Inspect zero-activation rates across representative batches when investigating a dying ReLU. A unit can remain inactive on relevant training examples when its pre-activation stays negative, passing no local gradient through that path. A leaky variant adds a negative-side slope, but test it rather than assuming it will repair training.

A broader overview of activation functions in Python includes alternatives such as sigmoid.

How does ReLU compare with GELU?

GELU is another activation available in neural-network libraries. PyTorch defines it as x multiplied by the standard normal cumulative distribution function at x, rather than a hard zero threshold. Its response around zero is smooth and can retain a scaled negative value.

ActivationNegative input behaviorBoundary behavior
ReLUReturns zero for negative valuesHas a corner at zero
GELUScales inputs using the Gaussian cumulative distributionChanges smoothly through zero

The PyTorch GELU documentation describes exact and tanh-approximate forms. A scalar comparison explains the curves, while a trained model’s validation results show which operation suits its task.

When should you test a different activation?

Use training evidence to decide whether an alternative improves the model. A small scalar example confirms behavior but cannot answer this model-level question.

ObservationNext check
Training loss falls but validation performance does not improveCheck held-out metrics and compare against the same baseline settings
Many units output zero on representative batchesInspect pre-activations and test an alternative activation in a controlled comparison
Results vary between runsRepeat the comparison and review variation, not just one run
  • Compare validation results as well as the training loss while holding the data split and other settings fixed.
  • Track how often hidden units output zero across representative batches.

Training loss describes fit to training examples, while validation results describe performance on held-out examples. Zero-output frequency helps locate units that stay on ReLU’s zero branch. Interpret these signals together when reviewing an activation change.

Start with a baseline model and change only its activation, keeping all other model and evaluation settings fixed. Repeat training when results vary, and choose a task-relevant metric such as a held-out classification score or regression error measure. Compare the runs to decide whether the change helps on the intended data.

Conclusion

The key distinction is between a scalar calculation for one value and a framework layer that participates in a model’s tensor operations.

For related reading, continue with building neural networks in Python or compare this function with AskPython’s sigmoid activation function tutorial. The Python, PyTorch and Keras documentation linked above specify the operations for each environment.

FAQ

These answers clarify common questions about ReLU’s shape, output and alternatives.

Is ReLU a linear function?

ReLU is linear on its negative and positive branches, but the change at zero makes the complete function nonlinear.

What does ReLU return for a positive input?

It returns the input unchanged. For example, ReLU(3) returns 3, not 1.

What is Leaky ReLU?

Leaky ReLU returns a scaled input for negative values and passes non-negative values through, using a selected negative-side slope.

Can Python max() apply ReLU to a NumPy array?

Built-in max() is not an element-wise array operation. Use an element-wise operation provided by the array or tensor framework.

What does ReLU return at zero?

It returns zero. Its ordinary derivative is undefined at the corner, so frameworks document a backward-pass convention.

Why is ReLU common in hidden layers?

Its rule is simple and introduces a nonlinear branch switch; whether it fits a model depends on the task and training behavior.

What is the difference between ReLU and GELU?

ReLU zeros negative inputs. GELU scales values with a smooth Gaussian-based response, including around zero.

Does Leaky ReLU change positive inputs?

No. It uses a selected slope for negative inputs and passes zero and positive inputs through.

Safa Mulani
Safa Mulani

An enthusiast in every forthcoming wonders!

Articles: 189