2017-04-26 4 views
0

저는 Theano를 배우면서 XOR을 배우는 매우 간단한 NN을 만들었습니다. 간단한 문제는 상당히 빨리 배워야합니다. 그러나 내가 발견 한 것은 그 해답이 때로는 정확하지 않지만 이상한 특정 오류이다.기본 NN 학습 XOR은 절반 정도의 시간에 대한 정답으로, 다른 경우는 일정하지만 이상한 대답으로 이어집니다.

[[0,0], [1,0], [0,1], [1,1]]을 입력하여 XOR을 테스트합니다. [0,1,1,0] 출력을 기대해야합니다. 그리고 실제로, 나는 그 절반 정도의 시간을 얻습니다.

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

그러나 다른 시간 나는 비슷한

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

또는 뭔가를 하나 하나 거의이고, 출력의 두 거의 정확히 0.5있는 조합의 일종을 얻을, 그래서 같이 다른 거의 0 like

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

여기 내 코드가 있습니다.

import theano 
import theano.tensor as T 
import numpy as np 

class 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]가됩니다. 그러나 다시, 나는 아직도 절반 정도의 정확한 출력을 얻고있다.

+0

비용 ('T.nnet.binary_crossentropy')에 크로스 엔트로피를 사용해 보셨습니까? 그리고 당신의 훈련 곡선은 어떻게 생겼습니까? – Simon

답변

0

D' oh! 그것은 고통스럽게 명백했다. 이것이 야간에 늦게 프로그램해서는 안되는 이유입니다.

내 숨겨진 레이어에 대해 ReLU로 전환하여 NN에 미치는 영향을 확인했지만 Tanh로 다시 전환하는 것을 잊었습니다. 분명히 ReLU는 필요한 음의 가중치를 허용하지 않습니다.