Явная трансляция тензора переменного размера пакета

Я пытаюсь реализовать собственный Keras Layer в Tensorflow 2.0RC, и мне нужно объединить тензор в форме [None, Q] на тензор в форме [None, H, W, D], чтобы получить тензор в форме [None, H, W, D + Q]. Предполагается, что два входных тензора имеют одинаковый размер пакета, хотя он заранее не известен. Кроме того, во время записи не известны значения H, W, D и Q, но они оцениваются в методе build уровня при первом вызове уровня. Проблема, с которой я столкнулся, заключается в трансляции тензора в форме [None, Q] до тензора в форме [None, H, W, Q] для объединения.

Вот пример попытки создать Keras Model с использованием функционального API, который выполняет широковещательную рассылку переменных из формы [None, 3] в форму [None, 5, 5, 3]:

import tensorflow as tf
import tensorflow.keras.layers as kl
import numpy as np

x = tf.keras.Input([3])  # Shape [None, 3]
y = kl.Reshape([1, 1, 3])(x)  # Need to add empty dims before broadcasting
y = tf.broadcast_to(y, [-1, 5, 5, 3])  # Broadcast to shape [None, 5, 5, 3]

model = tf.keras.Model(inputs=x, outputs=y)

print(model(np.random.random(size=(8, 3))).shape)

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

InvalidArgumentError:  Dimension -1 must be >= 0

И затем, когда я меняю -1 на None, это дает мне:

TypeError: Failed to convert object of type <class 'list'> to Tensor. Contents: [None, 5, 5, 3]. Consider casting elements to a supported type.

Как я могу осуществить указанную трансляцию?


person wwilliamcook    schedule 29.08.2019    source источник


Ответы (1)


Вам необходимо использовать динамическую форму y для определения размера пакета. Динамическая форма тензора y задается tf.shape(y) и является операцией тензора, представляющей форму y, вычисляемую во время выполнения. В модифицированном примере это демонстрируется путем выбора между старой формой [None, 1, 1, 3] и новой формой с помощью _ 6_.

import tensorflow as tf
import tensorflow.keras.layers as kl
import numpy as np

x = tf.keras.Input([3])  # Shape [None, 3]
y = kl.Reshape([1, 1, 3])(x)  # Need to add empty dims before broadcasting
# Retain the batch and depth dimensions, but broadcast along H and W
broadcast_shape = tf.where([True, False, False, True],
                           tf.shape(y), [0, 5, 5, 0])
y = tf.broadcast_to(y, broadcast_shape)  # Broadcast to shape [None, 5, 5, 3]

model = tf.keras.Model(inputs=x, outputs=y)

print(model(np.random.random(size=(8, 3))).shape)
# prints: "(8, 5, 5, 3)"

Использованная литература:

«TensorFlow: формы и динамические размеры»

person wwilliamcook    schedule 30.08.2019