Pregunta

Hay muchos recursos en línea sobre cómo implementar MLP en TensorFlow, y la mayoría de las muestras funcionan :) Pero estoy interesado en uno particular, que aprendí https://www.coursera.org/learn/machine-lelarning. En el que usa un costo función definida de la siguiente manera:

$ J ( theta) = frac {1} {m} sum_ {i = 1}^{m} sum_ {k = 1}^{k} izquierda [-y_k^{(i)} log ((h_ theta (x^{(i)})) _ k - (1 - y_k^{(i)}) log (1 - (h_ theta (x^{(i)})) _ K correcto ps

$ h_ theta $ es el sigmoideo función.

Y ahí está mi implementación:

# 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))

Creo que la definición de las capas es correcta, pero el problema está en el cross_entropy. Si uso el primero, el que se comentó, el modelo converge rápidamente; Pero si uso el segundo, que creo/espero que sea la traducción de la ecuación anterior, el modelo no convergerá.

¿Fue útil?

Solución

Cometiste tres errores:

  1. Omitió los términos de compensación antes de las transformaciones no lineales (variables B_1 y B_Out). Esto aumenta el poder representativo de la red neuronal.
  2. Omitió la transformación Softmax en la capa superior. Esto hace que la salida sea una distribución de probabilidad, por lo que puede calcular la entropía cruzada, que es la función de costo habitual para la clasificación.
  3. Utilizó la forma binaria de la entropía cruzada cuando debería haber usado la forma de clase múltiple.

Cuando ejecuto esto, tengo precisiones más del 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))
Licenciado bajo: CC-BY-SA con atribución
scroll top