Parametric Rectified Linear Unit(PReLU) 是ReLU激活函数的一个改进版本。它的核心思想是将ReLU中负值区域的固定斜率(在Leaky ReLU中是一个小的常数值,如0.01)变成一个可学习的参数。这使得神经网络能够通过训练数据自动学习出最适合当前任务的负值区域斜率,从而获得更大的灵活性和潜在的更好性能。
PReLU函数的数学公式如下所示:
$ PReLU(x) = \left \{ \begin{array}{ll} x,& x>0 \\ a_i x,& x \leq 0 \end{array} \right.$
PReLU函数中,参数$\alpha$通常为0到1之间的数字,并且通常相对较小。$\alpha$是一个可学习的参数。在训练开始时,它通常被初始化为一个小的值(如0.25),然后通过梯度下降(如Adam、SGD等优化器)自动更新。
如果$\alpha_i = 0$,则$PReLU(x)$变为$ReLU(x)$
如果$\alpha_i > 0$,则$PReLU(x)$变为$Leaky ReLU(x)$
在负值域,PReLU的斜率较小,这也可以避免Dead ReLU问题。如下所示:
import matplotlib.pyplot as plt
import torch
import torch.nn as nn
# 设置中文字体支持
plt.rcParams["font.sans-serif"] = ["SimHei"]
plt.rcParams["axes.unicode_minus"] = False
# 展示 PReLU 在神经网络中的实际应用效果
# 创建一个简单的神经网络并可视化激活函数的输出分布
# 生成随机输入数据
torch.manual_seed(42)
input_data = torch.randn(1000, 10) # 1000个样本,每个样本10个特征
# 创建带有 PReLU 的简单网络层
layer = nn.Sequential(
nn.Linear(10, 50),
nn.PReLU(num_parameters=50) # 每个通道有自己的参数
)
# 通过网络前向传播
with torch.no_grad():
output = layer(input_data)
# 绘制激活前后的分布对比
plt.figure(figsize=(12, 5))
plt.subplot(1, 2, 1)
plt.hist(input_data.flatten().numpy(), bins=50, alpha=0.7, color="blue")
plt.title("输入数据分布", fontsize=14)
plt.xlabel("值", fontsize=12)
plt.ylabel("频率", fontsize=12)
plt.subplot(1, 2, 2)
plt.hist(output.flatten().numpy(), bins=50, alpha=0.7, color="red")
plt.title("PReLU激活后数据分布", fontsize=14)
plt.xlabel("值", fontsize=12)
plt.ylabel("频率", fontsize=12)
plt.tight_layout()
plt.show()

通道共享(Channel-Shared): 同一层中的所有激活函数共享同一个 α 参数。这样增加的参数量极少(每层只多一个参数)。
通道独享(Channel-Wise): 更常见的方式是,在卷积神经网络(CNN)中,每个通道(channel)都有自己独立的 α 参数。例如,如果某一卷积层的输出有256个通道,那么就会引入256个新的 α 参数。
即使采用通道独享的方式,PReLU为整个网络增加的参数量也是微不足道的,几乎不会影响模型大小和计算速度。
α 参数与网络的权重(Weights)和偏置(Biases)一样,通过反向传播和梯度下降进行更新。
更新公式为: $\alpha := \alpha - \eta \cdot \frac{\partial L}{\partial \alpha}$,其中 L 是损失函数,η 是学习率。
由于负值区域也有梯度 $\alpha$,信号可以在整个网络中更有效地反向传播,有效缓解了深层网络中的梯度消失问题。
import matplotlib.pyplot as plt
import torch
import torch.nn as nn
# 设置中文字体支持
plt.rcParams["font.sans-serif"] = ["SimHei"]
plt.rcParams["axes.unicode_minus"] = False
# 创建 PReLU 函数
def prelu(x, a):
return torch.where(x > 0, x, a * x)
# 生成输入数据
x = torch.linspace(-5, 5, 1000)
# 不同 alpha 参数的 PReLU
alphas = [0.1, 0.25, 0.5, 1.0]
colors = ["r", "g", "b", "m"]
labels = [f"PReLU (α={a})" for a in alphas]
# 创建图形
plt.figure(figsize=(12, 8))
# 绘制不同 alpha 值的 PReLU
for i, alpha in enumerate(alphas):
y = prelu(x, alpha)
plt.plot(x.numpy(), y.numpy(), color=colors[i], label=labels[i], linewidth=2)
# 绘制 ReLU 和 LeakyReLU 作为对比
plt.plot(x.numpy(), nn.ReLU()(x).numpy(), "k--", label="ReLU", linewidth=2)
plt.plot(x.numpy(), nn.LeakyReLU(0.01)(x).numpy(), "c--", label="LeakyReLU (0.01)", linewidth=2)
# 设置图形属性
plt.title("PReLU 激活函数与其它激活函数对比", fontsize=16)
plt.xlabel("输入值 (x)", fontsize=14)
plt.ylabel("输出值 (f(x))", fontsize=14)
plt.legend(fontsize=12)
plt.grid(True, alpha=0.3)
plt.axhline(0, color="black", linewidth=0.5)
plt.axvline(0, color="black", linewidth=0.5)
plt.xlim(-5, 5)
plt.ylim(-2, 5)
# 添加注释
plt.annotate("负值区域有不同斜率", xy=(-3, -0.5), xytext=(-4, -1.5),
arrowprops=dict(arrowstyle="->", color="red"),
fontsize=12, color="red")
plt.tight_layout()
plt.show()

import matplotlib.pyplot as plt
import torch
import torch.nn as nn
# 设置中文字体支持
plt.rcParams["font.sans-serif"] = ["SimHei"]
plt.rcParams["axes.unicode_minus"] = False
# 生成随机输入数据
torch.manual_seed(42)
input_data = torch.randn(1000, 10) # 1000个样本,每个样本10个特征
# 展示不同激活函数的输出分布对比
activations = {
"ReLU": nn.ReLU(),
"LeakyReLU(0.01)": nn.LeakyReLU(0.01),
"PReLU(0.25)": nn.PReLU(num_parameters=1, init=0.25),
"PReLU(0.5)": nn.PReLU(num_parameters=1, init=0.5)
}
plt.figure(figsize=(14, 10))
for i, (name, activation) in enumerate(activations.items()):
plt.subplot(2, 2, i+1)
with torch.no_grad():
activated = activation(input_data)
plt.hist(activated.flatten().numpy(), bins=50, alpha=0.7)
plt.title(f"{name} 输出分布", fontsize=14)
plt.xlabel("值", fontsize=12)
plt.ylabel("频率", fontsize=12)
plt.tight_layout()
plt.show()

缓解死亡ReLU问题:负值区域有梯度,神经元不会完全“死亡”。
自适应学习:网络自动学习最优的激活函数形态,避免了手动调整超参数的麻烦,可能获得比ReLU和Leaky ReLU更好的性能。
几乎无额外成本:增加的参数量非常少,计算开销几乎可以忽略不计。
过拟合风险:引入了额外的参数,理论上增加了过拟合的风险,但在实践中,由于其参数量极少,这种风险通常很小,可以通过正则化技术缓解。
需要更多迭代:有时可能需要比ReLU更多的迭代次数才能收敛到最佳性能。
PReLU在2015年由何恺明等人在论文《Delving Deep into Rectifiers: Surpassing Human-Level Performance on ImageNet Classification》中提出,并在ImageNet图像分类任务上展示了其优越性。
它特别适用于深度卷积神经网络(CNN),尤其是在计算机视觉任务中(如图像分类、目标检测)。当使用ReLU时遇到明显的“神经元死亡”问题,导致模型性能下降时。作为ReLU和Leaky ReLU的一个直接替代品,以期获得性能提升。
| 特性 | ReLU | Leaky ReLU | PReLU |
|---|---|---|---|
| 负区公式 | 0 | αx (α是固定超参数) | αx (α是可学习参数) |
| Dying ReLU | 存在 | 缓解 | 缓解 |
| 灵活性 | 低 | 中 | 高 |
| 额外参数 | 无 | 无 | 很少(每层或每通道一个) |
简而言之,PReLU是一个“聪明”的Leaky ReLU,它把需要人工设定的斜率值变成了一个可以由模型自己学习的参数,让激活函数能够自适应地调整其形态,从而更好地拟合复杂的数据。