【问题标题】:Tensorflow error concerning the shape of placeholders关于占位符形状的 TensorFlow 错误
【发布时间】:2018-01-06 19:49:02
【问题描述】:

我对 TensorFlow 很陌生,我试图理解占位符的概念。 假设我有一个形状为 100x4 的特征集。所以我有 100 行 4 个不同的特征。然后目标是 100x1 的形状。如果我想将两个矩阵都用作训练集。我要做的是:

X = tf.placeholder(tf.float64, shape=X_train.shape)
Y = tf.placeholder(tf.float64, shape=y_train.shape)

W = tf.Variable(tf.random_normal([4, 1]), name="weight",dtype=tf.float32)
b = tf.Variable(rng.randn(), name="bias",dtype=tf.float32)

pred = tf.add(tf.multiply(X, W), b)

cost = tf.reduce_sum(tf.pow(pred-Y, 2))/(2*n_samples)

optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(cost)

init = tf.global_variables_initializer()

with tf.Session() as sess:

    # Run the initializer
    sess.run(init)

    # Fit all training data
    for epoch in range(training_epochs):
        for (x, y) in zip(X_train, y_train):
            sess.run(optimizer, feed_dict={X: x, Y: y})
            ... # some plotting and printing of results

然后导致“ValueError:无法为具有形状'(..., ...)'的张量'Placeholder:0'提供形状(...,)的值”。更具体地说,成本函数中“sub”的维度不相等。

有人能解释一下如何进行吗?为什么? 提前致谢

【问题讨论】:

    标签: python tensorflow


    【解决方案1】:

    如果您想批量训练您的数据,您应该使用占位符。

    为什么?
    这在您拥有大型数据集时完成,例如,如果您想针对图像分类问题训练分类器,但无法将所有训练图像加载到内存中。相反,通过batch gradient descent 训练您的模型。通过这种技术,每次只加载一批图像,并且只在该批上执行反向传播。这需要更多的 epoch 才能收敛到最小值,但每个 epoch 的训练速度更快。

    怎么做?
    您首先定义两个占位符,一个用于训练示例X,一个用于它们的标签Y,在您的情况下分别具有(batch_size, 4)(batch_size, 1) 的形状。
    然后,当您想要训练您的模型时,您应该通过提要字典输入您的数据到占位符中:

    with tf.Session() as sess:
        sess.run(train_op, feed_dict={X:x_batch, Y:y_batch}) # train_op is the operation that minimizes your cost function
    

    其中x_batchy_batch 应该是来自X_trainY_train 数组的随机批次,但它们应该有batch_size 示例而不是100 示例(以便它们的尺寸与占位符的尺寸匹配)。

    为什么您不应该这样做?
    由于您有一个小型数据集,它已经加载到您的内存中,您可以使用常规梯度下降。

    怎么做?
    只需使用变量 (tf.Variable()) 而不是占位符。

    X = tf.Variable(X_train)
    Y = tf.Variable(Y_train)
    

    这将创建两个变量类型的张量,它们在初始化时将分别采用X_trainY_train 的形状和值。

    别忘了在你的会话中初始化它们:

    with tf.Session() as sess:
         sess.run(tf.global_variables_initializer()) # initialize variables
         sess.run(train_op) # no need for a feed_dict
    

    【讨论】:

    • 感谢您的澄清回复。但我仍然不明白为什么它不能与占位符一起使用,在这种情况下,batch_size 将等于 X_train.shape 的第一个参数?我添加了更多代码来对问题进行上下文化。
    • 好吧,自编辑以来,我认为您的问题不在于占位符 X 和 Y,而在于变量 W 和 b。您需要 pred 和 Y 具有相同的维度,以便在计算成本函数时减去它们。这意味着 X*W+b 需要具有 (100,1) 的形状。为了实现这一点,W 需要具有 (4,1) 的形状。您不需要更改变量 b。
    • 尝试:W = tf.Variable(rng.randn(4,1), name="weight",dtype=tf.float64) pred = tf.matmul(X,W) + b #保持其余行不变, tf.Session() as sess: ... sess.run(init) ... for epoch in range(training_epochs): ... sess.run(optimizer, feed_dict={X:X_train, Y:Y_train})
    • 确实,谢谢!用 matmul() 替换并在喂食过程中移除拉链就可以了!但是为什么不能使用 zip 呢?是因为尺寸应该完全相同吗?
    • 您使用 zip 的方式,每次您传递一个示例(您拥有的 100 个示例)作为模型的输入。如果你想这样做,你应该让你的 X 占位符的形状为 (4,) 和 y 的形状为 (1,)
    【解决方案2】:

    了解占位符的概念

    需要占位符来为您将来提供的真实数据保留一个位置:

    x = tf.placeholder(tf.float32, shape=X_train.shape)
    logits = nn(x)  # making some operations with x in order to calculate logits
    
    s = tf.Session()
    logits = s.run(logits, feed_dict={x: X_train})
    

    因为我们使用占位符来制作 logits,所以我们需要放置真实数据而不是占位符以便计算 logits

    "ValueError: 无法为形状为 '(..., ...)' 的张量“Placeholder:0”提供形状 (...,) 的值”

    看起来在feed_dict={x: X_train} 中,您的占位符x 排名第二,但X_train 排名第一。最好仔细检查您的数据。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-05
      • 2016-12-25
      相关资源
      最近更新 更多