【问题标题】:Tensorflow hashtable lookup with arrays使用数组查找 TensorFlow 哈希表
【发布时间】:2018-10-23 06:21:01
【问题描述】:

我正在尝试让 HashMap 类型的功能与 tensorflow 一起使用。当键和值是 int 类型时,我让它工作。但是当它们是数组时,它会给出错误 - ValueError: Shapes (2,) and () are not compatible 在线 default_value)

import numpy as np
import tensorflow as tf


input_tensor = tf.constant([1, 1], dtype=tf.int64)
keys = tf.constant(np.array([[1, 1],[2, 2],[3, 3]]),  dtype=tf.int64)
values = tf.constant(np.array([[4, 1],[5, 1],[6, 1]]),  dtype=tf.int64)
default_value = tf.constant(np.array([1, 1]),  dtype=tf.int64)

table = tf.contrib.lookup.HashTable(
        tf.contrib.lookup.KeyValueTensorInitializer(keys, values),
        default_value)

out = table.lookup(input_tensor)
with tf.Session() as sess:
    table.init.run()
    print(out.eval())

【问题讨论】:

  • default_value 应该是一个标量值,而不是一个数组。
  • 但我的值是数组。这有什么意义?它也给出了错误:ValueError: Shape must be rank 1 but is rank 2 for 'key_value_init_4' (op: 'InitializeTable') with input shapes: [2], [3,2], [3,2].
  • 我投票只是因为@MihkelL。居然发了MCVE,真爽! :)

标签: python numpy tensorflow


【解决方案1】:

不幸的是,tf.contrib.lookup.HashTable 仅适用于一维张量。这是一个使用tf.SparseTensors 的实现,当然只有当您的键是整数(int32 或 int64)张量时才有效。

对于值,我将两列存储在两个单独的张量中,但如果您有很多列,您可能只想将它们存储在一个大张量中,并将索引作为值存储在一个 tf.SparseTensor 中。

此代码(已测试):

import tensorflow as tf

lookup = tf.placeholder( shape = ( 2, ), dtype = tf.int64 )
default_value = tf.constant( [ 1, 1 ], dtype = tf.int64 )
input_tensor = tf.constant( [ 1, 1 ], dtype=tf.int64)
keys = tf.constant( [ [ 1, 2 ], [ 3, 4 ], [ 5, 6 ] ],  dtype=tf.int64 )
values = tf.constant( [ [ 4, 1 ], [ 5, 1 ], [ 6, 1 ] ],  dtype=tf.int64 )
val0 = values[ :, 0 ]
val1 = values[ :, 1 ]

st0 = tf.SparseTensor( keys, val0, dense_shape = ( 7, 7 ) )
st1 = tf.SparseTensor( keys, val1, dense_shape = ( 7, 7 ) )

x0 = tf.sparse_slice( st0, lookup, [ 1, 1 ] )
y0 = tf.reshape( tf.sparse_tensor_to_dense( x0, default_value = default_value[ 0 ] ), () )
x1 = tf.sparse_slice( st1, lookup, [ 1, 1 ] )
y1 = tf.reshape( tf.sparse_tensor_to_dense( x1, default_value = default_value[ 1 ] ), () )

y = tf.stack( [ y0, y1 ], axis = 0 )

with tf.Session() as sess:
    print( sess.run( y, feed_dict = { lookup : [ 1, 2 ] } ) )
    print( sess.run( y, feed_dict = { lookup : [ 1, 1 ] } ) )

将输出:

[4 1]
[1 1]

根据需要(查找键 [ 1, 2 ] 的值 [ 4, 1 ] > 和 [ 1, 1 ] 的默认值 [ 1, 1 ],它指向一个非- 存在条目。)

【讨论】:

  • 是的,但由于哈希表中不存在密钥,因此它应该返回default_value。所以这不是一个可行的解决方案。这种重塑对许多例子都不起作用。如果您考虑一下,它不会像哈希图那样使逻辑正常工作。例如,如果您将键列表更改为 [[1, 2],[1, 1],[5, 6]] 它应该可以工作 - 在正常的哈希表实现中 - 但它会在您的解决方案中引发错误。 :)
  • 哦,你是对的,显然没有考虑到这一点。让我想想我能不能想出别的办法。我们是否知道索引张量的内容,例如,它们是整数还是有最大值?这会很有帮助。
  • tf.SparseTensors 重写了答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-10-01
  • 1970-01-01
  • 2018-06-14
  • 1970-01-01
  • 2017-04-13
  • 2016-04-03
  • 1970-01-01
相关资源
最近更新 更多