2015-11-17 2 views
13

Я хочу создать тривиальную нейронную сеть, она должна просто реализовать XOR-ворота. Я использую библиотеку TensorFlow в python. Для ворот XOR, единственными данными, с которыми я тренируюсь, является полная таблица истинности, которой должно быть достаточно право? Над оптимизацией я ожидаю, что это произойдет очень быстро. Проблема с кодом заключается в том, что веса и предубеждения не обновлять. Каким-то образом он до сих пор дает мне 100% -ную точность с нулем для смещений и весов.Проблемы с внедрением XOR-ворот с нейронными сетями в Tensorflow

x = tf.placeholder("float", [None, 2]) 
W = tf.Variable(tf.zeros([2,2])) 
b = tf.Variable(tf.zeros([2])) 

y = tf.nn.softmax(tf.matmul(x,W) + b) 

y_ = tf.placeholder("float", [None,1]) 


print "Done init" 

cross_entropy = -tf.reduce_sum(y_*tf.log(y)) 
train_step = tf.train.GradientDescentOptimizer(0.75).minimize(cross_entropy) 

print "Done loading vars" 

init = tf.initialize_all_variables() 
print "Done: Initializing variables" 

sess = tf.Session() 
sess.run(init) 
print "Done: Session started" 

xTrain = np.array([[0, 0], [0, 1], [1, 0], [1, 1]]) 
yTrain = np.array([[1], [0], [0], [0]]) 


acc=0.0 
while acc<0.85: 
    for i in range(500): 
     sess.run(train_step, feed_dict={x: xTrain, y_: yTrain}) 


    print b.eval(sess) 
    print W.eval(sess) 


    print "Done training" 


    correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1)) 

    accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float")) 

    print "Result:" 
    acc= sess.run(accuracy, feed_dict={x: xTrain, y_: yTrain}) 
    print acc 

B0 = b.eval(sess)[0] 
B1 = b.eval(sess)[1] 
W00 = W.eval(sess)[0][0] 
W01 = W.eval(sess)[0][1] 
W10 = W.eval(sess)[1][0] 
W11 = W.eval(sess)[1][1] 

for A,B in product([0,1],[0,1]): 
    top = W00*A + W01*A + B0 
    bottom = W10*B + W11*B + B1 
    print "A:",A," B:",B 
    # print "Top",top," Bottom: ", bottom 
    print "Sum:",top+bottom 

Я следую учебник от http://tensorflow.org/tutorials/mnist/beginners/index.md#softmax_regressions и в конечном для петли я печати результаты образуют матрицу (как описано в ссылке).

Может кто-нибудь указать мою ошибку и что я должен сделать, чтобы исправить ее?

ответ

19

Есть несколько проблем с вашей программой.

Первая проблема заключается в том, что функция, которую вы изучаете, не XOR - это NOR. Линии:

xTrain = np.array([[0, 0], [0, 1], [1, 0], [1, 1]]) 
yTrain = np.array([[1], [0], [0], [0]]) 

... должно быть:

xTrain = np.array([[0, 0], [0, 1], [1, 0], [1, 1]]) 
yTrain = np.array([[0], [1], [1], [0]]) 

Следующая большая проблема в том, что сеть вы создали isn't capable of learning XOR. Вы должны будете использовать нелинейную функцию (например, tf.nn.relu() и определить, по крайней мере, еще один слой, чтобы узнать функцию XOR Например:.

x = tf.placeholder("float", [None, 2]) 
W_hidden = tf.Variable(...) 
b_hidden = tf.Variable(...) 
hidden = tf.nn.relu(tf.matmul(x, W_hidden) + b_hidden) 

W_logits = tf.Variable(...) 
b_logits = tf.Variable(...) 
logits = tf.matmul(hidden, W_logits) + b_logits 

Еще одна проблема в том, что при инициализации весов к нулю будет prevent your network from training . Как правило, вы должны инициализировать веса случайным образом, и ваши пристрастия к нулю Вот один популярный способ сделать это:.

HIDDEN_NODES = 2 

W_hidden = tf.Variable(tf.truncated_normal([2, HIDDEN_NODES], stddev=1./math.sqrt(2))) 
b_hidden = tf.Variable(tf.zeros([HIDDEN_NODES])) 

W_logits = tf.Variable(tf.truncated_normal([HIDDEN_NODES, 2], stddev=1./math.sqrt(HIDDEN_NODES))) 
b_logits = tf.Variable(tf.zeros([2])) 

Собираем все вместе, и используя TensorFlow процедуры для кросс-энтропии (с одной горячей кодировка yTrain для удобства), вот программа, которая изучает XOR:

import math 
import tensorflow as tf 
import numpy as np 

HIDDEN_NODES = 10 

x = tf.placeholder(tf.float32, [None, 2]) 
W_hidden = tf.Variable(tf.truncated_normal([2, HIDDEN_NODES], stddev=1./math.sqrt(2))) 
b_hidden = tf.Variable(tf.zeros([HIDDEN_NODES])) 
hidden = tf.nn.relu(tf.matmul(x, W_hidden) + b_hidden) 

W_logits = tf.Variable(tf.truncated_normal([HIDDEN_NODES, 2], stddev=1./math.sqrt(HIDDEN_NODES))) 
b_logits = tf.Variable(tf.zeros([2])) 
logits = tf.matmul(hidden, W_logits) + b_logits 

y = tf.nn.softmax(logits) 

y_input = tf.placeholder(tf.float32, [None, 2]) 

cross_entropy = tf.nn.softmax_cross_entropy_with_logits(logits, y_input) 
loss = tf.reduce_mean(cross_entropy) 

train_op = tf.train.GradientDescentOptimizer(0.2).minimize(loss) 

init_op = tf.initialize_all_variables() 

sess = tf.Session() 
sess.run(init_op) 

xTrain = np.array([[0, 0], [0, 1], [1, 0], [1, 1]]) 
yTrain = np.array([[1, 0], [0, 1], [0, 1], [1, 0]]) 

for i in xrange(500): 
    _, loss_val = sess.run([train_op, loss], feed_dict={x: xTrain, y_input: yTrain}) 

    if i % 10 == 0: 
    print "Step:", i, "Current loss:", loss_val 
    for x_input in [[0, 0], [0, 1], [1, 0], [1, 1]]: 
     print x_input, sess.run(y, feed_dict={x: [x_input]}) 

Обратите внимание, что это, вероятно, не самая эффективная нейронная сеть для вычисления XOR, поэтому предложения по настройке параметров приветствуются!

+0

Большое спасибо за подробный ответ. Это было очень полезно! –

+0

Является ли это Full-Adder сейчас? – schwenk

+1

Не совсем, поскольку он не моделирует бит переноса вывода. Есть два выходных бита из полудателя (сумма и перенос-вывод), поэтому вам понадобится 4 класса вывода (если вы используете однострунную кодировку для выходного класса, который я использовал здесь). Для полного сумматора вам также потребуется смоделировать третий вход. Оба они должны быть простым дополнением к коду, который я опубликовал. – mrry

Смежные вопросы