我正在尝试实现一个具有大约 2000 个输入的神经网络。
我已经对 iris 数据集进行了一些测试,以便检查它,它似乎有效,但是当我运行测试时,它会抛出错误的结果,大多数时候,对于所有测试,我都会得到相同的结果每个数据的输出。我担心如果它与偏差过程和梯度更新有某种关系,也许你们可以发现错误或给我一些建议。 这是反向传播过程的部分代码。
def backward_propagation(parameters, cache, X, Y):
#weights
W1 = parameters['W1']
W2 = parameters['W2']
#Outputs after activation function
A1 = cache['A1']
A2 = cache['A2']
dZ2= A2 - Y
dW2 = np.dot(dZ2, A1.T)
db2 = np.sum(dZ2, axis=1, keepdims=True)
dZ1 = np.multiply(np.dot(W2.T, dZ2), 1 - np.power(A1, 2))
dW1 = np.dot(dZ1, X.T)
db1 = np.sum(dZ1, axis=1, keepdims=True)
gradient = {"dW1": dW1,
"db1": db1,
"dW2": dW2,
"db2": db2}
return gradient
最佳答案
如果不提供预测和转发功能,很难看出它是否真正正常工作。
这样我们就可以准确地知道正在做什么,并查看反向传播是否真的正确。
您没有正确推导 sigmoid 函数,我认为您也没有正确应用链式法则。
据我所知,您正在使用这种架构:
梯度为(应用链式法则):
在您的代码中,它按以下方式翻译:
W1 = parameters['W1']
W2 = parameters['W2']
#Outputs after activation function
A1 = cache['A1']
A2 = cache['A2']
dA2= A2 - Y
dfc2 = dA2*A2*(1 - A2)
dA1 = np.dot(dfc2, W2.T)
dW2 = np.dot(A1.T, dfc2)
db2 = np.sum(dA2, axis=1, keepdims=True)
dfc1 = dA1*A1*(1 - A1)
dA1 = np.dot(dfc1, W1.T)
dW1 = np.dot(X.T, dfc1)
db1 = np.sum(dA1, axis=1, keepdims=True)
gradient = {
"dW1": np.sum(dW1, axis=0),
"db1": np.sum(db1, axis=0),
"dW2": np.sum(dW2, axis=0),
"db2": np.sum(db2, axis=0)
}
我检查执行以下代码:
import numpy as np
W1 = np.random.rand(30, 10)
b1 = np.random.rand(10)
W2 = np.random.rand(10, 1)
b2 = np.random.rand(1)
def sigmoid(x):
return 1 / (1 + np.exp(-x))
X = np.random.rand(100, 30)
Y = np.ones(shape=(100, 1)) #...
for i in range(100000000):
fc1 = X.dot(W1) + b1
A1 = sigmoid(fc1)
fc2 = A1.dot(W2) + b2
A2 = sigmoid(fc2)
L = np.sum(A2 - Y)**2
print(L)
dA2= A2 - Y
dfc2 = dA2*A2*(1 - A2)
dA1 = np.dot(dfc2, W2.T)
dW2 = np.dot(A1.T, dfc2)
db2 = np.sum(dA2, axis=1, keepdims=True)
dfc1 = dA1*A1*(1 - A1)
dA1 = np.dot(dfc1, W1.T)
dW1 = np.dot(X.T, dfc1)
db1 = np.sum(dA1, axis=1, keepdims=True)
gradient = {
"dW1": dW1,
"db1": db1,
"dW2": dW2,
"db2": db2
}
W1 -= 0.1*np.sum(dW1, axis=0)
W2 -= 0.1*np.sum(dW2, axis=0)
b1 -= 0.1*np.sum(db1, axis=0)
b2 -= 0.1*np.sum(db2, axis=0)
如果您的最后一个激活是 sigmoid,则该值将介于 0 和 1 之间。您应该记住,通常这用于指示概率,而交叉熵通常用作损失。
关于python - 训练神经网络后,我为每个输入数据获得相同的输出(2000 个输入,1 个输出),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54186701/