Классификация MNIST: низкая точность (10%) и отсутствие изменений в потерях

Я изучаю TensorFlow и устал применять в базе данных mnist. Мой вопрос (см. прикрепленное изображение):

  • что могло вызвать такой вывод для точности (улучшение, а затем ухудшение!) И потери (почти постоянные!)
  • точность не так велика, просто колеблется в районе 10%

Точность/потери - Tensorboard]

Несмотря на:

  • 5-слойная сеть (включая выходной слой), с 200/10/60/30/10 нейронами соответственно
  • Сеть не учится? несмотря на скорость обучения 0,1 (что, я считаю, довольно высоко)

Полный код: https://github.com/vibhorj/tf > mnist-2.py

1) вот как определяются слои:

K,L,M,N=200,100,60,30
""" Layer 1 """
with tf.name_scope('L1'):
    w1 = tf.Variable(initial_value = tf.truncated_normal([28*28,K],mean=0,stddev=0.1), name = 'w1')
    b1 = tf.Variable(initial_value = tf.truncated_normal([K],mean=0,stddev=0.1), name = 'b1')
""" Layer 2 """
with tf.name_scope('L2'):
    w2 = tf.Variable(initial_value =tf.truncated_normal([K,L],mean=0,stddev=0.1), name = 'w2')
    b2 = tf.Variable(initial_value = tf.truncated_normal([L],mean=0,stddev=0.1), name = 'b2')
""" Layer 3 """
with tf.name_scope('L3'):
    w3 = tf.Variable(initial_value = tf.truncated_normal([L,M],mean=0,stddev=0.1), name = 'w3')
    b3 = tf.Variable(initial_value = tf.truncated_normal([M],mean=0,stddev=0.1), name = 'b3')
""" Layer 4 """
with tf.name_scope('L4'):
    w4 = tf.Variable(initial_value = tf.truncated_normal([M,N],mean=0,stddev=0.1), name = 'w4')
    b4 = tf.Variable(initial_value = tf.truncated_normal([N],mean=0,stddev=0.1), name = 'b4')
""" Layer output """
with tf.name_scope('L_out'):
    w_out = tf.Variable(initial_value = tf.truncated_normal([N,10],mean=0,stddev=0.1), name = 'w_out')
    b_out = tf.Variable(initial_value = tf.truncated_normal([10],mean=0,stddev=0.1), name = 'b_out')

2) функция потерь

Y1 = tf.nn.sigmoid(tf.add(tf.matmul(X,w1),b1), name='Y1')
Y2 = tf.nn.sigmoid(tf.add(tf.matmul(Y1,w2),b2), name='Y2')
Y3 = tf.nn.sigmoid(tf.add(tf.matmul(Y2,w3),b3), name='Y3')
Y4 = tf.nn.sigmoid(tf.add(tf.matmul(Y3,w4),b4), name='Y4')

Y_pred_logits = tf.add(tf.matmul(Y4, w_out),b_out,name='logits')
Y_pred_prob = tf.nn.softmax(Y_pred_logits, name='probs')

error = -tf.matmul(Y
              , tf.reshape(tf.log(Y_pred_prob),[10,-1]), name ='err')
loss = tf.reduce_mean(error, name = 'loss')

3) функция оптимизации

opt = tf.train.GradientDescentOptimizer(0.1)
grads_and_vars = opt.compute_gradients(loss)
ctr = tf.Variable(0.0, name='ctr')
z = opt.apply_gradients(grads_and_vars, global_step=ctr)  

4) Код тензорборда:

evt_file = tf.summary.FileWriter('/Users/vibhorj/python/-tf/g_mnist')
evt_file.add_graph(tf.get_default_graph())

s1 = tf.summary.scalar(name='accuracy', tensor=accuracy)
s2 = tf.summary.scalar(name='loss', tensor=loss)
m1 = tf.summary.merge([s1,s2])

