Подтвердить что ты не робот

Проблема с подачей списка в feed_dict в TensorFlow

Я пытаюсь передать список в feed_dict, однако у меня возникают проблемы с этим. Скажем, у меня есть:

inputs = 10 * [tf.placeholder(tf.float32, shape=(batch_size, input_size))]

где входы подаются в некоторую функцию outputs, которую я хочу вычислить. Поэтому, чтобы запустить это в тензорном потоке, я создал сеанс и выполнил следующее:

sess.run(outputs, feed_dict = {inputs: data}) 
#data is my list of inputs, which is also of length 10

но я получаю сообщение об ошибке, TypeError: unhashable type: 'list'. Тем не менее, я могу передать элемент данных таким образом:

sess.run(outputs, feed_dict = {inputs[0]: data[0], ..., inputs[9]: data[9]}) 

Итак, мне интересно, есть ли способ решить эту проблему. Я также попытался построить словарь (используя цикл for), однако это приводит к созданию словаря с одним элементом, где они имеют следующий ключ: tensorflow.python.framework.ops.Tensor at 0x107594a10

4b9b3361

Ответ 1

Здесь есть две проблемы:

Первая проблема заключается в том, что вызов Session.run() принимает только небольшое количество типов в качестве ключей feed_dict. В частности, списки тензоров не поддерживаются как ключи, поэтому вам нужно поместить каждый тензор в отдельный ключ. * Один из удобных способов сделать это - использование словаря

inputs = [tf.placeholder(...), ...]
data = [np.array(...), ...]
sess.run(y, feed_dict={i: d for i, d in zip(inputs, data)})

Вторая проблема заключается в том, что синтаксис 10 * [tf.placeholder(...)] в Python создает список из десяти элементов, где каждый элемент тот же тензорный объект (т.е. имеет то же свойство name, тот же id, и является ссылочным, если вы сравниваете два элемента из списка, используя inputs[i] is inputs[j]). Это объясняет, почему, когда вы пытались создать словарь, используя элементы списка в качестве ключей, вы получили словарь с одним элементом - потому что все элементы списка были идентичны.

Чтобы создать 10 различных тензодатчиков-заполнителей, как вы планировали, вы должны сделать следующее:

inputs = [tf.placeholder(tf.float32, shape=(batch_size, input_size))
          for _ in xrange(10)]

Если вы напечатаете элементы этого списка, вы увидите, что каждый элемент представляет собой тензор с другим именем.


РЕДАКТИРОВАТЬ: * Теперь вы можете передать кортежи в качестве ключей feed_dict, потому что они могут использоваться как словарные ключи.

Ответ 2

Вот правильный пример:

batch_size, input_size, n = 2, 3, 2
# in your case n = 10
x = tf.placeholder(tf.types.float32, shape=(n, batch_size, input_size))
y = tf.add(x, x)

data = np.random.rand(n, batch_size, input_size)

sess = tf.Session()
print sess.run(y, feed_dict={x: data})

И вот странные вещи, которые я вижу в вашем подходе. По какой-то причине вы используете 10 * [tf.placeholder(...)], который создает 10 тензоров размера (batch_size, input_size). Не знаю, зачем вы это делаете, если вы можете просто создать на тензоре 3-го ранга (где первое измерение равно 10).

Поскольку у вас есть список тензоров (а не тензор), вы не можете подавать свои данные в этот список (но в моем случае я могу подавать свой тензор).

Ответ 3

feed_dict может быть предоставлен путем предварительной подготовки словаря следующим образом

n = 10
input_1 = [tf.placeholder(...) for _ in range(n)]
input_2 = tf.placeholder(...)
data_1 = [np.array(...) for _ in range(n)]
data_2 = np.array(...)


feed_dictionary = {}
for i in range(n):
    feed_dictionary[input_1[i]] = data_1[i]
feed_dictionary[input_2] = data_2
sess.run(y, feed_dict=feed_dictionary)