我在尝试编写我的第一个神经网络,但现在已经在这个问题上卡了一个多星期。我正在按照Andrew NG的机器学习课程进行学习,并在Python中实现了以下函数。
forwardPropogate() #进行前向传播 backwardPropogate() #使用反向传播计算梯度 costFunction() #输入神经网络的所有参数,组成一个单一数组并计算其成本 gradientDescend() #尝试使用梯度下降法最小化成本
当我尝试训练网络时,我发现它给出了非常糟糕的结果,并且当我无法找出代码的问题时,我下载了MATLAB版本的代码,并尝试将其与我自己的代码进行比较。
为了确保我的实现是正确的,我运行了MATLAB代码,从中获取参数,并通过我的backwardPropogate()
和costFunction()
运行它们。
运行backwardPropogate()
后,这是MATLAB和我的代码给出的梯度图。
如你所见,它们非常相似。此外,我还手动检查了两者的输出,足以让我相信
backwardPropogate()
的实现是正确的。我还进行了数值梯度检查,结果也非常吻合。
MATLAB代码计算出的参数成本是J = 0.14942
,而Python给出的结果是J = 0.149420032652
。我确信costFunction()
和backwardPropogate()
的实现是正确的(难道不是吗?)。
当我运行我的gradientDescend()
时,我得到了成本值与迭代次数的图表。。这看起来又很好。
我无法理解为什么代码仍然给我不好的值。即使在训练集上的成功率也几乎只有10%。
这是我的梯度下降函数及其调用方式。
def gradientDescend(self,gradientFunction,thetaValues): JValues = np.zeros(MAX_ITER) for i in range(0,MAX_ITER): thetaValues = thetaValues - ALPHA * gradientFunction(thetaValues) J = self.costFunction(thetaValues) JValues[i] = J print i/MAX_ITER * 100 #显示完成百分比 return thetaValues,JValues def train(self): thetaValues = (np.random.rand(NoTheta1+NoTheta2,1) * (2 * INIT_EPSILON)) - INIT_EPSILON trainedThetas,JVals = self.gradientDescend(self.getGradients,thetaValues) self.theta1,self.theta2 = self.unrollParameters(thetaValues) xaxis = np.arange(0,len(JVals)) plt.plot(xaxis,JVals) plt.show() return self.theta1,self.theta2
进一步检查后,我发现参数的初始随机值表现得和我的训练值一样差!在所有事情中,这是我最不理解的。成本函数似乎从循环开始到结束都在下降。所以即使最终参数不好,它们至少应该比初始值表现得更好。我不知道接下来该怎么办。欢迎任何建议。
回答:
在train()
中,你的GradientDescend()
函数的输出trainedThetas
实际上并未被使用。在GradientDescend()
之后的那一行,self.unrollParameters(thetaValues)
使用了原始的随机向量thetaValues
。这就是为什么你没有看到成本函数的任何学习或改进。
在unrollParameters()
中用trainedValues
替换thetaValues
,你就能正常运行了。