python - 使用 tensorflow 从头开始的简单 MLP
问题描述
我正在尝试从头开始在 tensorflow 中实现 MLP,并在 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
虽然当我尝试从 label_batch 打印前 10 个样本时:
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)
我在这里想念什么?
解决方案
您误解了错误消息(Python 在这方面可能会产生误导,我们都曾多次陷入此类错误,而不是我们想承认的......)。即使它label_tensor : label_batch
在您的错误中显示该行,它实际上是在谈论整个session.run()
调用。
原因是,您看到此错误是因为您希望调用返回一个元组,但您只提供了一个由 TensorFlow 计算的张量。
sess.run(training_step, feed_dict=...)
将返回None
,因为操作training_step
不应该返回任何内容,调用它您只需执行一个优化步骤。
要获得所需的结果,请将代码更改为:
_ , loss_result = sess.run([training_step, loss],
feed_dict={
image_tensor : image_batch,
label_tensor : label_batch
})
这样 TensorFlow 将评估这两个操作,第一个将返回 None (正如你已经得到的那样),第二个将计算给定批次的损失函数的值。
(请注意,您必须重命名左侧的损失变量,因为如果不这样做,您将替换损失操作,下一次调用可能会引发异常或更糟,只会给出错误的结果)
推荐阅读
- actions-on-google - 设备的预期 Google Home 查询请求频率是多少?
- html - 是否可以有 HTML 标签显示更多由空格分隔的字符串的第一部分?
- asp.net-core - 教程 ASP.NET Core 标识:无法生成创建数据库
- java - 从其他类访问经过身份验证的用户(没有 SecurityContextHolder)
- java - 如何在二维数组中找到最常见的元素?除了二维数组,你不能使用任何东西
- c++ - C++ 如何知道子类调用父方法?
- django - 如何实现表单序列
- javascript - 显示不存在的城市的错误消息?
- python - 如何使用 google API for python 在特定文件夹下创建工作表?
- sql - 如何摆脱光标并使用 UPDATE 和 SELECT