Исключение, возникшее при вызове BroadcastTo.call()

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

Я пытаюсь обучить модель предсказания текстовой последовательности из изображения (LSTM + CNN). Однако, когда я пытаюсь обучить модель, возникает ошибка BroadcastTo на внутреннем слое, которую трудно отладить дальше.

Сообщение об ошибке:

Эпоха 1/10
---------------------------------------------------------------------------
TypeError                                 Traceback (последний вызов был последним)
<ipython-input-134-01c02dee08c0> in <cell line: 5>()
      3 tf.debugging.disable_traceback_filtering()
      4 
----> 5 model.fit([train_images, train_sequences], train_sequences,
      6           epochs=10, batch_size=32, validation_split=0.2)

1 фреймы
/usr/local/lib/python3.10/dist-packages/keras/src/utils/traceback_utils.py в error_handler(*args, **kwargs)
    120             # Чтобы получить полный стек вызовов, вызовите:
    121             # `keras.config.disable_traceback_filtering()`
--> 122             raise e.with_traceback(filtered_tb) from None
    123         наконец:
    124             del filtered_tb

/usr/local/lib/python3.10/dist-packages/tensorflow/python/framework/tensor_util.py в make_tensor_proto(values, dtype, shape, verify_shape, allow_broadcast)
    611       str_values = [compat.as_bytes(x) for x in proto_values]
    612     кроме TypeError:
