Соберите субтензор дополненного тензора данных переменного размера в Tensorflow - PullRequest
0 голосов
/ 20 февраля 2019

У меня есть некоторые последовательные данные переменной длины с фиксированной размерностью тензора.Рассмотрим список тензоров s_1, ..., s_b списка некоторых фиксированных размерных матриц [l_1, m, n], ..., [l_b, m, n].Например,

s_1 = [ [[1,2],[3,4]], [[5,6],[7,8]] ]
s_2 = [ [[9,10],[11,12]], [[13,14],[15,16]], [[17,18],[19,20]] ]

Хотя данные приведены в дополненной форме, например:

S = [ [[[1,2],[3,4]], [[5,6],[7,8]], [[0,0],[0,0]]], 
    [[[9,10],[11,12]], [[13,14],[15,16]], [[17,18],[19,20]]] ]
l = [2,3]

, где S - тензор дополненных списков матриц, а l -1-D тензор с i -ой записью, заданной длиной последовательности i.

Теперь я хочу извлечь тензор, заданный путем конкатенации списка матриц.Результат должен быть

[ [[1,2],[3,4]], [[5,6],[7,8]], [[9,10],[11,12]], [[13,14],[15,16]], [[17,18],[19,20]] ]

Это вычисление будет выполнено в функции для map метода tf.data.Dataset.

Каков правильный подход для этого в тензорном потоке?Я думал об использовании tf.boolean_mask вместе с tf.sequence_mask, но не могу получить желаемый результат.Может быть, какое-то умное использование tf.gather_nd?

EDIT

tf.boolean_mask(S,tf.sequence_mask(l))

, кажется, дает правильный результат, но я могу заставить его работать только вне функциипередано методу map tf.data.Dataset.

def _parse_SE(in_example_proto):
    S = ...
    l = ... #obtain S and l from the record

    return tf.tuple([S,l])
dataset = tf.data.TFRecordDataset("test.txt")
dataset = dataset.map(_parse_SE)
dataset = dataset.padded_batch(BATCH_SIZE, padded_shapes=([], [None], [], [None,n,s]))
iterator = dataset.make_initializable_iterator()
[S_bat, l_bat] = iterator.get_next()
wanted_bat = tf.boolean_mask(S_bat,tf.sequence_mask(l_bat)) # when evaluated wanted_bat stores the wanted concatenation

работает.Но если я попытаюсь внести изменения в функцию отображения, я просто получу S снова:

def _parse_SE(in_example_proto):
    S = ...
    l = ... #obtain S and l from the record
    wanted = tf.boolean_mask(S,tf.sequence_mask(l))

    return tf.tuple([wanted,l])
dataset = tf.data.TFRecordDataset("test.txt")
dataset = dataset.map(_parse_SE)
dataset = dataset.padded_batch(BATCH_SIZE, padded_shapes=([], [None], [], [None,n,s]))
iterator = dataset.make_initializable_iterator()
[wanted_bat, l_bat] = iterator.get_next() # when evaluated wanted_bat just contains S_bat of the previous example

РЕДАКТИРОВАТЬ 2

Второй подход не будетработать как функция _parse_SE, переданная map, будет применена к каждому элементу пакета в данный момент, а не к целому пакету.Таким образом, мы не можем реорганизовать партию внутри _parse_SE.

...