python - neural - tensorflow tutorial
TensorFlow para clasificación binaria (1)
Estoy tratando de adaptar este ejemplo MNIST a la clasificación binaria.
Pero al cambiar mis NLABELS
de NLABELS=2
a NLABELS=1
, la función de pérdida siempre devuelve 0 (y precisión 1).
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from tensorflow.examples.tutorials.mnist import input_data
import tensorflow as tf
# Import data
mnist = input_data.read_data_sets(''data'', one_hot=True)
NLABELS = 2
sess = tf.InteractiveSession()
# Create the model
x = tf.placeholder(tf.float32, [None, 784], name=''x-input'')
W = tf.Variable(tf.zeros([784, NLABELS]), name=''weights'')
b = tf.Variable(tf.zeros([NLABELS], name=''bias''))
y = tf.nn.softmax(tf.matmul(x, W) + b)
# Add summary ops to collect data
_ = tf.histogram_summary(''weights'', W)
_ = tf.histogram_summary(''biases'', b)
_ = tf.histogram_summary(''y'', y)
# Define loss and optimizer
y_ = tf.placeholder(tf.float32, [None, NLABELS], name=''y-input'')
# More name scopes will clean up the graph representation
with tf.name_scope(''cross_entropy''):
cross_entropy = -tf.reduce_mean(y_ * tf.log(y))
_ = tf.scalar_summary(''cross entropy'', cross_entropy)
with tf.name_scope(''train''):
train_step = tf.train.GradientDescentOptimizer(10.).minimize(cross_entropy)
with tf.name_scope(''test''):
correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
_ = tf.scalar_summary(''accuracy'', accuracy)
# Merge all the summaries and write them out to /tmp/mnist_logs
merged = tf.merge_all_summaries()
writer = tf.train.SummaryWriter(''logs'', sess.graph_def)
tf.initialize_all_variables().run()
# Train the model, and feed in test data and record summaries every 10 steps
for i in range(1000):
if i % 10 == 0: # Record summary data and the accuracy
labels = mnist.test.labels[:, 0:NLABELS]
feed = {x: mnist.test.images, y_: labels}
result = sess.run([merged, accuracy, cross_entropy], feed_dict=feed)
summary_str = result[0]
acc = result[1]
loss = result[2]
writer.add_summary(summary_str, i)
print(''Accuracy at step %s: %s - loss: %f'' % (i, acc, loss))
else:
batch_xs, batch_ys = mnist.train.next_batch(100)
batch_ys = batch_ys[:, 0:NLABELS]
feed = {x: batch_xs, y_: batch_ys}
sess.run(train_step, feed_dict=feed)
He comprobado las dimensiones de batch_ys
(alimentado en y
) y _y
y ambas son matrices NLABELS=1
cuando NLABELS=1
por lo que el problema parece ser anterior a eso. ¿Tal vez algo que ver con la multiplicación de matrices?
De hecho, tengo este mismo problema en un proyecto real, por lo que cualquier ayuda sería apreciada ... ¡Gracias!
El ejemplo original de MNIST utiliza una codificación instantánea para representar las etiquetas en los datos: esto significa que si hay NLABELS = 10
clases (como en MNIST), la salida de destino es [1 0 0 0 0 0 0 0 0 0]
para la clase 0, [0 1 0 0 0 0 0 0 0 0]
para la clase 1, etc. El operador tf.nn.softmax()
convierte los logits calculados por tf.matmul(x, W) + b
en una distribución de probabilidad a través de las diferentes clases de salida, que luego se compara con el valor introducido para y_
.
Si NLABELS = 1
, esto actúa como si hubiera solo una clase, y la op tf.nn.softmax()
computaría una probabilidad de 1.0
para esa clase, lo que lleva a una entropía cruzada de 0.0
, desde tf.log(1.0)
es 0.0
para todos los ejemplos.
Hay (al menos) dos enfoques que podrías probar para la clasificación binaria:
Lo más simple sería establecer
NLABELS = 2
para las dos clases posibles, y codificar sus datos de entrenamiento como[1 0]
para la etiqueta 0 y[0 1]
para la etiqueta 1. Esta respuesta tiene una sugerencia sobre cómo hacerlo.Puede mantener las etiquetas como números enteros
0
y1
y usartf.nn.sparse_softmax_cross_entropy_with_logits()
, como se sugiere en esta respuesta .