Как создать логическую маску в тензорном потоке со средним диапазоном, установленным только на True, с использованием индексации, указанной в другом тензоре - PullRequest
0 голосов
/ 10 июля 2020

У меня есть тензор формы [None, 1], состоящий из значения для каждой партии. Используя этот тензор, я должен создать логическую маску со значениями, установленными в true, начиная с значения индекса (из тензора) соответствующей партии до фиксированной длины, и все остальные, установленные на false.

Пример, рассмотрим тензор индекса должен быть

[[1],[2],[2]]

Предположим, что желаемая длина временных шагов для каждого пакета равна 5, а фиксированная длина равна 2, а затем для первого пакета в индексах, начиная с 1 и заканчивая 2 (как fixed length = 2), значения должны быть установлены True. То же самое для других партий. то есть, я хочу, чтобы моя логическая маска была создана как

[[False,True,True,False,False],
 [False,False,True,True,False],
 [False,False,True,True,False]]

Как достичь вышеуказанного без необходимости делать индивидуально для каждой партии? И желательно без использования рваной функции в тензорном потоке?

index < tf.range(number_of_timesteps) 

Вышеупомянутое можно использовать для установки True в крайних случаях, но я не смог найти способ установить True в середине.

1 Ответ

0 голосов
/ 10 июля 2020

Решение вашего примера может быть выполнено с помощью комбинации tf.one_hot и tf.roll.

input = [[1],[2],[2]]
intermediate_output = tf.one_hot(input, 5)
output = intermediate_output + tf.roll(intermediate_output, shift=1,axis=2)

Если вам нужно преобразовать в логическое значение из нулей и единиц

output = tf.where(tf.equal(output, 1), True, False)

Объяснение: tf.one_hot используется для преобразования ваших индексов в промежуточное горячее представление. Далее tf.roll сдвигает промежуточное представление на 1. Объединение этого с промежуточным представлением и преобразование в логическое значение возвращает желаемый результат.

EDIT:

Я не вижу хорошего способа, кроме a для l oop, чтобы расширить это до нескольких временных шагов. Приведенный ниже код сгенерирует желаемый результат

input = [[1],[2],[2]]
intermediate_output = tf.one_hot(input, 5)

outputs = []
timesteps = 3
for i in range(timesteps):
  outputs.append(tf.roll(intermediate_output, shift=i,axis=2))

output = tf.reduce_sum(tf.unstack(outputs, timesteps), 2)
output = tf.where(tf.equal(output, 1), True, False)

...