如何检查relu梯度

时间:2016-11-16 03:18:31

标签: matlab machine-learning neural-network deep-learning

我试图实施ANN,我还为反向传播写了一个数值梯度检查。 当我使用sigmoid函数时,数值梯度检查正常工作 但是,当我使用relu激活时,渐变检查失败。

我得到的渐变如下:

switch opts.act_function
    case 'relu'
        d_act = a{i} > 0;
    case 'sigmoid'
        d_act = a{i} * (1 - a{i});
end

我的问题是0处没有渐变。如果我将0的子梯度设置为0,这是正确的吗?

1 个答案:

答案 0 :(得分:5)

已知使用ReLU函数进行数值检查会在x = 0处出现问题。如果您还记得,ReLU函数的定义是f(x) = max(0, x)。它是一个斜坡函数,其中小于0的值被钳制为0,而严格为正值的值保持相同的值。

数字梯度检查功能(如ReLU)遇到的问题通常被称为 kinks 的问题。扭结指的是目标或激活函数的不可微分部分。对于ReLU函数,从x = 0左侧和x = 0右侧接近的导数相等,因此导数在x = 0处不存在或者更通俗地说,x = 0 存在扭结。

即使您没有渐变为0,但对于给定的wepsilon,您可能会在执行渐变检查时计算非零渐变。例如,x = -1e-5非零的情况,并考虑epsilon = 1e-4时的情况。通过使用评论中所见的居中差异近似,f(x + epsilon) = f(-1e-5 + 1e-4) = f(9e-5) = 9e-5给出了ReLU的定义。同样,f(x - epsilon) = f(-1e-5 - 1e-4) = f(-1.1e-5) = 0给出了ReLU的定义。因此,如果您尝试近似导数:

(f(x + epsilon) - f(x - epsilon)) / (2*epsilon) = (9e-5 - 0) / 2e-4 = 0.45

数值梯度在理论上应为0时给出0.45。因此,对于x = 0的小值,不能依赖数值梯度。你没有遇到sigmoid函数的这个问题,因为它是一个在任何地方都是可微分的函数,所以对于一个足够小的epsilon,你应该能够获得与函数的实际导数大致相同的值。

当数字不准确时,您可以做的是识别。您可以做的是确定f(x + epsilon)f(x - epsilon)符号何时不同,这表明您正在x = 0穿越扭结。然后,您可以向用户输出已发生此情况的警告,并且不应依赖数值梯度。否则,当f(x + epsilon)f(x - epsilon)具有相同符号时,渐变应该能够正常传递。