2017-08-07 90 views
2

我有下面的代碼來學習簡單的XOR網絡:TensorFlow簡單的XOR例如不收斂

import tensorflow as tf 
import numpy as np 

def generate_xor(length=1000): 
    x = np.random.randint(0,2, size=(length,2)) 
    y = [] 
    for pair in x: 
     y.append(int(np.logical_xor(pair[0],pair[1]))) 
    return x, np.array(y) 

n_inputs = 2 
n_hidden = n_inputs*4 
n_outputs = 1 


x = tf.placeholder(tf.float32, shape=[1,n_inputs]) 
y = tf.placeholder(tf.float32, [1, n_outputs]) 

W = tf.Variable(tf.random_uniform([n_inputs, n_hidden],-1,1)) 
b = tf.Variable(tf.zeros([n_hidden])) 

W2 = tf.Variable(tf.random_uniform([n_hidden,n_outputs],-1,1)) 
b2 = tf.Variable(tf.zeros([n_outputs])) 

def xor_model(data): 
    x = data 
    hidden_layer = tf.nn.relu(tf.matmul(x,W)+b) 
    output = tf.nn.relu(tf.matmul(hidden_layer, W2)+b2) 
    return output 

xor_nn = xor_model(x) 
cost = tf.reduce_mean(tf.abs(xor_nn - y)) 
train_step = tf.train.AdagradOptimizer(0.05).minimize(cost) 

init = tf.initialize_all_variables() 
sess = tf.Session() 
sess.run(init) 

x_data,y_data = generate_xor(length=100000) 
errors = [] 
count = 0 
out_freq = 1000 
for xor_in, xor_out in zip(x_data,y_data): 
    _, err = sess.run([train_step, cost], feed_dict={x:xor_in.reshape(1,2), y:xor_out.reshape(1,n_outputs)}) 
    errors.append(err) 
    count += 1 

    if count == out_freq: 
     tol = np.mean(errors[-out_freq:]) 
     print tol 
     count = 0 
     if tol < 0.005: 
      break 


n_tests = 100 
correct = 0 
count = 0 
x_test, y_test = generate_xor(length=n_tests) 
for xor_in, xor_out in zip(x_test, y_test): 
    output = sess.run([xor_nn], feed_dict={x:xor_in.reshape(1,2)})[0] 
    guess = int(output[0][0]) 
    truth = int(xor_out) 
    if guess == truth: 
     correct += 1 
    count += 1 
    print "Model %d : Truth %d - Pass Rate %.2f" % (int(guess), int(xor_out), float(correct*100.0)/float(count)) 

但是,我不能可靠地收斂的代碼。我嘗試改變隱藏層的大小,使用不同的優化器/步長和不同的權重和偏差初始化。

我很明顯正在做一個元素錯誤。如果有人能幫助我會很感激。

編輯:

感謝炳廷和亞歷山大Svetkin我設法發現我的錯誤。首先,當我把它們輸入整數時,我沒有把輸出四捨五入,這是一個男生的錯誤。其次,我有一個relu在輸出層,這是不需要的 - 複製和粘貼錯誤。第三,relu確實是這項任務的激活函數的一個錯誤選擇,使用sigmoid函數效果更好。

所以這個:

hidden_layer = tf.nn.relu(tf.matmul(x,W)+b) 
output = tf.nn.relu(tf.matmul(hidden_layer, W2)+b2) 

變成這樣:

hidden_layer = tf.nn.sigmoid(tf.matmul(x,W)+b) 
output = tf.matmul(hidden_layer, W2)+b2 

這:

guess = int(output[0][0]) 

變成這樣:

guess = int(output[0][0]+0.5) 

回答

1

不應該只返回輸出層的激活功能而不是relu

output = tf.matmul(hidden_layer, W2) + b2 
1
  1. RELU只是不是二元分類任務右激活功能,使用不同的東西,像雙曲線函數。
  2. 注意你的浮點輸出值。 0.99應該是1還是0?使用舍入。