--> 613       raise TypeError(f"Не удалось преобразовать элементы {values} в тензор. "
    614                       "Рассмотрите возможность преобразования элементов в поддерживаемый тип. См. "
    615                       "https://www.tensorflow.org/api_docs/python/tf/dtypes "

TypeError: Исключение возникло при вызове BroadcastTo.call().

Не удалось преобразовать элементы (None, 100, 256) в тензор. Рассмотрите возможность преобразования элементов в поддерживаемый тип. См. https://www.tensorflow.org/api_docs/python/tf/dtypes для поддерживаемых типов TF.

Аргументы, полученные вызовом BroadcastTo.call():
  • x=tf.Tensor(shape=(32, 100, 1), dtype=bool)

Код модели

IMG_WIDTH, IMG_HEIGHT = 200, 50
EMBEDDING_DIM = 256
MAX_SEQ_LENGTH = 100  # Максимальная длина выходной последовательности

from tensorflow import keras
from tensorflow.keras.layers import Layer

class CastingLayer(Layer):
    def __init__(self, **kwargs):
        super(CastingLayer, self).__init__(**kwargs)

    def call(self, inputs):
        return tf.cast(inputs, dtype=tf.float32)

def create_cnn_encoder():
    """Создайте извлекатель признаков CNN."""
    inputs = Input(shape=(IMG_HEIGHT, IMG_WIDTH, 1))  # Вход в градациях серого
    x = Conv2D(32, (3, 3), activation='relu', padding='same')(inputs)
    x = MaxPooling2D((2, 2))(x)
    x = Conv2D(64, (3, 3), activation='relu', padding='same')(x)
    x = MaxPooling2D((2, 2))(x)
    x = Conv2D(128, (3, 3), activation='relu', padding='same')(x)
    x = MaxPooling2D((2, 2))(x)
    x = Flatten()(x)
    cnn_output = Dense(EMBEDDING_DIM, activation='relu')(x)
    return Model(inputs, cnn_output)

def create_model():
    """Создайте модель энкодер-декодер."""
    cnn_encoder = create_cnn_encoder()

    # Энкодер
    encoder_input = cnn_encoder.input
    encoder_output = cnn_encoder.output
    encoder_output = RepeatVector(MAX_SEQ_LENGTH, name="enc_output")(encoder_output)

    # Декодер
    decoder_input = Input(shape=(MAX_SEQ_LENGTH,))
    decoder_embedding = Embedding(vocab_size, EMBEDDING_DIM, mask_zero=True)(decoder_input) 

    #decoder_gru = Bidirectional(GRU(256, return_sequences=True), name="dec_gru")(decoder_embedding)
    decoder_gru = GRU(256, return_sequences=True, name="gru")(decoder_embedding)
    decoder_gru = TimeDistributed(Dense(EMBEDDING_DIM), name="td_gru")(decoder_gru) # Добавлен слой Dense для соответствия размерности вывода энкодера

    # Конкатенация Энкодера и Декодера
    decoder_concat = Concatenate()([encoder_output, decoder_gru])
    # Изменено: Оберните слой Dense в слой lambda для обработки маски
    dense_layer = Dense(vocab_size, activation='softmax') 
    decoder_output = TimeDistributed(dense_layer)(decoder_concat)

    # Полная модель
    model = Model([encoder_input, decoder_input], decoder_output)
    model.compile(optimizer="adam", loss="sparse_categorical_crossentropy", metrics=['accuracy'])
    return model

model = create_model()
model.summary()

Изображение модели:

Я попробовал следующее:

  • Вручную преобразовать входные данные в float (из изображений) и int32 (из последовательностей)
  • Пытался добавить слой преобразования после слоя декодирования. Это невозможно из-за маскирования в слое декодирования, которое не поддерживается (ожидается, что последующие слои будут следовать за маскировкой)
  • Я пытался отслеживать обратный вызов, но они замаскированы. Я пытался отключить внутреннюю фильтрацию. Изменений в выходном трассировке не произошло.

Ожидание заключается в том, что обучение модели должно работать, так как входные слои имеют float32 и int32.

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

Ошибка, с которой вы столкнулись, указывает на проблему с преобразованием данных в тензор внутри вашей модели для последовательного предсказания текста на основе изображений, использующей комбинацию LSTM и CNN. Давайте разберем ваши проблемы шаг за шагом и рассмотрим, как их устранить.

Проблема и ее причины

Ошибка TypeError говорит о невозможности конвертировать элементы в виде (None, 100, 256) в тензор. Это может указывать на несоответствие типов данных между входами и ожидаемыми типами в слоях вашей модели. Предварительно рассмотрим следующий участок кода, в котором возникает ошибка:

decoder_concat = Concatenate()([encoder_output, decoder_gru])

Здесь вы пытаетесь объединить выходы кодировщика и декодировщика. Важно убедиться, что форма тензоров, которые вы пытаетесь объединить, подходит для операции конкатенации. Ваша ошибка говорит о том, что один из этих тензоров может иметь неправильный тип (например, bool), что также может указывать на проблему с маскированием входных данных.

Анализ вашего кода

  1. Проверка форматов данных: Убедитесь, что encoder_output и decoder_gru имеют совместимые формы для конкатенации. Один из них может иметь размерность, несовместимую с ожидаемой другой формой.

  2. Обработка типов данных: Привязка типов данных в Embedding и то, что вы используете mask_zero=True, может вызвать проблемы. Попробуйте временно отключить маскирование и посмотрите, изменится ли поведение модели. Убедитесь, что передаваемые в Embedding данные имеют целочисленный формат типа int32.

  3. Кастинг данных: Вероятно, стоит добавить кастинг к float32 для изображений и int32 для последовательностей (если вы этого уже не сделали). Вы также упомянули использование CastingLayer, но важно убедиться, что он применяется корректно.

Рекомендации по исправлению

  • Проверьте формы тензоров после каждой операции: Включите print(tensor.shape) после RepeatVector, GRU, и перед Concatenate, чтобы убедиться, что все они имеют правильные размеры. Например:

    encoder_output = RepeatVector(MAX_SEQ_LENGTH)(encoder_output)
    print("Encoder Output Shape:", encoder_output.shape)
    
    decoder_gru = GRU(256, return_sequences=True)(decoder_embedding)
    print("Decoder GRU Output Shape:", decoder_gru.shape)
  • Проблемы с маскированием: Если у вас есть проблемы с mask_zero, попробуйте убрать маскирование и посмотрите, сможет ли код пройти без ошибок. Например:

    decoder_embedding = Embedding(vocab_size, EMBEDDING_DIM)(decoder_input) 
  • Проверка входных данных: Убедитесь, что ваши train_images и train_sequences действительно имеют ожидаемые формы и типы данных. Возможно, стоит добавить проверки данных перед вызовом model.fit.

  • Использование исключений и отладка: Используйте отладочные инструменты TensorFlow, чтобы изучить конкретную ошибку. Запустите код с включенной отладкой, чтобы получить более детальную информацию о проблеме.

При исправлении кода и проверке его практически, следуйте этим шагам, и, надеюсь, вы сможете устранить эту ошибку и успешно обучить вашу модель.

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

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