tf.one_hot() 是否支持 SparseTensor 作为索引参数?
Does tf.one_hot() supports SparseTensor as indices parameter?
请问tf.one_hot()函数是否支持SparseTensor作为"indices"参数。我想做一个多标签分类(每个例子都有多个标签),需要计算 cross_entropy 损失。
我尝试直接将 SparseTensor 放在 "indices" 参数中,但它引发了以下错误:
TypeError:无法将类型对象转换为 Tensor。内容:SparseTensor(indices=Tensor("read_batch_features/fifo_queue_Dequeue:106", shape=(?, 2), dtype=int64, device=/job:worker), values=Tensor("string_to_index_Lookup:0", shape=(?,) , dtype=int64, device=/job:worker), dense_shape=Tensor("read_batch_features/fifo_queue_Dequeue:108", shape=(2,), dtype=int64, device=/job:worker)).考虑将元素转换为受支持的类型。
对可能的原因有什么建议吗?
谢谢。
one_hot 不支持将 SparseTensor 作为 indices 参数。您可以将稀疏张量的 indices / values 张量作为 indices 参数传递,这可能会解决您的问题。
您可以从初始 SparseTensor 构建另一个形状 (batch_size, num_classes)
的 SparseTensor。例如,如果您将 classes 保留在单个字符串特征列中(以空格分隔),则可以使用以下内容:
import tensorflow as tf
all_classes = ["class1", "class2", "class3"]
classes_column = ["class1 class3", "class1 class2", "class2", "class3"]
table = tf.contrib.lookup.index_table_from_tensor(
mapping=tf.constant(all_classes)
)
classes = tf.constant(classes_column)
classes = tf.string_split(classes)
idx = table.lookup(classes) # SparseTensor of shape (4, 2), because each of the 4 rows has at most 2 classes
num_items = tf.cast(tf.shape(idx)[0], tf.int64) # num items in batch
num_entries = tf.shape(idx.indices)[0] # num nonzero entries
y = tf.SparseTensor(
indices=tf.stack([idx.indices[:, 0], idx.values], axis=1),
values=tf.ones(shape=(num_entries,), dtype=tf.int32),
dense_shape=(num_items, len(all_classes)),
)
y = tf.sparse_tensor_to_dense(y, validate_indices=False)
with tf.Session() as sess:
tf.tables_initializer().run()
print(sess.run(y))
# Outputs:
# [[1 0 1]
# [1 1 0]
# [0 1 0]
# [0 0 1]]
这里的 idx
是一个稀疏张量。其索引的第一列 idx.indices[:, 0]
包含批次的行号,其值 idx.values
包含相关 class id 的索引。我们将这两者结合起来创建新的 y.indices
.
有关多标签 class化的完整实施,请参阅
的 "Option 2"
请问tf.one_hot()函数是否支持SparseTensor作为"indices"参数。我想做一个多标签分类(每个例子都有多个标签),需要计算 cross_entropy 损失。
我尝试直接将 SparseTensor 放在 "indices" 参数中,但它引发了以下错误:
TypeError:无法将类型对象转换为 Tensor。内容:SparseTensor(indices=Tensor("read_batch_features/fifo_queue_Dequeue:106", shape=(?, 2), dtype=int64, device=/job:worker), values=Tensor("string_to_index_Lookup:0", shape=(?,) , dtype=int64, device=/job:worker), dense_shape=Tensor("read_batch_features/fifo_queue_Dequeue:108", shape=(2,), dtype=int64, device=/job:worker)).考虑将元素转换为受支持的类型。
对可能的原因有什么建议吗?
谢谢。
one_hot 不支持将 SparseTensor 作为 indices 参数。您可以将稀疏张量的 indices / values 张量作为 indices 参数传递,这可能会解决您的问题。
您可以从初始 SparseTensor 构建另一个形状 (batch_size, num_classes)
的 SparseTensor。例如,如果您将 classes 保留在单个字符串特征列中(以空格分隔),则可以使用以下内容:
import tensorflow as tf
all_classes = ["class1", "class2", "class3"]
classes_column = ["class1 class3", "class1 class2", "class2", "class3"]
table = tf.contrib.lookup.index_table_from_tensor(
mapping=tf.constant(all_classes)
)
classes = tf.constant(classes_column)
classes = tf.string_split(classes)
idx = table.lookup(classes) # SparseTensor of shape (4, 2), because each of the 4 rows has at most 2 classes
num_items = tf.cast(tf.shape(idx)[0], tf.int64) # num items in batch
num_entries = tf.shape(idx.indices)[0] # num nonzero entries
y = tf.SparseTensor(
indices=tf.stack([idx.indices[:, 0], idx.values], axis=1),
values=tf.ones(shape=(num_entries,), dtype=tf.int32),
dense_shape=(num_items, len(all_classes)),
)
y = tf.sparse_tensor_to_dense(y, validate_indices=False)
with tf.Session() as sess:
tf.tables_initializer().run()
print(sess.run(y))
# Outputs:
# [[1 0 1]
# [1 1 0]
# [0 1 0]
# [0 0 1]]
这里的 idx
是一个稀疏张量。其索引的第一列 idx.indices[:, 0]
包含批次的行号,其值 idx.values
包含相关 class id 的索引。我们将这两者结合起来创建新的 y.indices
.
有关多标签 class化的完整实施,请参阅
的 "Option 2"