我正在尝试仅使用numpy实现一个2层神经网络。下面的代码只是计算前向传播。
训练数据包含两个示例,输入为5维,输出为4维。当我尝试运行我的网络时:
# Two Layer Neural networkimport numpy as npM = 2learning_rate = 0.0001X_train = np.asarray([[1,1,1,1,1] , [1,1,1,1,1]])Y_train = np.asarray([[0,0,0,0] , [1,0,0,0]])X_trainT = X_train.TY_trainT = Y_train.Tdef sigmoid(z): s = 1 / (1 + np.exp(-z)) return sw1=np.zeros((Y_trainT.shape[0], X_trainT.shape[0]))b1=np.zeros((Y_trainT.shape[0], 1))A1 = sigmoid(np.dot(w1 , X_trainT))w2=np.zeros((A1.shape[0], w1.shape[0]))b2=np.zeros((A1.shape[0], 1))A2 = sigmoid(np.dot(w2 , A1))# forward propogationdw1 = ( 1 / M ) * np.dot((A1 - A2) , X_trainT.T / M)db1 = (A1 - A2).mean(axis=1, keepdims=True)w1 = w1 - learning_rate * dw1b1 = b1 - learning_rate * db1dw2 = ( 1 / M ) * np.dot((A2 - A1) , Y_trainT.T / M)db2 = (A2 - Y_trainT).mean(axis=1, keepdims=True)w2 = w2 - learning_rate * dw2b2 = b2 - learning_rate * db2Y_prediction_train = sigmoid(np.dot(w2 , X_train) +b2)print(Y_prediction_train.T)
我收到了以下错误:
ValueError Traceback (most recent call last)<ipython-input-42-f0462b5940a4> in <module>() 36 b2 = b2 - learning_rate * db2 37 ---> 38 Y_prediction_train = sigmoid(np.dot(w2 , X_train) +b2) 39 print(Y_prediction_train.T)ValueError: shapes (4,4) and (2,5) not aligned: 4 (dim 1) != 2 (dim 0)
我的线性代数似乎出了问题,但我不知道问题出在哪里。
打印权重和相应的导数:
print(w1.shape)print(w2.shape)print(dw1.shape)print(dw2.shape)
打印结果为:
(4, 5)(4, 4)(4, 5)(4, 4)
如何将5维的训练示例纳入这个网络?
我是否正确实现了前向传播?
根据@Imran的回答,现在使用这个网络:
# Two Layer Neural networkimport numpy as npM = 2learning_rate = 0.0001X_train = np.asarray([[1,0,1,1,1] , [1,1,1,1,1]])Y_train = np.asarray([[0,1,0,0] , [1,0,0,0]])X_trainT = X_train.TY_trainT = Y_train.Tdef sigmoid(z): s = 1 / (1 + np.exp(-z)) return sw1=np.zeros((Y_trainT.shape[0], X_trainT.shape[0]))b1=np.zeros((Y_trainT.shape[0], 1))A1 = sigmoid(np.dot(w1 , X_trainT))w2=np.zeros((A1.shape[0], w1.shape[0]))b2=np.zeros((A1.shape[0], 1))A2 = sigmoid(np.dot(w2 , A1))# forward propogationdw1 = ( 1 / M ) * np.dot((A1 - A2) , X_trainT.T / M)db1 = (A1 - A2).mean(axis=1, keepdims=True)w1 = w1 - learning_rate * dw1b1 = b1 - learning_rate * db1dw2 = ( 1 / M ) * np.dot((A2 - A1) , Y_trainT.T / M)db2 = (A2 - Y_trainT).mean(axis=1, keepdims=True)w2 = w2 - learning_rate * dw2b2 = b2 - learning_rate * db2Y_prediction_train = sigmoid(np.dot(w2 , A1) +b2)print(Y_prediction_train.T)
打印结果为:
[[ 0.5 0.5 0.4999875 0.4999875] [ 0.5 0.5 0.4999875 0.4999875]]
我认为dw2 = ( 1 / M ) * np.dot((A2 - A1) , Y_trainT.T / M)
应该改为dw2 = ( 1 / M ) * np.dot((A2 - A1) , A1.T / M)
,因为为了将差异从隐藏层1传播到隐藏层2,这是正确的吗?
回答:
Y_prediction_train = sigmoid(np.dot(w2 , X_train) +b2)
w2
是你的第二隐藏层的权重矩阵。这永远不应该与你的输入X_train
相乘。
为了获得预测,你需要将前向传播分解成一个独立的函数,该函数接受一个输入X
,首先计算A1 = sigmoid(np.dot(w1 , X))
,然后返回A2 = sigmoid(np.dot(w2 , A1))
的结果
更新:
我认为dw2 = ( 1 / M ) * np.dot((A2 – A1) , Y_trainT.T / M)应该改为dw2 = ( 1 / M ) * np.dot((A2 – A1) , A1.T / M),因为为了将差异从隐藏层1传播到隐藏层2,这是正确的吗?
反向传播是向后传播错误的。第一步是计算损失函数相对于输出的梯度,如果你使用均方误差,这将是A2-Y
。然后将这个结果输入到第二层的权重和偏置的损失梯度项中,然后继续回传到第一层。你不希望在反向传播期间从第一层传播任何东西到第二层。
看起来你在更新的问题中几乎做对了,但我认为你想要的是:
dW2 = ( 1 / M ) * np.dot((A2 - Y) , A1.T)
另外几点注意事项:
- 你将权重初始化为零。这将不允许神经网络在训练期间打破对称性,你最终会在每个神经元上得到相同的权重。你应该尝试在[-1,1]范围内使用随机权重进行初始化。
- 你应该将前向和反向传播步骤放在一个循环中,以便在你的错误仍在改善时可以运行多个epoch。