标准答案是 ReLU 的输入很少完全为零,例如,请参见此处,因此它不会产生任何显着差异。
具体来说,要使 ReLU 获得零输入,输入的一整行到具有该层权重矩阵的一整列的层的点积必须完全为零。即使您有一个全零输入样本,最后一个位置仍然应该有一个偏差项,所以我真的看不到这种情况发生。
但是,如果您想自己测试,请尝试将零处的导数实现为0
, 0.5
,1
并查看是否有任何变化。
PyTorch 文档给出了一个简单的神经网络,带有一个隐藏层和 relu 激活的 numpy 示例。我在下面用一个固定的随机种子和三个将 ReLU 梯度的行为设置为 0 的选项复制了它。我还添加了一个偏差项。
N, D_in, H, D_out = 4, 2, 30, 1
# Create random input and output data
x = x = np.random.randn(N, D_in)
x = np.c_(x, no.ones(x.shape[0]))
y = x = np.random.randn(N, D_in)
np.random.seed(1)
# Randomly initialize weights
w1 = np.random.randn(D_in+1, H)
w2 = np.random.randn(H, D_out)
learning_rate = 0.002
loss_col = []
for t in range(200):
# Forward pass: compute predicted y
h = x.dot(w1)
h_relu = np.maximum(h, 0) # using ReLU as activate function
y_pred = h_relu.dot(w2)
# Compute and print loss
loss = np.square(y_pred - y).sum() # loss function
loss_col.append(loss)
print(t, loss, y_pred)
# Backprop to compute gradients of w1 and w2 with respect to loss
grad_y_pred = 2.0 * (y_pred - y) # the last layer's error
grad_w2 = h_relu.T.dot(grad_y_pred)
grad_h_relu = grad_y_pred.dot(w2.T) # the second laye's error
grad_h = grad_h_relu.copy()
grad_h[h < 0] = 0 # grad at zero = 1
# grad[h <= 0] = 0 # grad at zero = 0
# grad_h[h < 0] = 0; grad_h[h == 0] = 0.5 # grad at zero = 0.5
grad_w1 = x.T.dot(grad_h)
# Update weights
w1 -= learning_rate * grad_w1
w2 -= learning_rate * grad_w2