【问题标题】:InvalidArgumentError: You must feed a value for placeholder tensor PlaceholderInvalidArgumentError:您必须为占位符张量 Placeholder 提供一个值
【发布时间】:2016-07-10 20:28:41
【问题描述】:

我已经开始学习 tensorflow,但很难理解占位符/变量问题。

我正在尝试编写一个矩阵乘法函数。它在使用 tf.constant 时有效,但我很难理解如何使用变量

这是我的代码

import tensorflow as tf
import numpy as np 


mat_1 = np.array([[0,1,1,0], [1,0,1,0], [1,0,0,1], [0,1,1,0]]).astype('int32')
mat_2 = np.array([[0,1,1,0], [1,0,1,0], [1,0,0,1], [0,1,1,0]]).astype('int32')


def my_matmult1(mat_1, mat_2):
    #define session
    x_sess = tf.Session()

    with x_sess:
        xmat_1 = tf.constant(mat_1)
        xmat_2 = tf.constant(mat_2)
        r1 = tf.matmul(xmat_1, xmat_2)
        qq1 = x_sess.run(r1)

    return qq1    

def my_matmult2(mat_1, mat_2):
    #define session
    x_sess1 = tf.Session()

    with x_sess1:
        #initialize placeholders
        xmat_1_plh = tf.placeholder(dtype=mat_1.dtype, shape=mat_1.shape)
        xmat_2_plh = tf.placeholder(dtype=mat_2.dtype, shape=mat_2.shape)  

        #create variables
        x_mat_1 = tf.Variable(xmat_1_plh, trainable = False)
        x_mat_2 = tf.Variable(xmat_2_plh, trainable = False)

        x_sess1.run(tf.initialize_all_variables())

        #
        r1 = tf.matmul(xmat_1, xmat_2)
        qq1 = x_sess1.run(r1, feed_dic={mat_1, mat_2})

    return qq1  

这按预期工作:

my_matmult1(mat_1, mat_1)

但是,以下失败:

my_matmult2(mat_1, mat_1)

出现以下错误

无效参数错误

您必须使用 dtype int32 和 shape [4,4] 为占位符张量“Placeholder”提供一个值

即使更改了最后一行

qq1 = x_sess1.run(r1, feed_dic={tf.convert_to_tensor(mat_1), tf.convert_to_tensor(mat_2)})

我做错了什么?

【问题讨论】:

  • feed_dict 不是您代码中的字典。它在接受的答案中。

标签: tensorflow


【解决方案1】:

如果您在创建占位符后删除 tf.Variable() 行(并相应地修改馈送变量的名称),您的代码应该可以工作。

占位符用于您要为模型提供数据的变量。变量用于模型的参数(如权重)。

因此,您正确地创建了两个占位符,但随后无缘无故地创建了其他变量,这可能会在 Tensorflow 图表中造成混乱。

函数如下所示:

import tensorflow as tf
import numpy as np

def my_matmult2(mat_1, mat_2):
    #define session
    x_sess1=tf.Session()

    with x_sess1:
        #initialize placeholders
        xmat_1_plh = tf.placeholder(dtype=mat_1.dtype, shape=mat_1.shape)
        xmat_2_plh = tf.placeholder(dtype=mat_2.dtype, shape=mat_2.shape)  

        r1 = tf.matmul(xmat_1_plh, xmat_2_plh)

        x_sess1.run(tf.initialize_all_variables())

        #

        qq1 = x_sess1.run(r1, feed_dict={xmat_1_plh: mat_1 , xmat_2_plh: mat_2})

    return qq1 

mat_1=np.ones((5,5))
mat_2=np.ones((5,5))

b=my_matmult2(mat_1,mat_2)
print b

【讨论】:

  • 感谢@jean。它确实有效。我的想法(考虑到我刚从 TF 开始,可能有点天真)实际上是用 TF 替换我在 numpy 中执行的一些矩阵运算。我希望获得 (1) 的速度 - 大型矩阵和 (2) 克服核心外。但正如我所说,我只是在学习
【解决方案2】:

为了有意义地回答这个问题,我必须回到 tensorflow 的工作原理

图表
Tensorflow 中的图表只是计算将采用的地图/路径。它不保存任何值,也不执行任何操作。

会话
另一方面,会话需要图形、数据和运行时来执行。 Graphs 和 Sessions 的这个概念让 TensorFolow 将流定义或模型与实际的计算运行时分开。

将运行时与流程图分开
这很可能是为了将图形定义与运行时配置和数据的实际执行分开。例如,运行时可以在集群上。因此集群中的每个执行运行时都需要具有相同的图定义。但是每个运行时在执行过程中可能在本地有一组不同的数据。因此,在集群中的分布式执行期间可以提供输入和输出数据是很重要的。

为什么是占位符而不是变量
占位符充当图表的输入/输出管道。如果您将图形可视化为多个节点 - 占位符是输入或输出节点。

真正的问题是为什么 TensorFlow 不对 I/O 节点使用普通变量?为什么还有另一种类型?

在训练过程中(程序在会话中执行时),需要确保使用实际值来训练模型。基本上,训练过程中的feed_dict 只接受实际值,例如一个 Numpy ndarry。这些实际值不能由 TensorFlow 变量提供,因为 TensorFlow 变量没有数据,除非使用 eval() 或 session.run()。然而,训练语句本身是 session.run() 函数的一部分 - 因此它不能在其中使用另一个 session.run() 来将张量变量解析为数据。此时, session.run() 已经必须绑定到特定的运行时配置和数据。

【讨论】:

    【解决方案3】:

    您没有正确输入字典。您需要将字典设置为占位符的名称。我还添加了一个名称,您也许可以使用“xmat_1_plh”作为名称,但我更喜欢添加自己的名称。我还认为您在 my_matmult2() 函数中有一些额外的行。 x_mat_1/2 我不认为添加太多,但可能不会受到伤害(也许通过向图中添加另一个 OP 来提高一点性能。

    def my_matmult2(mat_1, mat_2):
     #define session
     x_sess1 = tf.Session()
    
     with x_sess1:
        #initialize placeholders
        xmat_1_plh = tf.placeholder(dtype=mat_1.dtype, shape=mat_1.shape, name ="xmat1")
        xmat_2_plh = tf.placeholder(dtype=mat_2.dtype, shape=mat_2.shape, name ="xmat2")  
    
        #create variables
        x_mat_1 = tf.Variable(xmat_1_plh, trainable = False)
        x_mat_2 = tf.Variable(xmat_2_plh, trainable = False)
    
        x_sess1.run(tf.initialize_all_variables())
    
        #
        r1 = tf.matmul(xmat_1, xmat_2)
        qq1 = x_sess1.run(r1, feed_dic={xmat1: mat_1, xmat2: mat_2})
    
     return qq1  
    

    我不确定您对这个函数的最终目标是什么,但您正在图中创建节点。因此,您可能希望将“.run()”语句移出此函数(到您希望主动将 2 矩阵相乘的位置),因为如果您只是在寻找,则不应在循环中调用它一种将 2 矩阵相乘的方法。

    如果这是对 my_matmult2() 的单个测试/调用,那么您应该使用对字典的更正。

    【讨论】:

    • 谢谢,但恐怕还是不行。该功能不适用于生产。只是对占位符/变量/常量有点困惑并尝试学习
    猜你喜欢
    • 2019-01-23
    • 1970-01-01
    • 1970-01-01
    • 2017-05-27
    • 1970-01-01
    • 1970-01-01
    • 2018-02-26
    • 1970-01-01
    相关资源
    最近更新 更多