Внедрить MLP в TensorFlow
-
16-10-2019 - |
Вопрос
В Интернете есть много ресурсов о том, как внедрить MLP в Tensorflow, и большинство образцов работают :) Но меня интересует конкретный, который я узнал из https://www.coursera.org/learn/machine-learning. Анкет В котором он использует Стоимость Функция определена следующим образом:
$ J ( theta) = frac {1} {m} sum_ {i = 1}^{m} sum_ {k = 1}^{k} Left [-y_k^{(i)} log ((h_ theta (x^{(i)})) _ k - (1 - y_k^{(i)}) log (1 - (h_ theta (x^{(i)})) _ k right ] $
$ h_ theta $ сигмоидальный функция
И есть моя реализация:
# one hidden layer MLP
x = tf.placeholder(tf.float32, shape=[None, 784])
y = tf.placeholder(tf.float32, shape=[None, 10])
W_h1 = tf.Variable(tf.random_normal([784, 512]))
h1 = tf.nn.sigmoid(tf.matmul(x, W_h1))
W_out = tf.Variable(tf.random_normal([512, 10]))
y_ = tf.matmul(h1, W_out)
# cross_entropy = tf.nn.sigmoid_cross_entropy_with_logits(y_, y)
cross_entropy = tf.reduce_sum(- y * tf.log(y_) - (1 - y) * tf.log(1 - y_), 1)
loss = tf.reduce_mean(cross_entropy)
train_step = tf.train.GradientDescentOptimizer(0.05).minimize(loss)
correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
# train
with tf.Session() as s:
s.run(tf.initialize_all_variables())
for i in range(10000):
batch_x, batch_y = mnist.train.next_batch(100)
s.run(train_step, feed_dict={x: batch_x, y: batch_y})
if i % 100 == 0:
train_accuracy = accuracy.eval(feed_dict={x: batch_x, y: batch_y})
print('step {0}, training accuracy {1}'.format(i, train_accuracy))
Я думаю, что определение слоев верно, но проблема в Cross_entropy. Анкет Если я использую первый, один был прокомментирован, модель быстро сходится; Но если я использую 2 -й, который, я думаю,/надеюсь, что это перевод предыдущего уравнения, модель не сходится.
Решение
Вы сделали три ошибки:
- Вы пропустили термины смещения перед нелинейными преобразованием (переменные B_1 и B_OUT). Это увеличивает репрезентативную силу нейронной сети.
- Вы пропустили преобразование Softmax на верхнем слое. Это делает вывод распределением вероятностей, поэтому вы можете рассчитать перекрестную энтропию, которая является обычной функцией стоимости для классификации.
- Вы использовали бинарную форму перекрестной энтропии, когда вы должны были использовать многоклассу.
Когда я запускаю это, я получаю точность более 90%:
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets('/tmp/MNIST_data', one_hot=True)
x = tf.placeholder(tf.float32, shape=[None, 784])
y = tf.placeholder(tf.float32, shape=[None, 10])
W_h1 = tf.Variable(tf.random_normal([784, 512]))
b_1 = tf.Variable(tf.random_normal([512]))
h1 = tf.nn.sigmoid(tf.matmul(x, W_h1) + b_1)
W_out = tf.Variable(tf.random_normal([512, 10]))
b_out = tf.Variable(tf.random_normal([10]))
y_ = tf.nn.softmax(tf.matmul(h1, W_out) + b_out)
# cross_entropy = tf.nn.sigmoid_cross_entropy_with_logits(y_, y)
cross_entropy = tf.reduce_sum(- y * tf.log(y_), 1)
loss = tf.reduce_mean(cross_entropy)
train_step = tf.train.GradientDescentOptimizer(0.05).minimize(loss)
correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
# train
with tf.Session() as s:
s.run(tf.initialize_all_variables())
for i in range(10000):
batch_x, batch_y = mnist.train.next_batch(100)
s.run(train_step, feed_dict={x: batch_x, y: batch_y})
if i % 1000 == 0:
train_accuracy = accuracy.eval(feed_dict={x: batch_x, y: batch_y})
print('step {0}, training accuracy {1}'.format(i, train_accuracy))