【问题标题】:Tensorflow placeholder for one-hot encoded labels用于单热编码标签的 TensorFlow 占位符
【发布时间】:2018-04-22 03:49:12
【问题描述】:

我有 one-hot 编码标签(从 0 到 10 的 11 个类别):

# one-hot encode labels
from sklearn.preprocessing import OneHotEncoder

labels = df.rating.values.reshape([-1, 1])
encoder = OneHotEncoder(sparse=False)
encoder.fit(labels)
labels = encoder.transform(labels)

并且有以下占位符:

# create the graph object
graph = tf.Graph()
# add nodes to the graph
with graph.as_default():
    inputs_ = tf.placeholder(tf.int32, [None, None], name='inputs')
    labels_ = tf.placeholder(tf.int32, [None, 1], name='labels')
    keep_prob = tf.placeholder(tf.float32, name='keep_prob')

我正在使用sparse_softmax_cross_entropy

with graph.as_default():
    logits = tf.layers.dense(inputs=outputs[:, -1], units=1)
    loss = tf.losses.sparse_softmax_cross_entropy(labels=labels_, logits=logits)        
    optimizer = tf.train.AdamOptimizer(learning_rate).minimize(loss)

TF 抛出:ValueError: Cannot feed value of shape (500, 1, 11) for Tensor 'labels:0', which has shape '(?, 1)'

我已经尝试了所有方法,但无法正常工作。 one-hot 编码数据的正确占位符是什么?

【问题讨论】:

    标签: python tensorflow


    【解决方案1】:

    第二个维度应该是你有多少类。 One-hot 编码意味着如果你有 10 个类,并且你对 5 类进行编码,那将产生一个长度为 10 的向量 [ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 ] .所以代码应该是:

    labels_ = tf.placeholder(tf.int32, [None, ***number of classes***], name='labels')
    

    再一次,tf.losses.sparse_softmax_cross_entropy() 采用 类标签,而不是 one-hot 编码。所以要么你用tf.argmax()对其进行解码,然后再将其提供给tf.losses.sparse_softmax_cross_entropy(),如下所示:

    loss = tf.losses.sparse_softmax_cross_entropy(
        labels = tf.argmax( labels_, axis = 1 ), logits = logits )
    

    或者真正的问题是,为什么你首先要使用 ont-hot 编码?您可以将df.rating.values.reshape([-1, 1]) 作为labels_ 提供给您的图表,并将 1 保留在第二维中。不需要整个 one-hot 编码块。

    您的代码中还有一些其他问题(原始问题中未显示)会影响此问题。首先,您像这样向网络提供数据:

        feed = {inputs_: x,
                labels_: y[:, None],
                keep_prob: 1,
                initial_state: test_state}
    

    为了尝试解决labels_ 问题,您添加了索引[:, None]。问题在于,在 Numpy 中,索引None 具有特殊含义:它将插入一个新维度。这就是( 500, 1, 1 ) 中额外维度的来源。在这里索引y 是不必要的,我已经删除了它。所以代码应该是:

        feed = {inputs_: x,
                labels_: y,
                keep_prob: 1,
                initial_state: test_state}
    

    然后出现了另一个问题,一个非常常见的错误,在这一行:

    loss, state, _ = sess.run([loss, final_state, optimizer], feed_dict=feed)
    

    您将loss 的值分配给loss,因此loss 现在是一个数字,而不是张量 em> 应该是。所以在第二次迭代中,代码失败了。我把它改成了

    loss_val, state, _ = sess.run([loss, final_state, optimizer], feed_dict=feed)
    

    当然,您还需要将该更改传播到 print()

    print("Epoch: {}/{}".format(e, epochs),
          "Iteration: {}".format(iteration),
          "Train loss: {:.3f}".format(loss_val))
    

    此外,在您定义 logits 的地方,您必须有 11 个单位,因为您有 11 个类别 ( 0 - 10 ),并且每个类别都需要一个概率:

    logits = tf.layers.dense(inputs=outputs[:, -1], units=11 )
    

    通过这些变化,训练运行,甚至似乎学到了一些东西:

    ('Epoch: 0/10', 'Iteration: 5', 'Train loss: 1.735')
    ('Epoch: 0/10', 'Iteration: 10', 'Train loss: 2.092')
    ('Epoch: 0/10', 'Iteration: 15', 'Train loss: 2.644')
    ('Epoch: 0/10', 'Iteration: 20', 'Train loss: 1.596')
    ('Epoch: 0/10', 'Iteration: 25', 'Train loss: 1.759')
    验证值:0.012
    ('Epoch: 0/10', 'Iteration: 30', 'Train loss: 1.581')
    ('Epoch: 0/10', 'Iteration: 35', 'Train loss: 2.213')
    ('Epoch: 0/10', 'Iteration: 40', 'Train loss: 2.176')
    ('Epoch: 0/10', 'Iteration: 45', 'Train loss: 1.849')
    ('Epoch: 0/10', 'Iteration: 50', 'Train loss: 2.474')
    Val acc: 0.017

    【讨论】:

    • 我之前尝试过,但它在loss = tf.losses.sparse_softmax_cross_entropy(labels=labels_, logits=logits) 处抛出Can not squeeze dim[1], expected a dimension of 1, got 11 for 'sparse_softmax_cross_entropy_loss/remove_squeezable_dimensions/Squeeze' (op: 'Squeeze') with input shapes: [?,11].
    • 更新答案。
    • 我也试过了(不使用一种热编码)......但它会抛出 Cannot feed value of shape (500, 1, 1) for Tensor 'labels:0', which has shape '(?, 1)' 如果我改为使用 softmax_cross_entropy 和 one-hot,则会抛出 Received a label value of 10 which is outside the valid range of [0, 1).跨度>
    • 如果我将占位符设为None, 1, 1,则抛出Rank mismatch: Rank of labels (received 3) should equal rank of logits minus 1 (received 2).
    • 您必须将标签作为形状(None, 1)。你如何获得额外的维度?每张图片都有一个标签。
    猜你喜欢
    • 1970-01-01
    • 2017-10-12
    • 2018-10-01
    • 1970-01-01
    • 2020-04-02
    • 2016-10-15
    • 2012-02-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多