Проблема с оптимизацией параметров в базовом многослойном персептроне

#python #tensorflow

#python #tensorflow

Вопрос:

Я совсем недавно начал изучать Tensorflow, но у меня возникли некоторые проблемы с расширением от простой однослойной нейронной сети до многослойной. Я вставил приведенный ниже код из своей попытки, любая помощь в объяснении того, почему он не работает, была бы весьма признательна!

 import tensorflow as tf
from tqdm import trange
from tensorflow.examples.tutorials.mnist import input_data

# Import data
mnist = input_data.read_data_sets("datasets/MNIST_data/", one_hot=True)

x = tf.placeholder(tf.float32, [None, 784])
W0 = tf.Variable(tf.zeros([784, 500]))
b0 = tf.Variable(tf.zeros([500]))
y0 = tf.matmul(x, W0)   b0
relu0 = tf.nn.relu(y0)
W1 = tf.Variable(tf.zeros([500, 100]))
b1= tf.Variable(tf.zeros([100]))
y1 = tf.matmul(relu0, W1)   b1
relu1 = tf.nn.relu(y1)
W2 = tf.Variable(tf.zeros([100, 10]))
b2= tf.Variable(tf.zeros([10]))
y2 = tf.matmul(relu1, W2)   b2
y = y2


# Define loss and optimizer
y_ = tf.placeholder(tf.float32, [None, 10])
cross_entropy =       tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y_, logits=y))
train_step = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy)

# Create a Session object, initialize all variables
sess = tf.Session()
sess.run(tf.global_variables_initializer())
# Train
for _ in trange(1000):
    batch_xs, batch_ys = mnist.train.next_batch(100)    
    sess.run(train_step, feed_dict={x: batch_xs, y_: batch_ys})

# Test trained model
correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
print('Test accuracy: {0}'.format(sess.run(accuracy, feed_dict={x: 
mnist.test.images, y_: mnist.test.labels})))

sess.close()
  

PS: Я знаю, что этот код может быть выполнен намного проще с помощью Keras или даже готовых слоев Tensorflow, но я пытаюсь получить более базовое представление о математике, лежащей в основе библиотеки. Спасибо!

Ответ №1:

Вам нужно принять во внимание 2 вещи.

1) tf.Variable(tf.zeros([784, 500])) измените это на tf.Variable(tf.random_normal([784, 500])) , поскольку лучше иметь случайную инициализацию весов, а не определять их как 0 с самого начала. При первоначальном значении 0 (что означает, что все получает одинаковое значение) модель будет следовать одному и тому же пути градиента и не сможет учиться. Для начала измените каждую zeros на random_normal . Есть лучшие способы сначала определить переменные, но это даст вам хорошее начало

2) ваша скорость обучения слишком высока train_step = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy) измените эту строку на

 train_step = tf.train.GradientDescentOptimizer(0.005).minimize(cross_entropy)
  

Комментарии:

1. Спасибо за ваш комментарий! По какой-то причине, даже после исправления этих строк, я все еще смотрю на показатели точности около 10%, что эквивалентно угадыванию по набору данных MNIST. Есть ли случайно более серьезная проблема с моей моделью?

2. Вы изменили все tf.zeros с tf.random_normal помощью? Потому что с этой моделью я получаю точность теста 88%.

3. By making it 0 model is unable to compute gradient — Это неверно.

4. Технически да, вы правы. Я не хотел вдаваться в подробности, я отредактирую эту строку. Было бы более уместно сказать, что модель застряла в некоторых локальных минимумах, она ведет себя как линейная модель. Плюс все нейроны, начинающиеся с одного и того же значения, будут проходить одинаковый путь при вычислении градиента.