5) запустить сеанс (тестовые данные mnist.test.images и mnist.test.labels

with tf.Session() as sess:
    sess.run(tf.variables_initializer(tf.global_variables()))
    for i in range(300):
       """ calc. accuracy on test data - TENSORBOARD before iteration beings """
       summary = sess.run(m1, feed_dict=test_data)
       evt_file.add_summary(summary, sess.run(ctr))
       evt_file.flush()

       """ fetch train data """        
       a_train, b_train = mnist.train.next_batch(batch_size=100)
       train_data = {X: a_train , Y: b_train}

       """ train """
       sess.run(z, feed_dict = train_data)

Цените свое время, чтобы дать какое-либо представление об этом. Я совершенно не знаю, как двигаться дальше (даже пытался инициализировать w & b с помощью random_normal, играл со скоростью обучения [0,1, 0,01, 0,001])

Ваше здоровье!


person Vibhor Jain    schedule 16.11.2017    source источник
comment
У вас есть Gist или общедоступный репозиторий, который мы можем проверить, чтобы найти проблему? У меня был быстрый обзор, но просмотр такого кода на этой странице занимает много времени. Обзор до сих пор: Возможно, что-то с областями имен.   -  person Eric Platon    schedule 16.11.2017
comment
Большое спасибо, что посмотрели! github.com/vibhorj/tf › mnist-2.py   -  person Vibhor Jain    schedule 16.11.2017
comment
Основные вопросы: (1) Чем ваша архитектура отличается от классических решений MNIST? (2) Существует ли аналогичная, более широкая топология, которая хорошо обучается? Например, что произойдет, если вы измените второй слой с 10 до 30 нейронов? Эти проверки помогут сузить проблему (устранить топологию как проблему).   -  person Prune    schedule 16.11.2017
comment
Есть общедоступный пример для TF и ​​MNiST, пожалуйста, прочитайте документы   -  person brown.2179    schedule 18.11.2017


Ответы (1)


Пожалуйста примите к сведению

  1. Инициализация смещений нулями
  2. Использование единиц ReLU вместо сигмовидных — избегайте насыщения
  3. Использование оптимизатора Adam — более быстрое обучение

Я чувствую, что ваша сеть довольно велика. Вы могли бы сделать с меньшей сети.

K,L,M,N=200,100,60,30
""" Layer 1 """
with tf.name_scope('L1'):
    w1 = tf.Variable(initial_value = tf.truncated_normal([28*28,K],mean=0,stddev=0.1), name = 'w1')
    b1 = tf.zeros([K])#tf.Variable(initial_value = tf.truncated_normal([K],mean=0,stddev=0.01), name = 'b1')
""" Layer 2 """
with tf.name_scope('L2'):
    w2 = tf.Variable(initial_value =tf.truncated_normal([K,L],mean=0,stddev=0.1), name = 'w2')
    b2 = tf.zeros([L])#tf.Variable(initial_value = tf.truncated_normal([L],mean=0,stddev=0.01), name = 'b2')
""" Layer 3 """
with tf.name_scope('L3'):
    w3 = tf.Variable(initial_value = tf.truncated_normal([L,M],mean=0,stddev=0.1), name = 'w3')
    b3 = tf.zeros([M]) #tf.Variable(initial_value = tf.truncated_normal([M],mean=0,stddev=0.01), name = 'b3')
""" Layer 4 """
with tf.name_scope('L4'):
    w4 = tf.Variable(initial_value = tf.truncated_normal([M,N],mean=0,stddev=0.1), name = 'w4')
    b4 = tf.zeros([N])#tf.Variable(initial_value = tf.truncated_normal([N],mean=0,stddev=0.1), name = 'b4')
""" Layer output """
with tf.name_scope('L_out'):
    w_out = tf.Variable(initial_value = tf.truncated_normal([N,10],mean=0,stddev=0.1), name = 'w_out')
    b_out = tf.zeros([10])#tf.Variable(initial_value = tf.truncated_normal([10],mean=0,stddev=0.1), name = 'b_out')


Y1 = tf.nn.relu(tf.add(tf.matmul(X,w1),b1), name='Y1')
Y2 = tf.nn.relu(tf.add(tf.matmul(Y1,w2),b2), name='Y2')
Y3 = tf.nn.relu(tf.add(tf.matmul(Y2,w3),b3), name='Y3')
Y4 = tf.nn.relu(tf.add(tf.matmul(Y3,w4),b4), name='Y4')

Y_pred_logits = tf.add(tf.matmul(Y4, w_out),b_out,name='logits')

loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=Y, logits=Y_pred_logits, name='xentropy'))
opt = tf.train.GradientDescentOptimizer(0.01)
grads_and_vars = opt.compute_gradients(loss)
ctr = tf.Variable(0.0, name='ctr', trainable=False)
train_op = opt.minimize(loss, global_step=ctr)

for v in tf.trainable_variables():
  print v.op.name

with tf.Session() as sess:
    sess.run(tf.variables_initializer(tf.global_variables()))
    for i in range(3000):
       """ calc. accuracy on test data - TENSORBOARD before iteration beings """
       #summary = sess.run(m1, feed_dict=test_data)
       #evt_file.add_summary(summary, sess.run(ctr))
       #evt_file.flush()

       """ fetch train data """
       a_train, b_train = mnist.train.next_batch(batch_size=100)
       train_data = {X: a_train , Y: b_train}

       """ train """
       l = sess.run(loss, feed_dict = train_data)
       print l
       sess.run(train_op, feed_dict = train_data)
person dgumo    schedule 16.11.2017
comment
Большое спасибо, что поделились советом. После 1) инициализации смещения до 0, 2) активации RELU, за исключением потери выходного слоя nan и без изменения точности (9,79%). EVen снизил скорость обучения до 0,00001. - person Vibhor Jain; 16.11.2017
comment
Не могли бы вы поделиться своим последним кодом? Я вижу, что потери для кода, который я разместил выше, снижаются. - person dgumo; 16.11.2017
comment
вот вам github.com/vibhorj/tf /blob/master/so-changes/mnist-2-so.py Большое спасибо! Интересно, код выглядит очень похоже, но потери уменьшаются в вашем понимании... может быть, это потому, что я не использую встроенную функцию tf.nn.softmax_cross_entropy_with_logits() для расчета потерь? - person Vibhor Jain; 17.11.2017
comment
Могу я спросить, почему вы рекомендуете инициализировать смещение до 0? какие последствия это имеет.. большинство людей говорят, что используют случайные значения для инициализации.. - person Vibhor Jain; 17.11.2017
comment
Это принято. Для единиц relu небольшое положительное значение может быть хорошим, так как это гарантирует, что градиенты текут изначально. - person dgumo; 17.11.2017
comment
Для вашей потери NaN функция, которую я использовал, численно стабильна. Вы можете Google для обсуждения по этому вопросу. Кстати, не могли бы вы проголосовать, если решение выше помогло? - person dgumo; 17.11.2017
comment
Спасибо за разъяснения относительно RELU. но я все еще не понимаю, почему ваш код работает (потери уменьшаются), а мой нет, они оба почти одинаковы! может быть потому, что я не использую встроенную функцию tf.nn.softmax_cross_entropy_with_logits() для расчета потерь? - person Vibhor Jain; 17.11.2017
comment
См. это обсуждение: stackoverflow.com/questions/34240703/ - person dgumo; 17.11.2017
comment
Давайте продолжим это обсуждение в чате. - person Vibhor Jain; 17.11.2017