PyTorch 中非线性激活函数的导数计算

非线性激活函数在神经网络中引入非线性特性,使模型能够拟合复杂数据分布。常见的激活函数如 ReLUSigmoidTanh 等,在反向传播时需要计算其导数。

ReLU 为例,其导数定义为分段函数:

  • 当输入 $x > 0$ 时,导数为 $1$;
  • 当输入 $x \leq 0$ 时,导数为 $0$。

数学表达式为: $$ \frac{d}{dx}\text{ReLU}(x) = \begin{cases} 1 & \text{if } x > 0 \ 0 & \text{otherwise} \end{cases} $$

反向传播的实现原理

PyTorch 通过自动微分机制(Autograd)实现反向传播。在计算图中,激活函数的导数是关键节点。以 Sigmoid 函数为例: $$ \sigma(x) = \frac{1}{1 + e^{-x}} $$ 其导数为: $$ \sigma'(x) = \sigma(x)(1 - \sigma(x)) $$

在反向传播时,PyTorch 会根据前向传播的输出值自动计算梯度。例如 torch.sigmoid() 的反向传播会调用上述导数公式。

自定义激活函数的实现

若需自定义激活函数,必须手动实现其前向传播和反向传播逻辑。以下是带导数计算的 LeakyReLU 实现示例:

class LeakyReLU(torch.autograd.Function):
    @staticmethod
    def forward(ctx, x, slope=0.01):
        ctx.save_for_backward(x, torch.tensor(slope))
        return torch.where(x > 0, x, x * slope)

    @staticmethod
    def backward(ctx, grad_output):
        x, slope = ctx.saved_tensors
        grad_input = grad_output.clone()
        grad_input[x <= 0] *= slope.item()
        return grad_input

梯度检查验证

为确保导数计算的正确性,可通过 PyTorch 的梯度检查工具验证:

input = torch.randn(3, requires_grad=True)
torch.autograd.gradcheck(LeakyReLU.apply, input)

常见激活函数的导数对比

激活函数导数公式
ReLU$\mathbb{I}(x > 0)$
Sigmoid$\sigma(x)(1 - \sigma(x))$
Tanh$1 - \tanh^2(x)$
LeakyReLU$\begin{cases}1 & \text{if } x > 0 \ \text{slope} & \text{otherwise}\end{cases}$

更多推荐