使用 tensorflow 从头开始简单的 MLP
simple MLP from scratch using tensorflow
我正在尝试从头开始在 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()
调用。
您看到此错误的原因是因为您希望通过调用 return 编辑一个元组,但您只提供了一个由 TensorFlow 计算的张量。
sess.run(training_step, feed_dict=...)
将 return None
因为操作 training_step
不应该 return 任何东西,调用它你只需执行一个优化步骤。
要获得所需的结果,请将代码更改为:
_ , loss_result = sess.run([training_step, loss],
feed_dict={
image_tensor : image_batch,
label_tensor : label_batch
})
这样 TensorFlow 将评估这 2 个操作,第一个是 return None(正如您已经得到的那样),第二个将计算给定批次的损失函数的值。
(请注意,您必须重命名左侧的损失变量,因为如果不这样做,您将替换损失操作,而下一次调用可能会引发异常或更糟,只会给出错误的结果)
我正在尝试从头开始在 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()
调用。
您看到此错误的原因是因为您希望通过调用 return 编辑一个元组,但您只提供了一个由 TensorFlow 计算的张量。
sess.run(training_step, feed_dict=...)
将 return None
因为操作 training_step
不应该 return 任何东西,调用它你只需执行一个优化步骤。
要获得所需的结果,请将代码更改为:
_ , loss_result = sess.run([training_step, loss],
feed_dict={
image_tensor : image_batch,
label_tensor : label_batch
})
这样 TensorFlow 将评估这 2 个操作,第一个是 return None(正如您已经得到的那样),第二个将计算给定批次的损失函数的值。
(请注意,您必须重命名左侧的损失变量,因为如果不这样做,您将替换损失操作,而下一次调用可能会引发异常或更糟,只会给出错误的结果)