TensorFlow Dataset API: использование массивов NumPy с добавлением пакетной обработки

Быстрый отказ от ответственности: я впервые активно задаю здесь вопрос о переполнении стека.

Теперь перейдем к самому вопросу. У меня возникают некоторые проблемы с использованием довольно нового API набора данных tenorflow 1.4 вместе с чтением входных данных переменной длины из массивов numpy и пакетной обработки с дополнениями.

Согласно официальной документации (https://www.tensorflow.org/programmers_guide/datasets#consuming_numpy_arrays) с использованием массивов в качестве входных данных поддерживается и просто. Суть теперь в том, что данные должны быть переданы в заполнители тензорного потока, прежде чем к данным можно будет применить метод padded_batch объекта набора данных. Однако представление numpy входов переменной длины не является симметричным и поэтому интерпретируется как последовательность, а не как массив. Но не вся причина предоставления метода padded_batch в том, что последовательность входных данных переменной длины может обрабатываться набором данных. Короче говоря, кто-нибудь из вас, ребята, сталкивался с подобной ситуацией и нашел для нее решение? Спасибо большое за вашу помощь!

Ниже приведены некоторые фрагменты кода, которые могут помочь лучше понять проблему.

Как выглядит ввод:

array([array([65,  3, 96, 94], dtype=int32), array([88], dtype=int32),
       array([113,  52, 106,  57,   3,  86], dtype=int32),
       array([88,  3, 23, 91], dtype=int32), ... ])

The actual code snippet where the dataset is defined in populated:


for fold, (train_idx, dev_idx) in enumerate(sss.split(X, y)):

    X_train = X[train_idx]
    y_train = y[train_idx]

    X_dev = X[dev_idx]
    y_dev = y[dev_idx]

    tf.reset_default_graph()
    with tf.Session() as sess:

       features_placeholder = tf.placeholder(tf.int32, [None, None], name='input_x')
       labels_placeholder = tf.placeholder(tf.int32, [None, num_classes], name='input_y')

       dataset = tf.data.Dataset.from_tensor_slices((features_placeholder, labels_placeholder))

       dataset = dataset.shuffle(buffer_size=len(train_idx))
       dataset = dataset.padded_batch(batch_size, padded_shapes=([None], [None]), padding_values=(1, 0))

       iterator = dataset.make_initializable_iterator()
       next_element = iterator.get_next()

       sess.run(iterator.initializer, feed_dict={features_placeholder: np.array(X_train),
                                                 labels_placeholder: np.array(y_train)})

И, наконец, соответствующая трассировка стека из записной книжки jupyter:


ValueError                                Traceback (most recent call last)
 in ()
----> 1 cnn.train2(X_idx, y_bin, n_splits=5)

in train2(self, X, y, n_splits) 480 481 self.session.run(iterator.initializer, feed_dict={features_placeholder: np.array(X_train), --> 482 labels_placeholder: np.array(y_train)}) 483 # self.session.run(iterator.initializer) 484

~/.virtualenvs/ravenclaw/lib/python3.6/site-packages/tensorflow/python/client/session.py in run(self, fetches, feed_dict, options, run_metadata) 887 try: 888 result = self._run(None, fetches, feed_dict, options_ptr, --> 889 run_metadata_ptr) 890 if run_metadata: 891 proto_data = tf_session.TF_GetBuffer(run_metadata_ptr)

~/.virtualenvs/ravenclaw/lib/python3.6/site-packages/tensorflow/python/client/session.py in _run(self, handle, fetches, feed_dict, options, run_metadata) 1087 feed_handles[subfeed_t] = subfeed_val 1088 else: -> 1089 np_val = np.asarray(subfeed_val, dtype=subfeed_dtype) 1090 1091 if (not is_tensor_handle_feed and

~/.virtualenvs/ravenclaw/lib/python3.6/site-packages/numpy/core/numeric.py in asarray(a, dtype, order) 490 491 """ --> 492 return array(a, dtype, copy=False, order=order) 493 494

ValueError: setting an array element with a sequence.

Еще раз спасибо за вашу поддержку.


person bash    schedule 18.01.2018    source источник


Ответы (1)


У меня была такая же проблема, пока я не наткнулся на эту ссылку здесь из ветки проблемы с тензорным потоком. По-видимому, обходной путь для работы с входами различной длины - использовать Dataset.from_generator, как указано в ссылке. Рассматриваемый API находится здесь. Поскольку у меня также есть вектор ввода и меток, я использую функцию zip для итерации как ввода, так и меток:

zipped = list(zip(x_train,y_train))
dataset = tf.data.Dataset.from_generator(lambda: zipped, (tf.int32, tf.int32))
dataset = dataset.padded_batch(batch_size, padded_shapes=([None], [None]), padding_values=(1, 0))
iterator = dataset.make_one_shot_iterator()
next_element = iterator.get_next()
person tomgun    schedule 26.01.2018
comment
Привет, Томган. Большое спасибо за намек на эту проблему с TensorFlow и за предоставленный фрагмент кода. Это выглядит многообещающе и, вероятно, именно то, что я искал. Из-за смены приоритетов на работе я, возможно, не смогу попробовать это раньше, чем на следующей неделе. Однако я сделаю это, как только у меня будет возможность, и отмечу ваш ответ как правильный, если все сработает так, как ожидалось. Еще раз благодарим за помощь и терпение! - person bash; 29.01.2018