Как связать тензор со слоем кераса вдоль пакета (без указания размера пакета)?

#python #tensorflow #keras

Вопрос:

Я хочу объединить выходные данные слоя встраивания с пользовательским тензором ( myarr / myconst ). Я могу указать все с фиксированным размером пакета следующим образом:

 import numpy as np
import tensorflow as tf

BATCH_SIZE = 100
myarr = np.ones((10, 5))
myconst = tf.constant(np.tile(myarr, (BATCH_SIZE, 1, 1)))

# Model definition
inputs = tf.keras.layers.Input((10,), batch_size=BATCH_SIZE)
x = tf.keras.layers.Embedding(10, 5)(inputs)
x = tf.keras.layers.Concatenate(axis=1)([x, myconst])
model = tf.keras.models.Model(inputs=inputs, outputs=x)
 

Однако, если я не укажу размер пакета и не выложу свой массив, т. Е. Просто следующее…

 myarr = np.ones((10, 5))
myconst = tf.constant(myarr)

# Model definition
inputs = tf.keras.layers.Input((10,))
x = tf.keras.layers.Embedding(10, 5)(inputs)
x = tf.keras.layers.Concatenate(axis=1)([x, myconst])
model = tf.keras.models.Model(inputs=inputs, outputs=x)
 

… Я получаю сообщение об ошибке, указывающее, что фигуры [(None, 10, 5), (10, 5)] не могут быть объединены. Есть ли способ добавить эту None ось / batch_size, чтобы избежать разбиения на плитки?

Заранее спасибо

Ответ №1:

Вы хотите связать с 3D-тензором формы (batch, 10, 5) константу формы (10, 5) вдоль размерности пакета. Для этого ваша константа должна быть 3D. Поэтому вам нужно изменить его (1, 10, 5) форму и повторить вдоль axis=0 , чтобы соответствовать форме (batch, 10, 5) и выполнить объединение.

Мы делаем это внутри Lambda слоя:

 X = np.random.randint(0,10, (100,10))
Y = np.random.uniform(0,1, (100,20,5))

myarr = np.ones((1, 10, 5)).astype('float32')
myconst = tf.convert_to_tensor(myarr)

def repeat_const(tensor, myconst):
    shapes = tf.shape(tensor)
    return tf.repeat(myconst, shapes[0], axis=0)

inputs = tf.keras.layers.Input((10,))
x = tf.keras.layers.Embedding(10, 5)(inputs)
xx = tf.keras.layers.Lambda(lambda x: repeat_const(x, myconst))(x)
x = tf.keras.layers.Concatenate(axis=1)([x, xx])
model = tf.keras.models.Model(inputs=inputs, outputs=x)
model.compile('adam', 'mse')

model.fit(X, Y, epochs=3)