基本神经网络学习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

如何评估在Google AI Platform上使用内置Linear Learner训练的分类模型?

我在尝试评估使用Google AI Platform内…

如何解决tf_serving_entrypoint.sh: 第3行: 6 非法指令(核心已转储)的问题,使用tensorflow/serving镜像

我在使用docker镜像tensorflow/serv…

用于重构句子的NLP库

我在寻找一个可以重构单词或句子的NLP库。 我不知道s…

如何显示LinearRegression()的权重和偏置?

我在尝试解决一个线性回归问题,并且使用了sklearn…

在 train_test_split 中使用 ‘stratify’ 并没有区别。它有什么用途?

我在尝试使用 sklearn 的 train_test…

如何将字符串数据分类为整数?

我需要对数据集中某个特征的字符串值进行分类,以便进一步…

发表回复

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