下面是小的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个占位符:xytf.placeholder是一个容器,可以在每次执行程序时为其提供不同的值。

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

占位符的优点是不会记住您为执行一次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给出了no guarantees关于sess.run()评估其操作的order的信息。因此,在上面的代码行中,您将不知道返回的loss_value是在运行训练操作之前还是之后的损失。唯一的方法是先运行训练操作,然后像在代码中一样,在对sess.run()的两个单独调用中运行损失操作。

关于tensorflow - 为什么我们需要使用feed_dict传递值以在TensorFlow中打印损失值,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/51407644/

10-12 21:25