Как вставить в `MutableHashTable` на лету в граф вычислений? - PullRequest
0 голосов
/ 12 февраля 2019

Требования к модели

Я строю простую модель тензорного потока, которая должна сохранять / создавать карту INDEX ==> INDEX на лету, чтобы ее можно было обучать в режиме онлайн на наборе данных, который создается в реальном времени,т.е. набор данных не существует для предварительной сборки карты (в противном случае я бы).

Конечно, я могу построить карту вне графика вычисления тензорного потока (и преобразовать каждый идентификатор в INDEX до подачи входных данных модели), но мы действительно хотели бы, чтобы модель была автономной во время сохранения, чтобы упростить прогнозирование в будущем./ задачи вычислений.

Подход

Я пытаюсь использовать для этого значения tenorflow MutableHashTable, но продолжаю сталкиваться с "catchya's" от tenorflow.Я подтвердил, что могу вставлять новые элементы ключа / значения в хеш-таблицу с помощью

# defined in computation graph
id_to_idx = tf.contrib.lookup.MutableHashTable(tf.int32, tf.int32, MISSING_KEY_VALUE)

# .. with an open tf.Session

keys = [123, 234, 456, 567]
vals = [0,1,2,3]
sess.run(id_to_idx.insert(keys, vals))

sess.run(id_to_idx.lookup(keys))
# Returns [0,1,2,3]

. Мне бы хотелось, чтобы это было сделано на графике, чтобы идентифицировать новые ключи, назначать дополнительные значения, затем вставляется в хеш-таблицу для использования в остальной части модели.

Я хотел бы иметь что-то вроде этого,

# defined in computation graph
id_inputs = tf.placeholder(tf.int32, shape=(None,))
update_hashtable = id_to_idx.insert(new_keys, new_values)
indices = id_to_idx.lookup(id_inputs)

# .. with open tf.Session()

batch_of_somenew_and_someold_ids = [13,563,673,23]
sess.run([update_hashtable, indices], feed_dict={id_inputs: batch_of_somenew_and_someold_ids)
# Updates hash table values then returns them with next op

Минимальный пример

import tensorflow as tf

MISSING_KEY_VALUE = -1

id_inputs = tf.placeholder(tf.int32, shape=(None,))
id_to_idx = tf.contrib.lookup.MutableHashTable(tf.int32, tf.int32, MISSING_KEY_VALUE)
_next_idx = tf.Variable(0, dtype=tf.int32)

#
# Update Hash Table
#
_indices = id_to_idx.lookup(id_inputs) # initial lookup from hash
_not_seen_loc = tf.not_equal(_indices, MISSING_KEY_VALUE) # location in batch of IDs that haven't been seen
_ids_not_seen_yet = tf.where(_not_seen_loc, id_inputs, id_inputs) # list of the IDs that haven't been seen
_end_idx = _next_idx + tf.size(_not_seen_loc) 
_new_indices = tf.range(_next_idx, _end_idx) # new hash tables values for these keys

# Operation to update the idx iterator for next batch of inputs
update_iter = _next_idx.assign(_end_idx)

# *should* be an operation that makes the insert
update_hashtable = id_to_idx.insert(_ids_not_seen_yet, _new_indices)

# Operation to get mapped IDs for batch
indices = id_to_idx.lookup(id_inputs)

# .. Graph continues and does ML stuff

При выполнении этого примера

with tf.Session() as sess:
  sess.run(tf.global_variables_initializer())

  # some mock input data pulled off a dataset obj
  batch_ids = [34, 532, 5, 234, 6]

  _, iter_val, batch_indices = sess.run([update_hashtable, update_iter indices], feed_dict={id_inputs: batch_ids})

выдает ошибку

Fetch argument <function update_hashtable at 0x1384401e0> has invalid type <class 'function'>, must be a string or Tensor. (Can not convert a function into a Tensor or Operation.)

, которая кажется странной, поскольку id_to_idx.insert(keys,vals) должна возвращать операцию (как описано в документациии тестовый пример).

Я подтвердил, что итератор idx правильно увеличивается, печатая результат после каждой серии из 16,

[16,32,48,64,80,96,112,128,144,160,176]

Вопросы

  1. Не работает MutableHashTable внутри графа вычислений?В документах говорится, что входные данные могут быть тензорами.

  2. Печать типа update_hashtable, Почему это не возвращает операцию (как в случае поиска)?

print(type(update_hashtable))
print(type(indices))

# <class 'function'>
# <class 'tensorflow.python.framework.ops.Tensor'>
Я неправильно подхожу к этой проблеме?Есть ли известное / лучшее решение этой проблемы?
...