【问题标题】:Why is my neural network cost function increasing despite giving correct predictions?尽管给出了正确的预测,为什么我的神经网络成本函数会增加?
【发布时间】: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


【解决方案1】:

我同意,这个问题似乎与 theta1,2 有关,尽管我似乎也不清楚如果您正在绘制的是训练准确度,模型如何学习。

另外,您提到y_vectors 是一个'm x 10' 数组,但分配m = y_vectors.shape[1]。看来你应该写m = y_vectors.shape[0]

P.s.:我的帖子更多的是评论,但我还不能评论。

【讨论】:

  • OP 绘制的是成本函数,而不是训练精度——尽管 2 应该是相关的
  • 抱歉,我的问题打错了。我重新检查了我的代码,它实际上是一个 '10 by m' 数组。
猜你喜欢
  • 2018-03-11
  • 1970-01-01
  • 2016-08-24
  • 1970-01-01
  • 1970-01-01
  • 2019-08-15
  • 2016-07-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多