这个模型是在两个地方使用一个ReLU,还是通过对一层两侧的层进行矩阵乘法来计算梯度?
在这个简单的神经网络的最后一层(如下所示),在反向传播过程中,通过对y预测值与y进行矩阵乘法来计算最后一层w2
的梯度,我以为这只是在w1
和w2
层之间,而不是在w2
和y_pred
之间
有问题的行接近底部。它是grad_w2 = h_relu.t().mm(grad_y_pred)
。
我感到困惑,因为我以为一切都应该按顺序向前,然后按顺序向后。这个ReLU是在两个地方被使用吗?
这是对模型的视觉说明尝试。
这个例子来自Pytorch网站。它是页面上的第二个代码块。
grad_w2 = h_relu.t().mm(grad_y_pred)import torchdtype = torch.floatdevice = torch.device("cpu")# device = torch.device("cuda:0") # Uncomment this to run on GPU# N is batch size; D_in is input dimension;# H is hidden dimension; D_out is output dimension.N, D_in, H, D_out = 64, 1000, 100, 10# Create random input and output datax = torch.randn(N, D_in, device=device, dtype=dtype)y = torch.randn(N, D_out, device=device, dtype=dtype)# Randomly initialize weightsw1 = torch.randn(D_in, H, device=device, dtype=dtype)w2 = torch.randn(H, D_out, device=device, dtype=dtype)learning_rate = 1e-6for t in range(500): # Forward pass: compute predicted y h = x.mm(w1) h_relu = h.clamp(min=0) y_pred = h_relu.mm(w2) # Compute and print loss loss = (y_pred - y).pow(2).sum().item() if t % 100 == 99: print(t, loss) # Backprop to compute gradients of w1 and w2 with respect to loss grad_y_pred = 2.0 * (y_pred - y) grad_w2 = h_relu.t().mm(grad_y_pred) grad_h_relu = grad_y_pred.mm(w2.t()) grad_h = grad_h_relu.clone() grad_h[h < 0] = 0 grad_w1 = x.t().mm(grad_h) # Update weights using gradient descent w1 -= learning_rate * grad_w1 w2 -= learning_rate * grad_w2
感谢您耐心查看并试图为我澄清这个问题。
如果您能尝试在中间添加另一层权重和另一个ReLU,这可能会帮助我理解。这是我试图做的事情。
回答:
请考虑以下图表,它表示了所讨论的网络。反向传播的概念只是一种快速且直观地在复杂操作序列上应用链式法则的方法,以计算输出相对于张量的梯度。通常我们对计算叶张量(不是从其他张量派生的张量)相对于损失或目标的梯度感兴趣。所有叶张量在下图中表示为圆圈,损失用标有L的矩形表示。
使用反向图,我们可以沿着从L到w1和w2的路径,以确定我们需要哪些偏导数来计算L相对于w1和w2的梯度。为了简化,我们假设所有叶张量都是标量,以避免涉及向量和矩阵乘法的复杂性。
使用这种方法,L相对于w1和w2的梯度是
和
需要注意的是,由于w2是一个叶张量,我们在计算dL/dw2时只使用dy/dw2(即grad_w2
),因为它不是从L到w1的路径的一部分。