Вопрос или проблема
Я пытаюсь обучить модель предсказания текстовой последовательности из изображения (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
), что также может указывать на проблему с маскированием входных данных.
Анализ вашего кода
-
Проверка форматов данных: Убедитесь, что
encoder_output
иdecoder_gru
имеют совместимые формы для конкатенации. Один из них может иметь размерность, несовместимую с ожидаемой другой формой. -
Обработка типов данных: Привязка типов данных в
Embedding
и то, что вы используетеmask_zero=True
, может вызвать проблемы. Попробуйте временно отключить маскирование и посмотрите, изменится ли поведение модели. Убедитесь, что передаваемые вEmbedding
данные имеют целочисленный формат типаint32
. -
Кастинг данных: Вероятно, стоит добавить кастинг к
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, чтобы изучить конкретную ошибку. Запустите код с включенной отладкой, чтобы получить более детальную информацию о проблеме.
При исправлении кода и проверке его практически, следуйте этим шагам, и, надеюсь, вы сможете устранить эту ошибку и успешно обучить вашу модель.