#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. Технически да, вы правы. Я не хотел вдаваться в подробности, я отредактирую эту строку. Было бы более уместно сказать, что модель застряла в некоторых локальных минимумах, она ведет себя как линейная модель. Плюс все нейроны, начинающиеся с одного и того же значения, будут проходить одинаковый путь при вычислении градиента.