tf.lookup.StaticHashTable со списками (произвольных размеров) в качестве значений

#python #tensorflow #dictionary #hashtable #lookup

#python #тензорный поток #словарь #хэш-таблица #поиск

Вопрос:

Я хочу связать с именем каждого человека список чисел.

 keys = ["Fritz", "Franz", "Fred"]
values = [[1, 2, 3], [4, 5], [6, 7, 8, 9]]
  

Если я выполню следующее:

 import tensorflow as tf
table = tf.lookup.StaticHashTable(tf.lookup.KeyValueTensorInitializer(keys, values), default_value=0)
  

я получаю a, ValueError: Can't convert non-rectangular Python sequence to Tensor.
поскольку списки имеют разный размер и, следовательно, не могут быть преобразованы в a tf.Tensor .

Есть ли другой способ связать значения тензора со списками произвольной формы?

Спасибо за вашу помощь 🙂

Ответ №1:

StaticHashTable — начиная с TF 2.3 — не может возвращать многомерные значения, не говоря уже о неровных. Итак, несмотря на заполнение значений, создание хэш-таблицы, подобной этой:

 keys = ["Fritz", "Franz", "Fred"]
values = [[1, 2, 3, -1], [4, 5, -1, -1], [6, 7, 8, 9]]
table_init = tf.lookup.KeyValueTensorInitializer(keys, values)
table = tf.lookup.StaticHashTable(table_init, -1)
  

выдаст следующую ошибку:

 InvalidArgumentError: Expected shape [3] for value, got [3,4] [Op:LookupTableImportV2]
  

Чтобы обойти это, вы можете использовать плотные хэш-таблицы, хотя они находятся в экспериментальном режиме. Ни плотные, ни статические хэш-таблицы не обеспечивают поддержку неровных ключей или значений. Поэтому лучше всего дополнить ваши значения и создать плотную хэш-таблицу. Во время поиска вы можете удалить их обратно. Общий код выглядит следующим образом:

 keys = ["Fritz", "Franz", "Fred"]
values = [[1, 2, 3, -1], [4, 5, -1, -1], [6, 7, 8, 9]]
table = tf.lookup.experimental.DenseHashTable(key_dtype=tf.string, value_dtype=tf.int64, empty_key="<EMPTY_SENTINEL>", deleted_key="<DELETE_SENTINEL>", default_value=[-1, -1, -1, -1])
table.insert(keys, values)
  

И во время поиска:

 >>> tf.RaggedTensor.from_tensor(table.lookup(['Franz', 'Emil']), padding=-1)
<tf.RaggedTensor [[4, 5], []]>