【发布时间】:2021-09-21 17:47:35
【问题描述】:
我正在用 python 创建一个神经网络来识别手写数字。我很确定我的前馈、反向传播和梯度下降是正确的,因为我的程序的训练准确度约为 90%。我确信它工作正常,因为我从物理上抽取了几张随机测试示例图像并将其与预测进行比较,它们都是正确的。
但是,在针对迭代绘制成本函数 J 时,我得到了非常奇怪的结果。有时它会以一种奇怪的方式减少,有时它会增加,这取决于我为正则化因子 lambda 选择的内容。这是一个示例图:
我怀疑错误在于我对成本函数的编码方式,尽管我无法发现它。这是函数:
def J2(y_target, y_pred, theta1, theta2, lamb):
"""
Args:
y_target np.array(n_samples,10): One-hot target class
y_pred np.array(n_samples,10): Predicted class likelihoods
[...]
"""
m = y_target.shape[1]
cost = np.multiply(y_target, np.log(y_pred)) + np.multiply((1-y_target),np.log(1-y_pred))
cost = np.sum(cost)
cost = (-1/m)*cost
reg = np.sum(np.square(theta1)) + np.sum(np.square(theta2))
reg = (lamb/2*m)*reg
J = cost + reg
return J
这是我进行正向和反向传播的方法:
def forward_prop2(X, theta1, theta2):
#forward propagation
#X is a 'm by n' matrix
#m = number of examples
#n = number of features
a1 = np.transpose(X)
z2 = np.matmul(theta1, a1)
a2 = sigmoid(z2)
a2 = np.append(np.ones((1,a2.shape[1])),a2,axis=0)
z3 = np.matmul(theta2, a2)
a3 = sigmoid(z3)
return a1, a2, a3
def backward_prop2(y_vectors, a1, a2, a3, theta1, theta2, lamb):
#backward propagation
#y_vectors is vectors of results (see notes for clarification)
#outputs gradiat arrays for theta1 and theta2
m = y_vectors.shape[1]
delta3 = a3 - y_vectors
delta2_matmul_term = np.matmul(np.transpose(theta2),delta3)
delta2_dot_term = np.multiply(a2, np.ones(a2.shape)-a2)
delta2 = np.multiply(delta2_matmul_term,delta2_dot_term)
triangle2 = np.matmul(delta3, np.transpose(a2))
triangle1 = np.matmul(delta2[1:,:],np.transpose(a1))
reg2 = np.zeros((theta2.shape[0],1))
reg2 = np.append(reg2,theta2[:,1:],axis=1)
grad2 = (1/m)*triangle2 + lamb*reg2
reg1 = np.zeros((theta1.shape[0],1))
reg1 = np.append(reg1,theta1[:,1:],axis=1)
grad1 = (1/m)*triangle1 + lamb*reg1
return grad1, grad2
最后我运行这个 for 循环:
iterations = 1000
alpha = 1
lamb = 0
J = []
for i in range (0, iterations):
a1, a2, a3 = nn.forward_prop2(X_train, theta1, theta2)
grad1, grad2 = nn.backward_prop2(y_vectors_train, a1, a2, a3, theta1, theta2, lamb)
theta1 ,theta2 = nn.grad_des(theta1, theta2, grad1, grad2, alpha)
J.append(nn.J2(y_vectors_train, a3, theta1, theta2, lamb))
plt.plot(J)
plt.xlabel('Iterations')
plt.ylabel('J')
plt.show()
编辑: 这是使 lambda 非常小后的图,即 0.0000000001:
在我看来还是有点不对劲。
【问题讨论】:
-
这是验证损失还是训练损失?
-
您应该检查一下 theta1 和 theta2 的值,我猜它们非常高。这导致
reg的值较高,从而使 J 增加。虽然这个模型的实际学习方式超出了我的范围...... -
我认为在 theta1 和 theta 2 中这不是一个错误,因为该算法实际上可以给出正确的预测。唯一的问题是显示成本函数。学习方法是这样的:medium.com/secure-and-private-ai-math-blogging-competition/…。 @Avandale
-
不确定这些术语是什么意思,我是新手。 @MushfiratMohaimin
-
我不是说这些术语有错误,我是说它们的价值很高(这不一定是坏事)。尝试降低
lambda的值(喜欢...很多),您的图表应该没问题。还有一个问题,你是如何进行反向传播的?你能告诉我们你的完整代码吗?
标签: python numpy machine-learning neural-network