#python #tensorflow #machine-learning #mnist
#python #tensorflow #машинное обучение #mnist
Вопрос:
Я пытаюсь реализовать MLP в tensorflow с нуля и протестировать его на наборе данных MNIST. Это мой код:
import tensorflow.compat.v1 as tf
from tensorflow.compat.v1.keras.losses import categorical_crossentropy
tf.disable_v2_behavior()
image_tensor = tf.placeholder(tf.float32 , shape=(None , 784))
label_tensor = tf.placeholder(tf.float32 , shape=(None , 10))
# Model architecture
# --> Layer 1
w1 = tf.Variable(tf.random_uniform([784 , 128])) # weights
b1 = tf.Variable(tf.zeros([128])) # bias
a1 = tf.matmul(image_tensor , w1) b1
h1 = tf.nn.relu(a1)
# --> Layer 2
w2 = tf.Variable(tf.random_uniform([128 , 128]))
b2 = tf.zeros([128])
a2 = tf.matmul(h1 , w2) b2
h2 = tf.nn.relu(a2)
# --> output layer
w3 = tf.Variable(tf.random_uniform([128 , 10]))
b3 = tf.zeros([10])
a3 = tf.matmul(h2 , w3) b3
predicted_tensor = tf.nn.softmax(a3)
loss = tf.reduce_mean(categorical_crossentropy(label_tensor , predicted_tensor))
opt = tf.train.GradientDescentOptimizer(0.01)
training_step = opt.minimize(loss)
with tf.Session() as sess:
init_op = tf.global_variables_initializer()
sess.run(init_op)
epochs = 50
batch = 100
iterations = len(training_images) // batch
for j in range(epochs):
start = 0
end = batch
for i in range(iterations):
image_batch = np.array(training_images[start : end])
label_batch = np.array(training_labels[start : end])
start = batch 1
end = start batch
_ , loss = sess.run(training_step , feed_dict = {
image_tensor : image_batch,
label_tensor : label_batch
})
но когда я пытаюсь запустить этот код, я получаю это сообщение об ошибке:
File "MNIST3.py", line 97, in <module>
main()
File "MNIST3.py", line 88, in main
label_tensor : label_batch
TypeError: 'NoneType' object is not iterable
Хотя, когда я пытаюсь распечатать первые 10 образцов из label_batch:
print(training_labels[0 : 10])
Это будет результат:
[[1 0 0 0 0 0 0 0 0 0]
[1 0 0 0 0 0 0 0 0 0]
[1 0 0 0 0 0 0 0 0 0]
[1 0 0 0 0 0 0 0 0 0]
[1 0 0 0 0 0 0 0 0 0]
[1 0 0 0 0 0 0 0 0 0]
[1 0 0 0 0 0 0 0 0 0]
[1 0 0 0 0 0 0 0 0 0]
[1 0 0 0 0 0 0 0 0 0]
[1 0 0 0 0 0 0 0 0 0]]
И когда я пытаюсь напечатать форму набора данных:
print(training_images.shape)
print(training_labels.shape)
Это вывод:
(10000, 784)
(10000, 10)
Чего мне здесь не хватает?
Комментарии:
1. Кроме того, это субъективная вещь, но подумайте также об изучении реализации TF 2.0. Я долгое время использовал TF 1.0, поэтому написал множество сложных моделей, используя графики и session.run, и работа с TF 2.0 до сих пор облегчала мне жизнь. Кроме того, именно там в конечном итоге будет оказана вся поддержка, так что это более прибыльная технология, на которую стоит тратить свое время. (Однако знание графиков, безусловно, полезно, поскольку вы работаете с графиками, например, при создании пользовательских слоев keras)
Ответ №1:
Вы неправильно поняли сообщение об ошибке (Python может вводить в заблуждение в этом, мы все сталкивались с подобными ошибками чаще, чем хотелось бы признать …). Несмотря на то, что он отображает label_tensor : label_batch
строку в вашей ошибке, на самом деле речь идет обо всем session.run()
вызове.
И причина, по которой вы видите эту ошибку, заключается в том, что вы ожидаете, что вызов вернет кортеж, но вы предоставляете только один тензор, который будет вычислен TensorFlow.
sess.run(training_step, feed_dict=...)
вернется None
, потому что op training_step
не должен ничего возвращать, вызывая его, вы просто выполняете один шаг оптимизации.
Чтобы получить желаемый результат, измените код на:
_ , loss_result = sess.run([training_step, loss],
feed_dict={
image_tensor : image_batch,
label_tensor : label_batch
})
Таким образом, TensorFlow оценит эти 2 операции, первая вернет None (как вы уже получаете), а вторая вычислит значение вашей функции потерь для данного пакета.
(Обратите внимание, что вам нужно переименовать переменную loss в левой части, потому что, если вы этого не сделаете, вы замените операцию потери, и следующий вызов, вероятно, вызовет исключение или, что еще хуже, просто даст неправильные результаты)