基本神经网络学习XOR问题大约有一半时间会得到正确答案,另一半时间则会趋向于一些恒定但奇怪的答案

我正在学习Theano,并且构建了一个非常简单的学习XOR的神经网络。一个简单的问题应该很快就能学会。但我发现答案有时并不正确,而是出现了一种奇怪的特定错误。

我输入[[0,0],[1,0],[0,1],[1,1]]来测试XOR。我期望得到[0,1,1,0]的输出。确实,大约有一半的时间我得到了这样的结果。

[[ 0.01763905] [ 0.99207316] [ 0.99207316] [ 0.00663723]]

但其他时候我得到了一些组合,其中两个输出几乎正好是0.5,一个接近1,另一个接近0。如下所示,

[[ 0.49998723] [ 0.49998723] [ 0.99430759] [ 0.00622013]]

或者类似的情况如

[[ 0.49957245] [ 0.98064991] [ 0.49957245] [ 0.02422073]]

这是我的代码。如果我训练的方式有问题,请随时告诉我(因为我完全是猜测是否应该为每一层分别计算梯度)

import theanoimport theano.tensor as Timport numpy as npclass HiddenLayer(object):    def __init__(self, input, layerShape):        # Input should be matrix of size (batch size, input nodes)        # Layer shape is (input nodes, hidden nodes)        self.input = input        self.W = theano.shared(np.random.normal(0,1,layerShape))        self.b = theano.shared(np.random.normal(0,1,layerShape[1]))        self.output = T.nnet.nnet.relu(T.dot(self.input,self.W)+self.b)    def train(self, cost, rate):        WGrad = T.grad(cost=cost, wrt=self.W)        bGrad = T.grad(cost=cost, wrt=self.b)        return [[self.W, self.W - WGrad * rate],                [self.b, self.b - bGrad * rate]]class OutputLayer(object):    def __init__(self, input, layerShape):        self.input = input        self.W = theano.shared(np.random.normal(0,1,layerShape))        self.b = theano.shared(np.random.normal(0,1,layerShape[1]))        self.output = T.nnet.nnet.sigmoid(T.dot(self.input,self.W)+self.b)    def train(self, cost, rate):        WGrad = T.grad(cost=cost, wrt=self.W)        bGrad = T.grad(cost=cost, wrt=self.b)        return [[self.W, self.W - WGrad * rate],                [self.b, self.b - bGrad * rate]]class Model(object):    def __init__(self, inputNodes, hiddenNodes, outputNodes, rate):        self.x = T.matrix()        self.y_ = T.matrix()        hiddenLayer = HiddenLayer(self.x, (inputNodes, hiddenNodes))        outputLayer = OutputLayer(hiddenLayer.output, (hiddenNodes, outputNodes))        self.layers = [hiddenLayer, outputLayer]        self.y = outputLayer.output        self.train = self.buildTrainOp(rate)        self.infer = self.buildInferenceOp()    def buildTrainOp(self, rate):        cost = T.mean(T.sqr(self.y - self.y_))        updates = [update for updates in [layer.train(cost, rate) for layer in self.layers] for update in updates]        return theano.function(inputs=[self.x, self.y_], outputs=cost, updates=updates)    def buildInferenceOp(self):        return theano.function(inputs=[self.x], outputs=self.y)nn = Model(2, 3, 1, 0.05)print(nn.infer([[0,0],[1,0],[0,1],[1,1]]))xorTableX = [[0,0],[1,0],[0,1],[1,1]]xorTableY = [[i!=j] for i,j in xorTableX]for i in range(100000):    batchX = xorTableX    batchY = xorTableY    nn.train(batchX, batchY)print(nn.infer([[0,0],[1,0],[0,1],[1,1]]))

如果你有关于使用Theano的好做法和惯例的建议,我也非常乐意听取。谢谢!

** 编辑:** 有趣的是,当我添加了第二个相同大小的隐藏层时,”错误”的输出变成了[0.5, 0.5, 0.5, 0.5]。但同样,我仍然大约有一半的时间得到正确输出。


回答:

天哪!这太明显了。这就是我为什么不应该在深夜编程的原因。

我将隐藏层的激活函数改成了ReLU,想看看这对神经网络有什么影响,但忘记改回Tanh了。显然ReLU不允许需要的负权重。

Related Posts

Keras Dense层输入未被展平

这是我的测试代码: from keras import…

无法将分类变量输入随机森林

我有10个分类变量和3个数值变量。我在分割后直接将它们…

如何在Keras中对每个输出应用Sigmoid函数?

这是我代码的一部分。 model = Sequenti…

如何选择类概率的最佳阈值?

我的神经网络输出是一个用于多标签分类的预测类概率表: …

在Keras中使用深度学习得到不同的结果

我按照一个教程使用Keras中的深度神经网络进行文本分…

‘MatMul’操作的输入’b’类型为float32,与参数’a’的类型float64不匹配

我写了一个简单的TensorFlow代码,但不断遇到T…

发表回复

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