Ошибка ключа при попытке извлечь активацию слоя в последовательной модели TensorFlow

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

Я работаю над моделью TensorFlow и пытаюсь визуализировать активации из конкретного слоя. Модель компилируется и обучается успешно, но когда я пытаюсь извлечь активации из скрытого ReLU-слоя, я сталкиваюсь с ошибкой KeyError. Вот краткий обзор того, что я делаю:

У меня есть последовательная модель, которая обучается на наборе данных MNIST. После обучения я пытаюсь создать новую модель для вывода активаций из скрытого ReLU (Dense) слоя. Я правильно изменил размер тестового изображения, но получаю ошибку при вызове функции predict() на модели активации.

Вот код, который я использую для извлечения активаций:

import tensorflow as tf
from tensorflow.keras import models, layers

# Загрузка и предобработка набора данных MNIST
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0

# Определение и компиляция модели
model = models.Sequential([
    layers.Flatten(input_shape=(28, 28)),
    layers.Dense(128, activation='relu'),
    layers.Dense(10)
])
model.compile(optimizer="adam", loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True), metrics=['accuracy'])
model.fit(x_train, y_train, epochs=5)

# Определение модели активации
layer_name="dense"
activation_model = models.Model(inputs=model.input, outputs=model.get_layer(layer_name).output)

# Подготовка тестового изображения
test_image = x_test[0].reshape(1, 28, 28)

# Получение активаций
activations = activation_model.predict(test_image)

Однако я получаю следующую ошибку.

<ipython-input-16-cbfe6f9d08f9> in <cell line: 19>()
     17 # Определение модели активации
     18 layer_name="dense"
---> 19 activation_model = models.Model(inputs=model.input, outputs=model.get_layer(layer_name).output)
     20 
     21 # Подготовка тестового изображения

1 frames
/usr/local/lib/python3.10/dist-packages/keras/src/ops/operation.py in _get_node_attribute_at_index(self, node_index, attr, attr_name)
    283         """
    284         if not self._inbound_nodes:
--> 285             raise ValueError(
    286                 f"The layer {self.name} has never been called "
    287                 f"and thus has no defined {attr_name}."

ValueError: Слой sequential_14 никогда не вызывался и, следовательно, не имеет заданного входа.

Я попробовал:

Проверил, что TensorFlow правильно установлен. Проверил слои модели и размеры входов. Подкорректировал размер входного изображения теста, добавив размер батча и каналы.

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

Для решения проблемы с ошибкой KeyError при попытке извлечь активации слоя из модели Sequential в TensorFlow, давайте разберем вашу ситуацию более подробно.

Вы корректно создали модель и обучили её на датасете MNIST. Однако проблема возникает на этапе извлечения активаций. Основной причиной этой ошибки является то, что при подаче входных данных в модель необходимо учитывать, что модель ожидает входы в определённом формате.

Давайте рассмотрим ваш код с учетом необходимых исправлений:

  1. Проблема с именем слоя: Вы используете layer_name="dense", но в вашей модели есть два слоя Dense, и в Keras слои могут быть доступны по индексу или имени. Вам нужно уточнить, какой именно слой вы хотите использовать. Например, по умолчанию Keras назначает именам слоев такие названия, как dense и dense_1 для первого и второго Dense слоя соответственно.

  2. Корректная форма ввода для активационной модели: Вы правильно изменили форму тестового изображения, но нужно убедиться, что оно имеет правильную форму, которая ожидается моделью. Для слоя Dense входные данные должны быть одномерными. Следовательно, правильно будет использовать test_image = x_test[0].reshape(1, 28 * 28).

Внесём необходимые изменения в ваш код:

import tensorflow as tf
from tensorflow.keras import models, layers

# Загрузка и предварительная обработка датасета MNIST
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0

# Определение и компиляция модели
model = models.Sequential([
    layers.Flatten(input_shape=(28, 28)),
    layers.Dense(128, activation='relu', name='dense_1'),  # Указываем имя слоя
    layers.Dense(10, name='output_layer')
])
model.compile(optimizer="adam", 
              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True), 
              metrics=['accuracy'])
model.fit(x_train, y_train, epochs=5)

# Определение активационной модели
layer_name = "dense_1"  # Укажите правильное имя слоя
activation_model = models.Model(inputs=model.input, outputs=model.get_layer(layer_name).output)

# Подготовка тестового изображения
test_image = x_test[0].reshape(1, 28 * 28)  # Изменяем форму

# Получение активаций
activations = activation_model.predict(test_image)

print(activations)  # Вывод активаций

Объяснение изменений:

  • Имя слоя: Убедитесь, что вы указываете правильное имя слоя, чтобы избежать путаницы, особенно если несколько слоев имеют одинаковый тип.
  • Форма входа: Изменение формы изображения на (1, 28*28) делает его подходящим для модели.

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

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

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