为什么我们需要使用feed_ict传递值来打印TensorFlow中的损失值



下面是小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})

您在代码中定义了两个占位符:xytf.placeholder是一个容器,它可以在每次执行程序时被馈送不同的值。

使用tf.placeholder时,TensorFlow会使用此容器(占位符(在内部定义其计算图。sess.run()运行这个计算图,但图本身没有意义,因为占位符容器是空的——它们不包含任何内容。因此,无论何时在代码中使用占位符,都需要使用sess.run()feed_dict参数在图中传递这些占位符的值。

占位符的优点是您为sess.run()的一次执行而放入的值不会被记住。也就是说,sess.run()的第二个调用将再次具有空占位符,并且您将不得不再次通过feed_dict将值放入其中。这就是为什么您必须在每次调用sess.run()时发送占位符的值。

一个有用的类比可能是将TensorFlow计算图视为一台物理机器——具有输入管道(xy(和输出管道(loss(。机器消耗输入管道中的数据(因此数据不会在多个调用中保留(,机器也会从输出管道中吐出东西——如果你没有捕捉到输出,就会丢失它。机器(图(不会在其中存储任何值或结果。它只用于定义一个对数据应用不同操作的工作流。

train这样的操作是机器的杠杆,当被拉动时,它在机器内做一些事情。现在,为了让机器完成任何工作,必须在输入管道中放入一些东西。当您调用sess.run(train)时,机器会用完占位符中的数据,计算损失(它通过loss输出管道发送,但您没有捕获(,并通过反向传播修改其内部变量。现在输入管道再次为空,loss的旧值丢失!因此,当您希望计算损失时,您将数据输入到输入管道中,并要求机器通过loss管道输出损失。

你可能会想这样做:

loss_value, _ = sess.run([loss, train], {x: x_train, y: y_train})

但是不幸的是,TensorFlow不能保证sess.run()评估其操作的顺序。因此,在上面的代码行中,您将不知道返回的loss_value是在运行训练操作之前还是之后的损失。唯一的方法是首先运行training操作,然后像在代码中所做的那样,在对sess.run()的两个单独调用中运行loss操作。

使用ylinear_model评估loss
注意:

  • y是占位符,并且
  • CCD_ 29的计算需要占位符CCD_

因此,一旦有了占位符,就必须使用feed_dict传递数据。

顺便说一下,运行sess.run(train, {x: x_train, y: y_train})会调用Gradient descension来优化损失函数。

运行CCD_ 33是为了打印出在执行列车运行train之后已经优化的损耗的当前值。

最新更新