反向传播的直觉
Intuition for back propagation
下面是神经网络反向传播的正向传播和部分实现的反向传播:
import numpy as np
def sigmoid(z):
return 1 / (1 + np.exp(-z))
X_train = np.asarray([[1,1], [0,0]]).T
Y_train = np.asarray([[1], [0]]).T
hidden_size = 2
output_size = 1
learning_rate = 0.1
forward propagation
w1 = np.random.randn(hidden_size, 2) * 0.1
b1 = np.zeros((hidden_size, 1))
w2 = np.random.randn(output_size, hidden_size) * 0.1
b2 = np.zeros((output_size, 1))
Z1 = np.dot(w1, X_train) + b1
A1 = sigmoid(Z1)
Z2 = np.dot(w2, A1) + b2
A2 = sigmoid(Z2)
derivativeA2 = A2 * (1 - A2)
derivativeA1 = A1 * (1 - A1)
first steps of back propagation
error = (A2 - Y_train)
dA2 = error / derivativeA2
dZ2 = np.multiply(dA2, derivativeA2)
背后的直觉是什么:
error = (A2 - Y_train)
dA2 = error / derivativeA2
dZ2 = np.multiply(dA2, derivativeA2)
我理解错误是当前预测 A2
与实际值 Y_train
之间的差异。
但为什么要将这个误差除以 A2
的导数,然后将 error / derivativeA2
的结果乘以 derivativeA2
?这背后的直觉是什么?
这些表达确实令人困惑:
derivativeA2 = A2 * (1 - A2)
error = (A2 - Y_train)
dA2 = error / derivativeA2
... 因为 error
本身没有意义。此时,目标是计算交叉熵损失的导数,其公式如下:
dA2 = (A2 - Y_train) / (A2 * (1 - A2))
推导见these lecture notes(公式6)。正好前面的操作是sigmoid
,它的导数是A2 * (1 - A2)
。这就是为什么再次使用此表达式来计算 dZ2
(公式 7)的原因。
但是,如果您有不同的损失函数(例如,L2)或不同的压缩层,那么 A2 * (1 - A2)
将不会被重用 。这些是计算图中的不同节点。
下面是神经网络反向传播的正向传播和部分实现的反向传播:
import numpy as np
def sigmoid(z):
return 1 / (1 + np.exp(-z))
X_train = np.asarray([[1,1], [0,0]]).T
Y_train = np.asarray([[1], [0]]).T
hidden_size = 2
output_size = 1
learning_rate = 0.1
forward propagation
w1 = np.random.randn(hidden_size, 2) * 0.1
b1 = np.zeros((hidden_size, 1))
w2 = np.random.randn(output_size, hidden_size) * 0.1
b2 = np.zeros((output_size, 1))
Z1 = np.dot(w1, X_train) + b1
A1 = sigmoid(Z1)
Z2 = np.dot(w2, A1) + b2
A2 = sigmoid(Z2)
derivativeA2 = A2 * (1 - A2)
derivativeA1 = A1 * (1 - A1)
first steps of back propagation
error = (A2 - Y_train)
dA2 = error / derivativeA2
dZ2 = np.multiply(dA2, derivativeA2)
背后的直觉是什么:
error = (A2 - Y_train)
dA2 = error / derivativeA2
dZ2 = np.multiply(dA2, derivativeA2)
我理解错误是当前预测 A2
与实际值 Y_train
之间的差异。
但为什么要将这个误差除以 A2
的导数,然后将 error / derivativeA2
的结果乘以 derivativeA2
?这背后的直觉是什么?
这些表达确实令人困惑:
derivativeA2 = A2 * (1 - A2)
error = (A2 - Y_train)
dA2 = error / derivativeA2
... 因为 error
本身没有意义。此时,目标是计算交叉熵损失的导数,其公式如下:
dA2 = (A2 - Y_train) / (A2 * (1 - A2))
推导见these lecture notes(公式6)。正好前面的操作是sigmoid
,它的导数是A2 * (1 - A2)
。这就是为什么再次使用此表达式来计算 dZ2
(公式 7)的原因。
但是,如果您有不同的损失函数(例如,L2)或不同的压缩层,那么 A2 * (1 - A2)
将不会被重用 。这些是计算图中的不同节点。