Получите размер пакета в пользовательском слое Keras и используйте операции тензорного потока (tf.Variable) - PullRequest
1 голос
/ 12 мая 2019

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

Предположим, что очень простой слой: (1) получить размер пакета (2) создать переменную tf.Variable (назовем это my_var) на основе размера пакета, затемнекоторые операции tf.random для окончательного изменения my_var (3) возвращают ввод, умноженный на my_var

Что я пробовал до сих пор:

class TestLayer(Layer):

    def __init__(self, **kwargs):

        self.num_batch = None
        self.my_var = None

        super(TestLayer, self).__init__(**kwargs)

    def build(self, input_shape):

        self.batch_size = input_shape[0]

        var_init = tf.ones(self.batch_size, dtype = x.dtype)
        self.my_var = tf.Variable(var_init, trainable=False, validate_shape=False)

        # some tensorflow random operations to alter self.my_var

        super(TestLayer, self).build(input_shape)  # Be sure to call this at the end

    def call(self, x):

        return self.my_var * x

    def compute_output_shape(self, input_shape):

        return input_shape

Теперь создаем очень простую модель:

# define model
input_layer = Input(shape = (2, 2, 3), name = 'input_layer')
x = TestLayer()(input_layer)

# connect model
my_mod = Model(inputs = input_layer, outputs = x)
my_mod.summary()

К сожалению, что бы я ни пытался / изменял в коде, я получал несколько ошибок, большинство из которых с очень криптографическими трассировками (ValueError: Невозможно преобразовать частично известный TensorShape в Tensor: или ValueError: Нет, значения не поддерживаются.).

Есть общие предложения?Заранее спасибо.

1 Ответ

1 голос
/ 12 мая 2019

Вам необходимо указать размер пакета, если вы хотите создать переменную размера batch_size. Кроме того, если вы хотите напечатать сводку, tf.Variable должен иметь фиксированную форму (validatate_shape=True), и он должен быть транслируемым для успешного умножения на вход:

import tensorflow as tf
from tensorflow.keras.layers import Layer, Input
from tensorflow.keras.models import Model

class TestLayer(Layer):

    def __init__(self, **kwargs):
        self.num_batch = None
        self.my_var = None
        super(TestLayer, self).__init__(**kwargs)

    def build(self, input_shape):
        self.batch_size = input_shape[0]
        var_init = tf.ones(self.batch_size, dtype=tf.float32)[..., None, None, None]
        self.my_var = tf.Variable(var_init, trainable=False, validate_shape=True)
        super(TestLayer, self).build(input_shape)  # Be sure to call this at the end

    def call(self, x):
        res = self.my_var * x
        return res

    def compute_output_shape(self, input_shape):
        return input_shape

# define model
input_layer = Input(shape=(2, 2, 3), name='input_layer', batch_size=10)
x = TestLayer()(input_layer)

# connect model
my_mod = Model(inputs=input_layer, outputs=x)
my_mod.summary()
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_layer (InputLayer)     (10, 2, 2, 3)             0         
_________________________________________________________________
test_layer (TestLayer)       (10, 2, 2, 3)             0         
=================================================================
Total params: 0
Trainable params: 0
Non-trainable params: 0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...