我正在尝试编写我的第一个神经网络,但是现在已经完全解决了这个问题一个多星期。我遵循Andrew NG的机器学习课程,并在python中实现了以下功能。
forwardPropogate() #does forward propagation
backwardPropogate() #computes the gradients using backpropogation
costFunction() #takes as input, all the parameters of the neural network in a rolled up single array and computes its cost
gradientDescend() #tries to minimise the cost using gradient descend
当我尝试训练网络时,发现它给我带来了非常糟糕的结果,当我无法弄清代码出了什么问题时,我下载了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 #show percentage completed
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
的原始随机向量。这就是为什么您看不到成本功能的任何学习或改进之处。
将thetaValues
替换为trainedValues
中的unrollParameters()
,您会很高兴。