Учебное пособие по Tensorflow MNIST - точность теста очень низкая

Я начал с tensorflow и следовал этому стандартному руководству по MNIST.

Однако, в отличие от ожидаемой точности 92%, точность, полученная как на обучающем наборе, так и на тестовом наборе, не превышает 67%. Я знаком с softmax и полиномиальной регрессией и получил более 94% результатов, используя чистую реализацию Python, а также используя sklearn.linear_model.LogisticRegression.

Я пробовал то же самое, используя набор данных CIFAR-10, и в этом случае точность была слишком низкой и составляла всего около 10%, что равнозначно случайному назначению классов. Это заставило меня усомниться в моей установке tensorflow, но я не уверен в этом.

Вот моя реализация учебника Tensorflow MNIST. Я бы попросил, если бы кто-нибудь мог взглянуть на мою реализацию.


person codeahead    schedule 24.04.2017    source источник


Ответы (3)


Вы построили свой график, указали функцию потерь и создали оптимизатор (что правильно). Проблема в том, что вы используете свой оптимизатор только один раз:

sess_tf.run(train_step, feed_dict={x: train_images_reshaped[0:1000], y_: train_labels[0:1000]})

Таким образом, вы запускаете свой градиентный спуск только один раз. Ясно, что вы не сможете быстро сойтись после всего лишь одного крошечного шага в правильном направлении. Вам нужно сделать что-то в этом роде:

for _ in xrange(many_steps):
  X, Y = get_a_new_batch_from(mnist_data)
  sess_tf.run(train_step, feed_dict={x: X, y_: Y})

Если вы не сможете понять, как изменить мой псевдокод, обратитесь к учебнику, потому что, насколько я помню, они прекрасно это освещали.

person Salvador Dali    schedule 24.04.2017
comment
Спасибо, что указали на это. Будучи пакетным градиентным спуском в учебнике, я почему-то решил, что мне не нужна итерация, и полностью пропустил концепцию конвергенции. Внесли изменения, и это, как и ожидалось. - person codeahead; 24.04.2017

W = tf.Variable(tf.zeros([784, 10]))
b = tf.Variable(tf.zeros([10]))

Инициализация W может привести к тому, что ваша сеть не будет учиться ничему, кроме случайных предположений. Потому что градиент будет нулевым, а бэкпроп на самом деле вообще не работает.

Вам лучше инициализировать W с помощью tf.Variable(tf.truncated_normal([784, 10], mean=0.0, stddev=0.01)) см. https://www.tensorflow.org/api_docs/python/tf/truncated_normal, чтобы узнать больше.

person Qy Zuo    schedule 24.04.2017
comment
Я пробовал этот подход, но он тоже не сработал, и причина была определена @Salvador Dali. - person codeahead; 24.04.2017

Не уверен, что это все еще актуально в июне 2018 года, но MNIST руководство для начинающих больше не соответствует коду примеру на Гитхабе. Если вы загрузите и запустите пример кода, он действительно даст вам предполагаемую точность 92%.

Я заметил две вещи, которые пошли не так, следуя инструкциям:

1) Случайный вызов softmax дважды

В учебнике сначала предлагается определить y следующим образом:

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

Но позже предлагается определить кросс-энтропию с помощью tf.nn.softmax_cross_entropy_with_logits, что позволит легко случайно сделать следующее:

cross_entropy = tf.nn.softmax_cross_entropy_with_logits(labels=y_, logits=y)

Это дважды отправило бы ваши логиты (tf.matmul(x, W) + b) через softmax, в результате чего я застрял с точностью 67%.

Однако я заметил, что даже исправление этого по-прежнему привело меня к очень нестабильной точности 80-90%, что приводит меня к следующей проблеме:

2) tf.nn.softmax_cross_entropy_with_logits() устарела

Они еще не обновили учебник, но страница tf.nn.softmax_cross_entropy_with_logits указывает, что эта функция устарела.

В примере кода на Github они заменили его на tf.losses.sparse_softmax_cross_entropy(labels=y_, logits=y).

Однако вы не можете просто поменять местами функцию — пример кода также меняет размерность во многих других строках.

Я предлагаю всем, кто делает это впервые, загрузить текущий рабочий код примера с Github и попытаться сопоставить его с концепциями руководства, не воспринимая инструкции буквально. Надеюсь, они соберутся обновить его!

person Casey L    schedule 14.06.2018