Вопрос

В Интернете есть много ресурсов о том, как внедрить 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 -й, который, я думаю,/надеюсь, что это перевод предыдущего уравнения, модель не сходится.

Это было полезно?

Решение

Вы сделали три ошибки:

  1. Вы пропустили термины смещения перед нелинейными преобразованием (переменные B_1 и B_OUT). Это увеличивает репрезентативную силу нейронной сети.
  2. Вы пропустили преобразование Softmax на верхнем слое. Это делает вывод распределением вероятностей, поэтому вы можете рассчитать перекрестную энтропию, которая является обычной функцией стоимости для классификации.
  3. Вы использовали бинарную форму перекрестной энтропии, когда вы должны были использовать многоклассу.

Когда я запускаю это, я получаю точность более 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))
Лицензировано под: CC-BY-SA с атрибуция
Не связан с datascience.stackexchange
scroll top