Tensorflow Keras: Запуск входных данных через не последовательно базовую модель без последнего слоя активации

Вопрос или проблема

У меня есть слой Transformer-Decoder, который включает несеквенционный поток входных данных с слоями Attention, работающими в цикле 12 раз. Как указано ниже:

def get_model():
    input_shape = (n_chans, embed_dim)
    input = layers.Input(shape=input_shape, dtype=tf.float32)
    positional_encoding = PositionalEmbedding(sequence_length, embed_dim)
    decoder_inputs = positional_encoding(input)
    mha = layers.MultiHeadAttention(num_heads=num_heads, key_dim=embed_dim)
    layernorm_1 = layers.LayerNormalization(epsilon=1e-05, axis=-1)
    layernorm_2 = layers.LayerNormalization(epsilon=1e-05, axis=-1)
    layernorm_3 = layers.LayerNormalization(epsilon=1e-05, axis=-1)
    #dropout_1 = tf.keras.layers.Dropout(0.1)
    dropout_2 = tf.keras.layers.Dropout(0.1)
    dropout_3 = tf.keras.layers.Dropout(0.1)
    dense_1 = layers.Dense((4*embed_dim), activation="gelu")
    dense_2 = layers.Dense(embed_dim)
    
    Z = decoder_inputs
    for N in range(12):
        Z = mha(query=Z, value=Z, key=Z, use_causal_mask=True)
        Z = dropout_2(Z)
        Z = layernorm_2(Z + skip_1)
        skip_2 = Z
        Z = dense_1(Z)
        Z = dense_2(Z)
        Z = dropout_3(Z)
    Z = layernorm_3(Z + skip_2)

    output1 = layers.TimeDistributed(tf.keras.layers.Dense(1, activation="sigmoid"))(Z)
    model = tf.keras.Model(input, output1)       
    return model

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

input_shape = (n_chans, sequence_length, 1)
inputs = tf.keras.layers.Input(shape = input_shape)
headless_model = tf.keras.models.Sequential(base_model.layers[:-1])
output = headless_model(input, training=False)
headless_model = keras.Model(input, output)

Но у меня есть некоторые сомнения, так как эта модель не последовательная и имеет повторяющиеся входы, такие как MHA, получающий тензор Z в качестве 3 аргументов, а также внутренний цикл for, будет ли это давать неправильную интерпретацию этой модели? Какой правильный подход для этого в Keras Tensorflow?

Примечание 1: Модель уже обучена и загружена с сохраненными весами. Примечание 2: Я пытаюсь получить безголовую модель без активаций для расчета расстояния Фреше для исследовательских целей.

Ответ или решение

Для получения выходных данных модели без последнего слоя активации в Keras, особенно когда ваша модель является сложной и состоит из нелинейных и повторяющихся последовательностей, необходимо подойти к этому вопросу с пониманием структуры модели и ее слоев. Ваша задача заключается в том, чтобы изначально создать «головное» (headless) представление модели без последнего слоя активации, сохраняя при этом всю сложность и логику, заложенную в слои до этого.

Шаг 1: Подготовка модели

Сначала разберемся с вашей текущей моделью. Созданная функция get_model() определяет модель Transformer с многошаговым вниманием, использующим слои, которые повторяются в цикле. Это сложная структура, включая множество нормализаций и дропаутов, поэтому просто извлечь все слои до последнего нельзя.

Шаг 2: Изменение входных данных

Ваша исходная реализация создания headless_model, а именно:

headless_model = tf.keras.models.Sequential(base_model.layers[:-1])

не будет работать, поскольку базовая модель (base_model) не является последовательной (sequential). Вместо этого, вам нужно создать новую модель учитывая только те слои, которые вам нужны.

Шаг 3: Создание headless модели

Для создания новой модели без последнего слоя активации, делайте следующее:

  1. Воспользуйтесь уже обученной моделью и извлеките все необходимые слои кроме выходного.
  2. Создайте новый Keras Model, указав вход и выход (но без активации).
def get_headless_model(base_model):
    # Извлечение всех слоев кроме последнего
    layer_outputs = base_model.layers[:-1]  # Игнорируем последний слой

    # Получаем выходные данные последнего слоя перед активацией
    output_tensor = base_model.layers[-2].output  # Слой перед активацией

    # Создаем новую модель
    headless_model = tf.keras.Model(inputs=base_model.input, outputs=output_tensor)

    return headless_model

# Загружаем нейронную сеть
base_model = get_model()
headless_model = get_headless_model(base_model)

# Теперь у вас есть headless_model для вычислений

Шаг 4: Использование модели для получения выходных данных

Теперь, когда у вас есть новая модель, вы можете передать данные через нее и получить выход без последней активации:

input_data = np.random.rand(n_chans, sequence_length, 1).astype(np.float32)  # Замените на ваши данные 
output = headless_model(input_data, training=False)

Заключение

Следуя данным шагам, вы можете избежать ошибок, связанных со структурой нейронной сети и обеспечить корректный вывод без последнего слоя активации. Это особенно важно для исследовательских целей, таких как вычисление расстояния Фреше (Fréchet Inception Distance), где требуется использовать промежуточные представления данных модели.

Если у вас возникнут дополнительные вопросы или потребуется дополнительная помощь, не стесняйтесь обращаться за разъяснениями.

Оцените материал
Добавить комментарий

Капча загружается...