Не удается получить выходные данные промежуточных подмодельных слоев с tf2.0 / keras - PullRequest
0 голосов
/ 23 октября 2019

Допустим, мы используем TensorFlow r2.0 и говорим, что хотим использовать подмодели в Keras, поэтому у нас есть модель A , например:

def create_model_A(in_num_units, name):
    x = tf.keras.Input(shape=(in_num_units))
    y = tf.keras.layers.Dense(in_num_units, activation='relu')(x)
    y = tf.keras.layers.BatchNormalization()(y)
    y = tf.keras.layers.Dense(in_num_units, activation='relu')(y)
    y = tf.keras.layers.BatchNormalization()(y)
    y = x + y
    return tf.keras.Model(x, y, name=name)

и модель * 1006. * B , который использует модель A :

def create_model_B(in_num_units):
    x = tf.keras.Input(shape=(in_num_units))
    y = create_model_A(x.shape[-1], name='A_1')(x)
    y = tf.keras.layers.Dense(in_num_units // 2, name='downsize_1')(y)
    y = tf.keras.layers.BatchNormalization()(y)
    y = create_model_A(y.shape[-1], name='A_2')(y)
    y = tf.keras.layers.Dense(in_num_units // 2, name='downsize_2')(y)
    y = tf.keras.layers.BatchNormalization()(y)
    y = create_model_A(y.shape[-1], name='A_3')(y)
    y = tf.keras.layers.Dense(in_num_units // 2, name='downsize_3')(y)
    y = tf.keras.layers.BatchNormalization()(y)
    y = create_model_A(y.shape[-1], name='A_4')(y)
    return tf.keras.Model(x, y)

Это работает как шарм. Мы можем создать модель B следующим образом:

num_in_units = 500
model = create_model_B(num_in_units) # Works!

И воспользоваться всеми преимуществами tf.keras.Model. Но проблема возникает, когда мы хотим получить результат промежуточного слоя, который имеет подмодель A . Если слой является частью модели B , все работает:

inter_model_1 = tf.keras.Model(
    model.input, model.get_layer('downsize_1').output) # Works!

Но если слой относится к подмодели A, он падает с ValueError. Эта команда:

inter_model_2 = tf.keras.Model(
    model.input, model.get_layer('A_3').output) # Does not work!

Дает:

ValueError: Graph disconnected: cannot obtain value for tensor Tensor("input_4:0", shape=(None, 250), dtype=float32) at layer "input_4". The following previous layers were accessed without issue: [] 

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

print([n.input_tensors.name for n in model.get_layer('A_3').inbound_nodes])
['input_4:0', 'batch_normalization_5/Identity:0']

Один - это подмодель tf.keras.Input, а другой - вход, связанный с топ-моделью.

При построении новой модели из топ-модели B входного тензора для топ-модели B выходного тензора путь в графе, кажется, правильно проходит мимовход 'batch_normalization_5' и оба тензора правильно связаны на графике.

Однако при попытке связать тензор входа топ-модели B с подмоделью A выходной тензор, кажется, что выходные тензоры связаны с подмоделью tf.keras.Input, и оба тензора отключены.

Решение, которое я нашел на данный момент, заключается в использовании версии тензора с топ-модельюmodel.get_layer('A_3').output:

model.get_layer('A_3')._outbound_nodes[0].input_tensors

Но это кажется слишком сложным и не чистым ... Кроме того, оно не позволяет нам использовать слои внутри модели A .

Интересно, кто-нибудь может дать мне некоторую точность в этом tf.keras поведении? Правильно ли я это сделал? Это предполагаемое поведение? Это ошибка? Большое спасибо!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...