为什么我们需要使用feed_dict传递值以在TensorFlow中打印损失值

时间:2018-07-18 17:16:09

标签: tensorflow machine-learning deep-learning

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

2 个答案:

答案 0 :(得分:1)

您在代码中定义了2个占位符:maxRecordsPerFilexy是一个容器,可以在每次执行程序时为其提供不同的值。

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

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

一个有用的类比可能是将TensorFlow计算图视为一台物理机器-具有输入管道(feed_dictsess.run())和输出管道(x)。机器消耗来自输入管道的数据(因此数据不会在多个调用之间保留),并且机器还会从输出管道吐出东西-如果您没有捕获输出,则会丢失它。机器(图形)没有在其中存储任何值或结果。它仅用于定义对数据应用不同操作的工作流。

诸如y之类的操作是机器的控制杆,将其拉动在机器内起作用。现在,要使机器执行任何工作,您必须在输入管道中放入一些东西。当您调用loss时,机器用完了占位符中的数据,计算了损耗(它是通过train输出管道发送的,您没有捕获到)并通过反向传播修改了其内部变量。现在,输入管道再次为空,并且sess.run(train)的旧值也丢失了!因此,当您希望计算损失时,可以将数据放入输入管道中,并要求机器通过loss管道输出损失。

您可能会想这样做:

loss

但不幸的是,TensorFlow给出了no guaranteesorder,其中loss在其中评估其操作。因此,在上面的代码行中,您将不知道返回的loss_value, _ = sess.run([loss, train], {x: x_train, y: y_train}) 是在运行训练操作之前或之后的损失。唯一的方法是先运行训练操作,然后像在代码中一样对sess.run()进行2次单独的调用来运行损失操作。

答案 1 :(得分:0)

使用lossylinear_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后已优化的损失的当前值。