EasyActivation Functions

Implement ReLU Activation

Activation Functions

Easy

Problem

Apply the Rectified Linear Unit elementwise:

\operatorname{ReLU}(x) = \max(0,x)

Here, x is each input value. Return the transformed values as a NumPy array with the same shape as the input.

Theory

A neural network is built from layers of linear transformations: multiply by a weight matrix, add a bias. The problem is that stacking linear functions just gives you another linear function. Two layers with no activation:

y = W_2(W_1 x + b_1) + b_2 = (W_2 W_1) x + (W_2 b_1 + b_2)

This is still just y = Ax + c, a single linear function. No matter how many layers you stack, the network can only learn linear relationships. It could never learn to classify images, understand language, or approximate complex patterns.

Activation functions break this linearity. After each linear transformation, an activation function applies a nonlinear operation element-wise. This is what gives neural networks their power to approximate any continuous function.


ReLU: The Simplest Nonlinearity

ReLU (Rectified Linear Unit) is defined as:

\text{ReLU}(x) = \max(0, x)

The rule is extremely simple:

Some examples:

The function looks like a hockey stick: flat at zero for all negative inputs, then a straight line with slope 1 for positive inputs.


Why ReLU Became Dominant

Before ReLU, the standard activations were sigmoid and tanh. Both squash their inputs into a bounded range (sigmoid to (0,1), tanh to (-1,1)). They worked, but they had a serious problem: vanishing gradients.

The vanishing gradient problem:

ReLU fixes this for positive inputs:

ReLU also has practical advantages:


The Gradient of ReLU

The derivative (used during backpropagation) is:

\frac{d}{dx} \text{ReLU}(x) = \begin{cases} 1, & \text{if } x > 0 \\ 0, & \text{if } x < 0 \end{cases}

At x = 0, the function has a sharp corner and is technically not differentiable. In practice, frameworks define the derivative at zero as 0 (some use 0.5 or 1). This does not cause problems in practice because hitting exactly $ = 0$ is extremely rare with floating-point numbers.

The gradient being exactly 1 for positive inputs is what makes ReLU so effective for deep networks. Compare this to sigmoid, where the maximum gradient is only 0.25 (at x = 0). After 10 layers of sigmoid, the gradient shrinks by a factor of $ \approx 10^{-6}$.


The Dead Neuron Problem

ReLU's main weakness: for negative inputs, the output and gradient are both exactly zero. If a neuron's weighted input is negative for every training example, it will never produce a nonzero output and never receive a nonzero gradient. It is permanently "dead."

How neurons die:

This can happen to a significant fraction of neurons, especially with high learning rates. In some networks, 10-40% of neurons can die.

Solutions that build on ReLU:


Where ReLU Is Used

ReLU is the default activation for most neural network architectures:

ReLU is less common in:

Examples

Example 1

Input
x = [-2, -1, 0, 3]
Output
[0.0, 0.0, 0.0, 3.0]
Explanation
Negative values become zero while nonnegative values remain unchanged.

Example 2

Input
x = 5
Output
5.0

Example 3

Input
x = [[-1, 2], [3, -4]]
Output
[[0.0, 2.0], [3.0, 0.0]]

Hints

  1. Convert the input with np.asarray(x, dtype=float).
  2. Use np.maximum(0.0, x) for the elementwise threshold.

Requirements

Constraints

Starter Code

import numpy as np

def relu(x) -> np.ndarray:
    """
    Returns a NumPy array with the same shape as x.
    """
    # Write code here
    pass

Test Cases

CaseMatches
Basic mixed valuespublic
Positive scalarpublic
2D arraypublic