下面是小的Tensorflow代码
# coding: utf-8
# In[27]:
import tensorflow as tf
# In[28]:
# Model parameters
W = tf.Variable([.3], dtype=tf.float32)
b = tf.Variable([-.3], dtype=tf.float32)
# In[29]:
# Model input and output
x = tf.placeholder(tf.float32)
linear_model = W * x + b
# In[30]:
y = tf.placeholder(tf.float32)
# In[31]:
# loss
loss = tf.reduce_sum(tf.square(linear_model - y))
# optimizer
optimizer = tf.train.GradientDescentOptimizer(0.01)
train = optimizer.minimize(loss)
# In[32]:
# training data
x_train = [1, 2, 3, 4]
y_train = [0, -1, -2, -3]
# In[33]:
# training loop
init = tf.global_variables_initializer()
# In[34]:
with tf.Session() as sess:
sess.run(init)
for i in range(1000):
sess.run(train, {x: x_train, y: y_train})
# evaluate training accuracy
curr_W, curr_b, curr_loss = sess.run([W, b, loss], {x: x_train, y: y_train})
print("W: %s b: %s loss: %s"%(curr_W, curr_b, curr_loss))
# In[ ]:
在for循环中,我们有以下代码
with tf.Session() as sess:
sess.run(init)
for i in range(1000):
sess.run(train, {x: x_train, y: y_train})
# evaluate training accuracy
curr_W, curr_b, curr_loss = sess.run([W, b, loss], {x: x_train, y: y_train})
print("W: %s b: %s loss: %s"%(curr_W, curr_b, curr_loss))
我的问题是,当我们运行sess.run(train, {x: x_train, y: y_train})
时,loss
也得到了计算,那么为什么要检索如下所示的损耗值时为什么需要传递feed_dict呢?谁能帮我理解这一点?
curr_W, curr_b, curr_loss = sess.run([W, b, loss], {x: x_train, y: y_train})
答案 0 :(得分:1)
您在代码中定义了2个占位符:maxRecordsPerFile
和x
。 y
是一个容器,可以在每次执行程序时为其提供不同的值。
使用tf.placeholder
时,TensorFlow使用此容器(占位符)在内部定义其计算图。 tf.placeholder
运行此计算图,但该图本身没有意义,因为占位符容器为空-它们不包含任何内容。因此,无论何时在代码中使用占位符,都需要使用sess.run()
的{{1}}参数在图形中传递这些占位符的值。
占位符的优点是不会记住您为执行feed_dict
而在其中放置的值。也就是说,第二次调用sess.run()
将再次具有空的占位符,并且您将再次不得不通过sess.run()
将值放入它们中。这就是为什么每次调用sess.run()
时都必须为占位符发送值的原因。
一个有用的类比可能是将TensorFlow计算图视为一台物理机器-具有输入管道(feed_dict
和sess.run()
)和输出管道(x
)。机器消耗来自输入管道的数据(因此数据不会在多个调用之间保留),并且机器还会从输出管道吐出东西-如果您没有捕获输出,则会丢失它。机器(图形)没有在其中存储任何值或结果。它仅用于定义对数据应用不同操作的工作流。
诸如y
之类的操作是机器的控制杆,将其拉动会在机器内起作用。现在,要使机器执行任何工作,您必须在输入管道中放入一些东西。当您调用loss
时,机器用完了占位符中的数据,计算了损耗(它是通过train
输出管道发送的,您没有捕获到)并通过反向传播修改了其内部变量。现在,输入管道再次为空,并且sess.run(train)
的旧值也丢失了!因此,当您希望计算损失时,可以将数据放入输入管道中,并要求机器通过loss
管道输出损失。
您可能会想这样做:
loss
但不幸的是,TensorFlow给出了no guarantees的order,其中loss
在其中评估其操作。因此,在上面的代码行中,您将不知道返回的loss_value, _ = sess.run([loss, train], {x: x_train, y: y_train})
是在运行训练操作之前或之后的损失。唯一的方法是先运行训练操作,然后像在代码中一样对sess.run()
进行2次单独的调用来运行损失操作。
答案 1 :(得分:0)
使用loss
和y
对linear_model
进行评估。
请注意:
y
是一个占位符,并且linear_model
的计算需要占位符x
因此,一旦有了占位符,就必须使用feed_dict
传递数据。
顺便说一句,运行sess.run(train, {x: x_train, y: y_train})
会调用梯度下降用于优化损失函数。
运行curr_W, curr_b, curr_loss = sess.run([W, b, loss], {x: x_train, y: y_train})
时,用于打印出执行火车操作train
后已优化的损失的当前值。