Lo que intento hacer es agregar un tensor constante a la salida de la red:

inputs = Input(shape=(config.N_FRAMES_IN_SEQUENCE, config.IMAGE_H, config.IMAGE_W, config.N_CHANNELS))
cnn = VGG16(include_top=False, weights='imagenet', input_shape=(config.IMAGE_H, config.IMAGE_W, config.N_CHANNELS))
x = TimeDistributed(cnn)(inputs)
x = TimeDistributed(Flatten())(x)
x = LSTM(256)(x)
x = Dense(config.N_LANDMARKS * 2, activation='linear')(x)

mean_landmarks = np.array(config.MEAN_LANDMARKS, np.float32)
mean_landmarks = mean_landmarks.flatten()
mean_landmarks_tf = tf.convert_to_tensor(mean_landmarks)
x = x + mean_landmarks_tf

model = Model(inputs=inputs, outputs=x)
optimizer = Adadelta()
model.compile(optimizer=optimizer, loss='mae')

Pero me sale un error:

ValueError: Output tensors to a Model must be the output of a Keras `Layer` (thus holding past layer metadata). Found: Tensor("add:0", shape=(?, 136), dtype=float32)

Es trivial en tensorflow, pero ¿cómo hacerlo en Keras?

4
mrgloom 16 oct. 2018 a las 11:36

2 respuestas

La mejor respuesta

Parece que se puede hacer con la capa Lambda:

from keras.layers import Lambda

def add_mean_landmarks(x):
    mean_landmarks = np.array(config.MEAN_LANDMARKS, np.float32)
    mean_landmarks = mean_landmarks.flatten()
    mean_landmarks_tf = tf.convert_to_tensor(mean_landmarks)
    x = x + mean_landmarks_tf
    return x


x = Lambda(add_mean_landmarks)(x)
4
mrgloom 16 oct. 2018 a las 08:42

Además de su propia respuesta, preferiría en gran medida una implementación nativa de adición, como por ejemplo Keras proporciona { {X0}}.

La razón de esto es que no estoy seguro de cómo su propia función lambda se empuja hacia las capas inferiores: Esencialmente, en TensorFlow (o cualquier otro backend que use), las operaciones internas hacen uso del gráfico computacional altamente optimizado, mientras que las operaciones personalizadas tienden a traducirse en una ejecución de bajo nivel más pesada (o, en el peor de los casos, hinchada).

La forma correcta de hacerlo con Keras.layers.Add sería simplemente hacer

x = keras.layers.Add()([x, add_mean_landmarks])
-1
dennlinger 16 oct. 2018 a las 12:08