ReLU函数是最常见的激活函数,其数学表达式和函数图像如下所示:
$$ ReLU(x) = max(0,x) $$

当人们看到ReLU函数的图像时候,总是感到疑惑,它看起来就是线性函数,怎么能实现非线性功能呢?
ReLU函数具有两面性,既有线性,又有非线性。
当 x>0 时,ReLU 表现为线性函数 f(x)=x。
当 x≤0 时,输出为 0,引入了非线性。
非线性来源:虽然 ReLU 在正区间是线性的,但其在负区间的截断(输出为 0)引入了非线性。多个 ReLU 单元的叠加可以形成复杂的非线性决策边界。
多单元组合。多个 ReLU 单元的组合可以逼近复杂的非线性函数。例如,两个 ReLU 单元可以组合成一个"V"形函数。
多层网络。在深层网络中,ReLU 的叠加能够学习到高度非线性的特征表示。
我们可以通过组合多个 ReLU 单元来实现一个非线性函数,例如一个"V"形函数。然后使用 matplotlib 绘制其示意图。
import numpy as np
import matplotlib.pyplot as plt
# 定义 ReLU 函数
def relu(x):
return np.maximum(0, x)
# 定义 V 形函数
def v_shape_function(x):
# 使用两个 ReLU 单元组合
return relu(x) + relu(-x)
# 生成输入数据
x = np.linspace(-10, 10, 500)
y = v_shape_function(x)
# 绘制图像
plt.figure(figsize=(8, 6))
plt.plot(x, y, label="V-Shaped Function", color="blue", linewidth=2)
plt.title("Nonlinear Function using ReLU", fontsize=16)
plt.xlabel("x", fontsize=14)
plt.ylabel("y", fontsize=14)
plt.grid(True, linestyle="--", alpha=0.6)
plt.axhline(0, color="black", linewidth=1)
plt.axvline(0, color="black", linewidth=1)
plt.legend()
plt.show()
定义两个 ReLU 单元:一个用于正斜率,另一个用于负斜率。组合这两个 ReLU 单元,形成一个"V"形函数。

import numpy as np
import matplotlib.pyplot as plt
# 定义 ReLU 函数
def relu(x):
return np.maximum(0, x)
# 定义 M 形函数
def double_m_shape_function(x):
# 使用五个 ReLU 单元组合
return (
relu(x + 10) - 2 * relu(x + 5) + 2 * relu(x) - 2 * relu(x - 5) + relu(x - 10)
)
# 生成输入数据
x = np.linspace(-15, 15, 500)
y = double_m_shape_function(x)
# 绘制图像
plt.figure(figsize=(8, 6))
plt.plot(x, y, label="M-Shaped Function", color="blue", linewidth=2)
plt.title("Nonlinear Function using Five ReLUs", fontsize=16)
plt.xlabel("x", fontsize=14)
plt.ylabel("y", fontsize=14)
plt.grid(True, linestyle="--", alpha=0.6)
plt.axhline(0, color="black", linewidth=1)
plt.axvline(0, color="black", linewidth=1)
plt.legend()
plt.show()
M 形函数:double_m_shape_function(x) 通过组合五个 ReLU 单元实现:
relu(x + 10):向左平移 10 个单位。
-2 * relu(x + 5):向左平移 5 个单位并向下拉伸。
2 * relu(x):不平移,向上拉伸。
-2 * relu(x - 5):向右平移 5 个单位并向下拉伸。
relu(x - 10):向右平移 10 个单位。

import numpy as np
import matplotlib.pyplot as plt
# 定义 ReLU 函数
def relu(x):
return np.maximum(0, x)
# 定义逼近正弦函数的 ReLU 组合
def relu_sine_approximation(x, n_segments=20):
# 计算每个分段的斜率和截距
segment_width = 2 * np.pi / n_segments # 每个分段的宽度
y_approx = np.zeros_like(x) # 初始化逼近结果
for i in range(n_segments):
# 分段起点和终点
start = -np.pi + i * segment_width
end = -np.pi + (i + 1) * segment_width
# 计算分段斜率
slope = (np.sin(end) - np.sin(start)) / segment_width
# 计算分段截距
intercept = np.sin(start) - slope * start
# 添加 ReLU 单元
y_approx += slope * relu(x - start) - slope * relu(x - end)
return y_approx
# 生成输入数据
x = np.linspace(-2 * np.pi, 2 * np.pi, 1000)
y_true = np.sin(x) # 真实的正弦函数
y_approx = relu_sine_approximation(x, n_segments=20) # ReLU 逼近的正弦函数
# 绘制图像
plt.figure(figsize=(10, 6))
plt.plot(x, y_true, label="True Sine Function", color="blue", linewidth=2)
plt.plot(x, y_approx, label="ReLU Approximation", color="red", linestyle="--", linewidth=2)
plt.title("Approximating Sine Function with Multiple ReLUs", fontsize=16)
plt.xlabel("x", fontsize=14)
plt.ylabel("y", fontsize=14)
plt.grid(True, linestyle="--", alpha=0.6)
plt.axhline(0, color="black", linewidth=1)
plt.axvline(0, color="black", linewidth=1)
plt.legend()
plt.show()
分段逼近。将正弦函数的一个周期(−π 到 π)分成 n_segments 个分段。对每个分段计算斜率和截距,并用 ReLU 单元拟合。
叠加 ReLU 单元。每个 ReLU 单元对应一个分段,通过斜率和截距调整其形状。将所有 ReLU 单元的输出叠加,形成对正弦函数的逼近。

蓝色曲线是真实的正弦函数。红色虚线是 ReLU 组合逼近的结果。随着 n_segments 的增加,红色虚线会越来越接近蓝色曲线,逼近效果显著提升。
n_segments:控制分段数量(ReLU 单元数量)。增加 n_segments 可以提高逼近精度,但计算量也会增加。例如,n_segments=50 已经可以很好地逼近正弦函数。如果需要更高的精度,可以尝试 n_segments=100 或更多。