我一直在研究以python实现的简单神经网络。目前,它似乎正在学习,但不幸的是,它似乎并未有效地学习。下图显示了经过约15,000次迭代训练的神经网络的输出,并提供了1000个训练示例(它试图学习x2)。网络的成本似乎也总是触底而已,刚好超过0.41,我不能再降低了。

编辑:我试图离开网络学习几个小时,可能要进行数百万甚至更多次迭代,并且grah上的两行似乎并在一起,但是,成本却拒绝了跌破0.41-ish。



我怀疑问题在于我的反向传播算法的实现,因为我的实现所提供的高成本价值似乎与

但是,如果我在实现的其他部分遗漏了某些内容,则下面是我的完整代码。

import numpy as np
class neural_network:

    def __init__(self,dimensions,nonlinear_function,nonlinear_function_derivative,seed=None):
        if seed:
            np.random.seed(seed)
        self.g=nonlinear_function
        self.g_dash=nonlinear_function_derivative
        self.theta_one=2*np.random.random((dimensions[0],dimensions[1]))-1
        self.theta_two=2*np.random.random((dimensions[1]+1,dimensions[2]))-1
    def predict(self,x):
        self.a1=x
        self.z2=np.dot(x,self.theta_one)
        self.a2=np.concatenate((self.g(self.z2),np.ones((np.shape(self.z2)[0],1))),axis=1)

        self.z3=np.dot(self.a2,self.theta_two)
        self.a3=self.g(self.z3)
        return self.a3
    def backprop(self,y,alpha,reg):
        self.y=y
        self.delta_three=self.a3-y
        self.delta_two=np.dot(self.delta_three,self.theta_two.T)[::,:-1]*self.g_dash(self.z2)

        self.Delta2=np.dot(self.a2.T,self.delta_three)
        self.Delta1=np.dot(self.a1.T,self.delta_two)

        self.theta_one_gradient=self.Delta1/len(self.a1)
        self.theta_two_gradient=self.Delta2/len(self.a1)

        self.theta_one_regularisation=(0.0001/len(self.a1))*self.theta_one
        self.theta_two_regularisation=(0.0001/len(self.a1))*self.theta_two

        self.theta_one_gradient[1]+=self.theta_one_regularisation[1]
        self.theta_two_gradient[1]+=self.theta_two_regularisation[1]

        self.theta_one-=alpha*(self.theta_one_gradient)
        self.theta_two-=alpha*(self.theta_two_gradient)
    def cost(self,reg):
        self.j=(1/len(self.a1))*np.sum(np.sum(-self.y*np.log(self.a3)-(1-self.y)*np.log(1-self.a3),1))
        self.j+=(reg/len(self.a1))*(sum(sum(self.theta_one**2,2))+sum(sum(self.theta_two**2,2)))
        return self.j
    def train(self,inPut,outPut,alpha,reg):
        self.predict(inPut)
        self.backprop(outPut,alpha,reg)


谁能提供有关我的实现以及backprop算法是否正确的任何反馈?

编辑:

下面是测试我正在使用的代码(只是放在同一文件中的神经网络代码之后)。我意识到它非常凌乱,并且包含许多不良做法的示例,但它似乎可以工作(但是效果不佳)。我已经使用不同的超参数进行了广泛的测试,而不仅仅是下面的代码中使用的参数,而且我无法将成本降低到低于0.41 ish,这看起来确实很差。如果有人能找到能大大降低成本最小界限的超参数,那基本上也可以回答我的问题。

np.seterr(all='raise')

def plot():
    plt.clf()
    plt.plot([i/100 for i in range(100)],[net.predict(np.array([[1,f/100]]))[0][0] for f in range(100)])
    plt.plot([i/100 for i in range(100)],[((f/100)**2) for f in range(100)])
    plt.pause(0.05)
import random
net=neural_network([2,400,1],lambda x:1/(1+np.exp(-x)),lambda x:(1/(1+np.exp(-x)))*(1-(1/(1+np.exp(-x)))))

count=0

import matplotlib.pyplot as plt
plt.ion()
r=[i/1000 for i in range(1,1000)]
inp=np.array([[1,f] for f in r])
outp=np.array([[f**2] for f in r])

net.predict(inp)

while True:
    count+=1

    net.train(inp,outp,1,0.001)
    if count%100==0:

        print(net.cost(0.001))
        plot()


评论

嗨,由于您的代码无法正常工作,我目前正在阅读您的问题。这是否按预期运行,但不是最佳运行?还是存在阻止您的代码输出正确答案的问题?

@JoeWallis网络似乎正在学习,但是从图中可以看出,这样做很糟糕。我想知道是否有人可以提出任何改进建议,以改善其学习效果,无论是通过指出我犯的算法错误,还是建议在其他地方提出改进建议。

聊天中的共识似乎是神经网络中的“正确性”不是二进制的,因此要求提高准确性应该是允许的。

请实际添加完整的代码。其中包括您的训练集和激活功能以及您选择的网络规模。

您可以将梯度检查用于调试目的(您可以在此处阅读更多内容)

#1 楼

您不应该在网络的输出层上使用激活功能。在您的示例中,这将网络的输出限制为(0,1),因为您使用的是S型激活。尝试删除激活和再培训。