3层神经网络陷入局部最小值

我根据这个教程用Python编写了一个3层神经网络,用于玩石头、剪刀、布游戏,样本数据使用-1代表石头0代表纸1代表剪刀,以及与教程中类似的数组。我的函数似乎在每次运行时都陷入相对最小值,我正在寻找解决这个问题的办法。程序如下所示。

#math moduleimport numpy as np#sigmoid function converts numbers to percentages(between 0 and 1)def nonlin(x, deriv = False):    if (deriv == True): #sigmoid derivative is just        return x*(1-x)#output * (output - 1)    return 1/(1+np.exp(-x)) #print the sigmoid function#input data: using MOCK RPS DATA, -1:ROCK, 0:PAPER, 1:SCISSORSinput_data = np.array([[1, 1, 1],                    [0, 0, 0],                    [-1, -1, -1],                    [-1, 1, -1]])#also for trainingoutput_data = np.array([[1],                    [0],                    [-1],                    [1]])#random numbers to not get stuck in local minima for fitnessnp.random.seed(1)#create random weights to be trained in loopfirstLayer_weights = 2*np.random.random((3, 4)) - 1 #size of matrixsecondLayer_weights = 2*np.random.random((4, 1)) - 1for value in xrange(60000): # loops through training    #pass input through weights to output: three layers    layer0 = input_data    #layer1 takes dot product of the input and weight matrices, then maps them to sigmoid function    layer1 = nonlin(np.dot(layer0, firstLayer_weights))    #layer2 takes dot product of layer1 result and weight matrices, then maps the to sigmoid function    layer2 = nonlin(np.dot(layer1, secondLayer_weights))    #check computer predicted result against actual data    layer2_error = output_data - layer2    #if value is a factor of 10,000, so six times (out of 60,000),    #print how far off the predicted value was from the data    if value % 10000 == 0:        print "Error:" + str(np.mean(np.abs(layer2_error))) #average error    #find out how much to re-adjust weights based on how far off and how confident the estimate    layer2_change = layer2_error * nonlin(layer2, deriv = True)    #find out how layer1 led to error in layer 2, to attack root of problem    layer1_error = layer2_change.dot(secondLayer_weights.T)    #^^sends error on layer2 backwards across weights(dividing) to find original error: BACKPROPAGATION    #same thing as layer2 change, change based on accuracy and confidence    layer1_change = layer1_error * nonlin(layer1, deriv=True)    #modify weights based on multiplication of error between two layers    secondLayer_weights = secondLayer_weights + layer1.T.dot(layer2_change)    firstLayer_weights = firstLayer_weights + layer0.T.dot(layer1_change)

如您所见,这是涉及的数据部分:

input_data = np.array([[1, 1, 1],                       [0, 0, 0],                       [-1, -1, -1],                       [-1, 1, -1]])#also for trainingoutput_data = np.array([[1],                        [0],                        [-1],                        [1]])

权重在这里:

firstLayer_weights = 2*np.random.random((3, 4)) - 1 #size of matrixsecondLayer_weights = 2*np.random.random((4, 1)) - 1

似乎在前一千代之后,权重的调整效率非常低,这让我认为它们已经达到了相对最小值,如下图所示:

权重的相对最小值点

有什么快速有效的替代方法可以解决这个问题吗?


回答:

您的网络的一个问题是输出(layer2元素的值)只能在0到1之间变化,因为您使用了sigmoid非线性。由于您的四个目标值之一是-1,而最接近的可能预测值是0,因此总会至少有25%的误差。以下是一些建议:

  1. 对输出使用独热编码:即设置三个输出节点——分别对应石头剪刀——并训练网络计算这些输出的概率分布(通常使用softmax和交叉熵损失)。

  2. 将网络的输出层设为线性层(应用权重和偏置,但不使用非线性)。要么添加另一层,要么从当前输出层移除非线性。

您可以尝试的其他方法,但不太可能可靠,因为您实际上是在处理分类数据而不是连续输出:

  1. 缩放您的数据,使训练数据中的所有输出都在0到1之间。

  2. 使用产生-1到1之间值的非线性(如tanh)。

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注