ошибка в коде вот код
import json
import numpy as np
import tensorflow as tf
from tensorflow.keras.models import Model, load_model
from tensorflow.keras.layers import (
    Input, LSTM, Dense, Embedding, Bidirectional, Concatenate
)
from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.preprocessing.sequence import pad_sequences
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint
import sys
import os
import pickle
import string
import re
from sklearn.model_selection import train_test_split

# Установка фиксированного значения для воспроизводимости
np.random.seed(42)
tf.random.set_seed(42)

# Параметры модели и обработки данных
MAX_NUM_WORDS_Q = 10000          # Максимальное количество слов в токенизаторе вопросов
MAX_NUM_WORDS_A = 10000          # Максимальное количество слов в токенизаторе ответов
MAX_SEQUENCE_LENGTH = 20         # Максимальная длина последовательности
EMBEDDING_DIM = 100              # Размерность векторного представления слов
LSTM_UNITS = 256                 # Количество единиц в LSTM слое
EPOCHS = 100                     # Количество эпох обучения
BATCH_SIZE = 16                  # Размер пакета
MODEL_PATH = 'qa_model_seq2seq.keras'      # Изменено с .h5 на .keras
TOKENIZER_Q_PATH = 'tokenizer_q.pickle' # Путь для сохранения токенизатора вопросов
TOKENIZER_A_PATH = 'tokenizer_a.pickle' # Путь для сохранения токенизатора ответов

def preprocess_text(text):
    """
    Простая предобработка текста: удаление пунктуации, приведение к нижнему регистру и удаление лишних пробелов.
    """
    text = text.lower()
    text = re.sub(f'[{re.escape(string.punctuation)}]', '', text)
    text = re.sub(r'\s+', ' ', text).strip()
    return text

class BahdanauAttention(tf.keras.layers.Layer):
    def __init__(self, units):
        super(BahdanauAttention, self).__init__()
        self.W1 = Dense(units)
        self.W2 = Dense(units)
        self.V = Dense(1)

    def call(self, query, values):
        """
        query: Декодерные выходы, форма (batch_size, t_decoder, hidden_size)
        values: Энкодерные выходы, форма (batch_size, t_encoder, hidden_size)
        """
        # query_with_time_axis: (batch_size, t_decoder, 1, hidden_size)
        query_with_time_axis = tf.expand_dims(query, 2)
        # values_with_time_axis: (batch_size, 1, t_encoder, hidden_size)
        values_with_time_axis = tf.expand_dims(values, 1)

        # score: (batch_size, t_decoder, t_encoder, 1)
        score = self.V(tf.nn.tanh(
            self.W1(query_with_time_axis) + self.W2(values_with_time_axis)
        ))

        # attention_weights: (batch_size, t_decoder, t_encoder, 1)
        attention_weights = tf.nn.softmax(score, axis=2)

        # context_vector: (batch_size, t_decoder, hidden_size)
        context_vector = attention_weights * tf.expand_dims(values, 1)
        context_vector = tf.reduce_sum(context_vector, axis=2)

        return context_vector

class QAModel:
    def __init__(self, data_file):
        self.data_file = data_file
        self.questions = []
        self.answers = []
        self.tokenizer_q = Tokenizer(num_words=MAX_NUM_WORDS_Q, oov_token="<OOV>")
        self.tokenizer_a = Tokenizer(num_words=MAX_NUM_WORDS_A, oov_token="<OOV>")
        self.model = None
        self.encoder_model = None
        self.decoder_model = None
        self.max_encoder_seq_length = MAX_SEQUENCE_LENGTH
        self.max_decoder_seq_length = MAX_SEQUENCE_LENGTH + 2  # Для <start> и <end>

        # Подготовка данных
        self.prepare_data()

        # Попытка загрузить существующую модель и токенизаторы
        if os.path.exists(MODEL_PATH) and os.path.exists(TOKENIZER_Q_PATH) and os.path.exists(TOKENIZER_A_PATH):
            self.load_model_and_tokenizers()
        else:
            print("Сохранённая модель или токенизаторы не найдены. Необходимо обучить модель командой 'train'.")

    def prepare_data(self):
        # Загрузка данных из JSON
        try:
            with open(self.data_file, 'r', encoding='utf-8') as f:
                data = json.load(f)
        except Exception as e:
            print(f"Ошибка при загрузке файла {self.data_file}: {e}")
            sys.exit(1)

        for entry in data:
            q = preprocess_text(entry['question'])
            a = preprocess_text(entry['answer'])
            self.questions.append(q)
            # Добавляем специальные токены начала и конца предложения для декодера
            a = '<start> ' + a + ' <end>'
            self.answers.append(a)

        # Разделение данных на обучающую и валидационную выборки
        self.questions_train, self.questions_val, self.answers_train, self.answers_val = train_test_split(
            self.questions, self.answers, test_size=0.2, random_state=42
        )

        # Токенизация вопросов и ответов
        self.tokenizer_q.fit_on_texts(self.questions_train)
        self.tokenizer_a.fit_on_texts(self.answers_train)

        # Сохранение словаря
        self.word_index_q = self.tokenizer_q.word_index
        self.word_index_a = self.tokenizer_a.word_index
        self.index_word_a = {v: k for k, v in self.word_index_a.items()}

        # Преобразование текстов в последовательности
        self.encoder_input_train = self.tokenizer_q.texts_to_sequences(self.questions_train)
        self.encoder_input_val = self.tokenizer_q.texts_to_sequences(self.questions_val)

        self.decoder_input_train = self.tokenizer_a.texts_to_sequences(self.answers_train)
        self.decoder_input_val = self.tokenizer_a.texts_to_sequences(self.answers_val)

        # Добавление паддинга и ограничение длины последовательностей
        self.encoder_input_train = pad_sequences(
            self.encoder_input_train, maxlen=self.max_encoder_seq_length, padding='post'
        )
        self.encoder_input_val = pad_sequences(
            self.encoder_input_val, maxlen=self.max_encoder_seq_length, padding='post'
        )

        self.decoder_input_train = pad_sequences(
            self.decoder_input_train, maxlen=self.max_decoder_seq_length, padding='post'
        )
        self.decoder_input_val = pad_sequences(
            self.decoder_input_val, maxlen=self.max_decoder_seq_length, padding='post'
        )

        # Создание выходных данных для декодера, смещённых на один токен вправо
        self.decoder_target_train = self._create_decoder_target(self.decoder_input_train)
        self.decoder_target_val = self._create_decoder_target(self.decoder_input_val)

    def _create_decoder_target(self, decoder_input):
        """
        Создаёт целевые выходные данные для декодера, смещённые на один токен.
        """
        decoder_target = np.zeros_like(decoder_input)
        decoder_target[:, :-1] = decoder_input[:, 1:]
        decoder_target[:, -1] = 0
        return np.expand_dims(decoder_target, -1)

    def build_model(self):
        """
        Строит модель Seq2Seq с использованием механизма внимания (Bahdanau Attention).
        """
        # Энкодер
        encoder_inputs = Input(shape=(self.max_encoder_seq_length,), name='encoder_inputs')
        encoder_embedding = Embedding(
            input_dim=MAX_NUM_WORDS_Q,
            output_dim=EMBEDDING_DIM,
            mask_zero=True,
            name='encoder_embedding'
        )(encoder_inputs)
        encoder_lstm = Bidirectional(
            LSTM(
                LSTM_UNITS,
                return_sequences=True,
                return_state=True,
                name='encoder_lstm'
            )
        )
        encoder_outputs, forward_h, forward_c, backward_h, backward_c = encoder_lstm(encoder_embedding)
        state_h = Concatenate()([forward_h, backward_h])
        state_c = Concatenate()([forward_c, backward_c])

        # Декодер
        decoder_inputs = Input(shape=(self.max_decoder_seq_length,), name='decoder_inputs')
        decoder_embedding = Embedding(
            input_dim=MAX_NUM_WORDS_A,
            output_dim=EMBEDDING_DIM,
            mask_zero=True,
            name='decoder_embedding'
        )(decoder_inputs)
        decoder_lstm = LSTM(
            LSTM_UNITS * 2,  # Удваиваем количество единиц из-за Bidirectional энкодера
            return_sequences=True,
            return_state=True,
            name='decoder_lstm'
        )
        decoder_outputs, _, _ = decoder_lstm(decoder_embedding, initial_state=[state_h, state_c])

        # Механизм внимания (BahdanauAttention)
        attention_layer = BahdanauAttention(units=256)  # units можно настроить по желанию
        context_vector = attention_layer(decoder_outputs, encoder_outputs)  # (batch_size, t_decoder, hidden_size)

        # Конкатенация контекстного вектора с выходами декодера
        decoder_combined_context = Concatenate(axis=-1, name='concat_layer')([decoder_outputs, context_vector])

        # Выходной слой
        decoder_dense = Dense(MAX_NUM_WORDS_A, activation='softmax', name='output_dense')
        decoder_outputs = decoder_dense(decoder_combined_context)

        # Модель обучения
        self.model = Model([encoder_inputs, decoder_inputs], decoder_outputs)
        self.model.compile(optimizer=Adam(), loss='sparse_categorical_crossentropy', metrics=['accuracy'])
        self.model.summary()

    def build_inference_models(self):
        """
        Строит отдельные энкодер и декодер модели для инференса.
        """
        if self.model is None:
            print("Модель не загружена!")
            return

        # Энкодер модель
        encoder_input_layer = self.model.get_layer('encoder_inputs')
        encoder_inputs = encoder_input_layer.output  # Получаем выход слоя 'encoder_inputs'
        encoder_embedding = self.model.get_layer('encoder_embedding')(encoder_inputs)
        encoder_lstm = self.model.get_layer('encoder_lstm')
        encoder_outputs, forward_h, forward_c, backward_h, backward_c = encoder_lstm(encoder_embedding)
        state_h = Concatenate()([forward_h, backward_h])
        state_c = Concatenate()([forward_c, backward_c])
        self.encoder_model = Model(encoder_inputs, [encoder_outputs, state_h, state_c])

        # Декодер модель
        decoder_input_layer = self.model.get_layer('decoder_inputs')
        decoder_inputs = decoder_input_layer.output  # Получаем выход слоя 'decoder_inputs'
        decoder_state_input_h = Input(shape=(LSTM_UNITS * 2,), name='decoder_state_input_h')
        decoder_state_input_c = Input(shape=(LSTM_UNITS * 2,), name='decoder_state_input_c')
        encoder_outputs_inf = Input(shape=(self.max_encoder_seq_length, LSTM_UNITS * 2), name='encoder_outputs_inf')

        decoder_embedding = self.model.get_layer('decoder_embedding')(decoder_inputs)
        decoder_lstm = self.model.get_layer('decoder_lstm')
        decoder_outputs, state_h_dec, state_c_dec = decoder_lstm(
            decoder_embedding, initial_state=[decoder_state_input_h, decoder_state_input_c]
        )

        # Механизм внимания (BahdanauAttention)
        attention_layer = self.model.get_layer('bahdanau_attention')
        context_vector = attention_layer(decoder_outputs, encoder_outputs_inf)  # (batch_size, t_decoder, hidden_size)

        # Конкатенация контекстного вектора с выходами декодера
        decoder_combined_context = Concatenate(axis=-1, name='concat_layer')([decoder_outputs, context_vector])

        # Выходной слой
        decoder_dense = self.model.get_layer('output_dense')
        decoder_outputs = decoder_dense(decoder_combined_context)

        # Модель декодера
        self.decoder_model = Model(
            [decoder_inputs, encoder_outputs_inf, decoder_state_input_h, decoder_state_input_c],
            [decoder_outputs, state_h_dec, state_c_dec]
        )

    def train(self):
        """
        Обучает модель на подготовленных данных.
        """
        if self.model is None:
            self.build_model()

        # Коллбэки
        early_stopping = EarlyStopping(monitor='val_loss', patience=10, verbose=1, restore_best_weights=True)
        model_checkpoint = ModelCheckpoint(
            MODEL_PATH,
            monitor='val_loss',
            save_best_only=True,
            verbose=1
        )

        print("Начало обучения модели...")
        history = self.model.fit(
            [self.encoder_input_train, self.decoder_input_train],
            self.decoder_target_train,
            batch_size=BATCH_SIZE,
            epochs=EPOCHS,
            validation_data=([self.encoder_input_val, self.decoder_input_val], self.decoder_target_val),
            callbacks=[early_stopping, model_checkpoint],
            verbose=2
        )
        print("Обучение завершено.")

        # Сохранение токенизаторов
        with open(TOKENIZER_Q_PATH, 'wb') as handle:
            pickle.dump(self.tokenizer_q, handle, protocol=pickle.HIGHEST_PROTOCOL)
        with open(TOKENIZER_A_PATH, 'wb') as handle:
            pickle.dump(self.tokenizer_a, handle, protocol=pickle.HIGHEST_PROTOCOL)
        print(f"Токенизаторы сохранены как {TOKENIZER_Q_PATH} и {TOKENIZER_A_PATH}.")

        # После обучения построим инференс модели
        self.build_inference_models()

    def load_model_and_tokenizers(self):
        """
        Загружает сохранённую модель и токенизаторы из файлов.
        """
        try:
            # Загружаем модель с указанием пользовательского слоя
            self.model = load_model(
                MODEL_PATH,
                custom_objects={'BahdanauAttention': BahdanauAttention},
                compile=False
            )
            print(f"Модель успешно загружена из {MODEL_PATH}.")

            # Загружаем токенизаторы
            with open(TOKENIZER_Q_PATH, 'rb') as handle:
                self.tokenizer_q = pickle.load(handle)
            with open(TOKENIZER_A_PATH, 'rb') as handle:
                self.tokenizer_a = pickle.load(handle)
            print(f"Токенизаторы успешно загружены из {TOKENIZER_Q_PATH} и {TOKENIZER_A_PATH}.")

            # Восстанавливаем индексы
            self.word_index_q = self.tokenizer_q.word_index
            self.word_index_a = self.tokenizer_a.word_index
            self.index_word_a = {v: k for k, v in self.word_index_a.items()}

            # После загрузки модели построим инференс модели
            self.build_inference_models()

        except Exception as e:
            print(f"Ошибка при загрузке модели или токенизаторов: {e}")
            print("Необходимо обучить модель командой 'train'.")

    def predict(self, question, decode_length=MAX_SEQUENCE_LENGTH):
        """
        Генерирует ответ на заданный вопрос.
        """
        if self.encoder_model is None or self.decoder_model is None:
            print("Инференс модели не готов. Убедитесь, что модель обучена и инференс модели построены.")
            return None

        question = preprocess_text(question)
        sequence = self.tokenizer_q.texts_to_sequences([question])
        padded = pad_sequences(sequence, maxlen=self.max_encoder_seq_length, padding='post')

        # Получение состояний энкодера
        encoder_outputs, state_h, state_c = self.encoder_model.predict(padded, verbose=0)

        # Инициализация декодера с токеном <start>
        target_seq = np.array([[self.tokenizer_a.word_index.get('<start>', 1)]])
        decoded_sentence = []

        # Инициализация состояний декодера
        decoder_state_h = state_h
        decoder_state_c = state_c

        for _ in range(decode_length):
            output_tokens, decoder_state_h, decoder_state_c = self.decoder_model.predict(
                [target_seq, encoder_outputs, decoder_state_h, decoder_state_c],
                verbose=0
            )

            # Выбор токена с наибольшей вероятностью
            sampled_token_index = np.argmax(output_tokens[0, -1, :])
            sampled_word = self.index_word_a.get(sampled_token_index, '<OOV>')

            if sampled_word == '<end>' or sampled_word == '<OOV>':
                break

            decoded_sentence.append(sampled_word)

            # Обновление целевой последовательности (добавляем сгенерированный токен)
            target_seq = np.array([[sampled_token_index]])

        return ' '.join(decoded_sentence)

def main():
    if len(sys.argv) < 2:
        print("Использование: python qa_seq2seq.py <data.json>")
        return

    data_file = sys.argv[1]
    if not os.path.exists(data_file):
        print(f"Файл данных {data_file} не найден.")
        return

    qa = QAModel(data_file)

    print("\nКонсольная программа для обучения и использования Seq2Seq модели вопросов и ответов.")
    print("Доступные команды:")
    print(" - train : Обучить (или переобучить) модель на предоставленных данных.")
    print(" - ask <ваш вопрос> : Получить ответ на заданный вопрос.")
    print(" - exit : Выйти из программы.\n")

    while True:
        try:
            command = input("Введите команду: ").strip()
        except (EOFError, KeyboardInterrupt):
            print("\nВыход из программы.")
            break

        if command.lower() == "train":
            qa.train()
        elif command.lower().startswith("ask "):
            question = command[4:].strip()
            if not question:
                print("Пожалуйста, введите вопрос после команды 'ask'. Например: ask Как тебя зовут?")
                continue
            answer = qa.predict(question)
            if answer:
                print("Ответ:", answer)
            else:
                print("Извините, я не могу ответить на этот вопрос.")
        elif command.lower() == "exit":
            print("Выход из программы.")
            break
        else:
            print("Неизвестная команда. Доступные команды: train, ask <вопрос>, exit.")

if __name__ == "__main__":
    main()
вот ошибка 

C:\Users\abeli\PycharmProjects\pythonProject4\.venv>python qa_rnn.py data.json
2024-11-11 12:19:32.944530: I tensorflow/core/util/port.cc:153] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`.
2024-11-11 12:19:34.232216: I tensorflow/core/util/port.cc:153] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`.
2024-11-11 12:19:37.877651: I tensorflow/core/platform/cpu_feature_guard.cc:210] This TensorFlow binary is optimized to use available CPU instructions in performance-critical operations.
To enable the following instructions: AVX2 FMA, in other operations, rebuild TensorFlow with the appropriate compiler flags.
Ошибка при загрузке модели или токенизаторов: <class 'keras.src.models.functional.Functional'> could not be deserialized properly. Please ensure that components that are Python object instances (layers, models, etc.) returned by `get_config()` are explicitly deserialized in the model's `from_config()` method.

config={'module': 'keras.src.models.functional', 'class_name': 'Functional', 'config': {'name': 'functional', 'trainable': True, 'layers': [{'module': 'keras.layers', 'class_name': 'InputLayer', 'config': {'batch_shape': [None, 20], 'dtype': 'float32', 'sparse': False, 'name': 'encoder_inputs'}, 'registered_name': None, 'name': 'encoder_inputs', 'inbound_nodes': []}, {'module': 'keras.layers', 'class_name': 'Embedding', 'config': {'name': 'encoder_embedding', 'trainable': True, 'dtype': {'module': 'keras', 'class_name': 'DTypePolicy', 'config': {'name': 'float32'}, 'registered_name': None}, 'input_dim': 10000, 'output_dim': 100, 'embeddings_initializer': {'module': 'keras.initializers', 'class_name': 'RandomUniform', 'config': {'seed': None, 'minval': -0.05, 'maxval': 0.05}, 'registered_name': None}, 'embeddings_regularizer': None, 'activity_regularizer': None, 'embeddings_constraint': None, 'mask_zero': True}, 'registered_name': None, 'build_config': {'input_shape': [None, 20]}, 'name': 'encoder_embedding', 'inbound_nodes': [{'args': [{'class_name': '__keras_tensor__', 'config': {'shape': [None, 20], 'dtype': 'float32', 'keras_history': ['encoder_inputs', 0, 0]}}], 'kwargs': {}}]}, {'module': 'keras.src.ops.numpy', 'class_name': 'NotEqual', 'config': {'name': 'not_equal'}, 'registered_name': 'NotEqual', 'name': 'not_equal', 'inbound_nodes': [{'args': [{'class_name': '__keras_tensor__', 'config': {'shape': [None, 20], 'dtype': 'float32', 'keras_history': ['encoder_inputs', 0, 0]}}, 0], 'kwargs': {}}]}, {'module': 'keras.layers', 'class_name': 'InputLayer', 'config': {'batch_shape': [None, 22], 'dtype': 'float32', 'sparse': False, 'name': 'decoder_inputs'}, 'registered_name': None, 'name': 'decoder_inputs', 'inbound_nodes': []}, {'module': 'keras.layers', 'class_name': 'Bidirectional', 'config': {'name': 'bidirectional', 'trainable': True, 'dtype': {'module': 'keras', 'class_name': 'DTypePolicy', 'config': {'name': 'float32'}, 'registered_name': None, 'shared_object_id': 1864770501904}, 'merge_mode': 'concat', 'layer': {'module': 'keras.layers', 'class_name': 'LSTM', 'config': {'name': 'forward_encoder_lstm', 'trainable': True, 'dtype': {'module': 'keras', 'class_name': 'DTypePolicy', 'config': {'name': 'float32'}, 'registered_name': None}, 'return_sequences': True, 'return_state': True, 'go_backwards': False, 'stateful': False, 'unroll': False, 'zero_output_for_mask': True, 'units': 256, 'activation': 'tanh', 'recurrent_activation': 'sigmoid', 'use_bias': True, 'kernel_initializer': {'module': 'keras.initializers', 'class_name': 'GlorotUniform', 'config': {'seed': None}, 'registered_name': None, 'shared_object_id': 1864770499888}, 'recurrent_initializer': {'module': 'keras.initializers', 'class_name': 'OrthogonalInitializer', 'config': {'seed': None, 'gain': 1.0}, 'registered_name': None, 'shared_object_id': 1864770499552}, 'bias_initializer': {'module': 'keras.initializers', 'class_name': 'Zeros', 'config': {}, 'registered_name': None, 'shared_object_id': 1864770499312}, 'unit_forget_bias': True, 'kernel_regularizer': None, 'recurrent_regularizer': None, 'bias_regularizer': None, 'activity_regularizer': None, 'kernel_constraint': None, 'recurrent_constraint': None, 'bias_constraint': None, 'dropout': 0.0, 'recurrent_dropout': 0.0, 'seed': None}, 'registered_name': None, 'build_config': {'input_shape': [None, 20, 100]}}, 'backward_layer': {'module': 'keras.layers', 'class_name': 'LSTM', 'config': {'name': 'backward_encoder_lstm', 'trainable': True, 'dtype': {'module': 'keras', 'class_name': 'DTypePolicy', 'config': {'name': 'float32'}, 'registered_name': None}, 'return_sequences': True, 'return_state': True, 'go_backwards': True, 'stateful': False, 'unroll': False, 'zero_output_for_mask': True, 'units': 256, 'activation': 'tanh', 'recurrent_activation': 'sigmoid', 'use_bias': True, 'kernel_initializer': {'module': 'keras.initializers', 'class_name': 'GlorotUniform', 'config': {'seed': None}, 'registered_name': None, 'shared_object_id': 1864770936400}, 'recurrent_initializer': {'module': 'keras.initializers', 'class_name': 'OrthogonalInitializer', 'config': {'seed': None, 'gain': 1.0}, 'registered_name': None, 'shared_object_id': 1864770936352}, 'bias_initializer': {'module': 'keras.initializers', 'class_name': 'Zeros', 'config': {}, 'registered_name': None, 'shared_object_id': 1864770935344}, 'unit_forget_bias': True, 'kernel_regularizer': None, 'recurrent_regularizer': None, 'bias_regularizer': None, 'activity_regularizer': None, 'kernel_constraint': None, 'recurrent_constraint': None, 'bias_constraint': None, 'dropout': 0.0, 'recurrent_dropout': 0.0, 'seed': None}, 'registered_name': None, 'build_config': {'input_shape': [None, 20, 100]}}}, 'registered_name': None, 'build_config': {'input_shape': [None, 20, 100]}, 'name': 'bidirectional', 'inbound_nodes': [{'args': [{'class_name': '__keras_tensor__', 'config': {'shape': [None, 20, 100], 'dtype': 'float32', 'keras_history': ['encoder_embedding', 0, 0]}}], 'kwargs': {'mask': {'class_name': '__keras_tensor__', 'config': {'shape': [None, 20], 'dtype': 'bool', 'keras_history': ['not_equal', 0, 0]}}}}]}, {'module': 'keras.layers', 'class_name': 'Embedding', 'config': {'name': 'decoder_embedding', 'trainable': True, 'dtype': {'module': 'keras', 'class_name': 'DTypePolicy', 'config': {'name': 'float32'}, 'registered_name': None, 'shared_object_id': 1864770501904}, 'input_dim': 10000, 'output_dim': 100, 'embeddings_initializer': {'module': 'keras.initializers', 'class_name': 'RandomUniform', 'config': {'seed': None, 'minval': -0.05, 'maxval': 0.05}, 'registered_name': None}, 'embeddings_regularizer': None, 'activity_regularizer': None, 'embeddings_constraint': None, 'mask_zero': True}, 'registered_name': None, 'build_config': {'input_shape': [None, 22]}, 'name': 'decoder_embedding', 'inbound_nodes': [{'args': [{'class_name': '__keras_tensor__', 'config': {'shape': [None, 22], 'dtype': 'float32', 'keras_history': ['decoder_inputs', 0, 0]}}], 'kwargs': {}}]}, {'module': 'keras.layers', 'class_name': 'Concatenate', 'config': {'name': 'concatenate', 'trainable': True, 'dtype': {'module': 'keras', 'class_name': 'DTypePolicy', 'config': {'name': 'float32'}, 'registered_name': None, 'shared_object_id': 1864770501904}, 'axis': -1}, 'registered_name': None, 'build_config': {'input_shape': [[None, 256], [None, 256]]}, 'name': 'concatenate', 'inbound_nodes': [{'args': [[{'class_name': '__keras_tensor__', 'config': {'shape': [None, 256], 'dtype': 'float32', 'keras_history': ['bidirectional', 0, 1]}}, {'class_name': '__keras_tensor__', 'config': {'shape': [None, 256], 'dtype': 'float32', 'keras_history': ['bidirectional', 0, 3]}}]], 'kwargs': {}}]}, {'module': 'keras.layers', 'class_name': 'Concatenate', 'config': {'name': 'concatenate_1', 'trainable': True, 'dtype': {'module': 'keras', 'class_name': 'DTypePolicy', 'config': {'name': 'float32'}, 'registered_name': None, 'shared_object_id': 1864770501904}, 'axis': -1}, 'registered_name': None, 'build_config': {'input_shape': [[None, 256], [None, 256]]}, 'name': 'concatenate_1', 'inbound_nodes': [{'args': [[{'class_name': '__keras_tensor__', 'config': {'shape': [None, 256], 'dtype': 'float32', 'keras_history': ['bidirectional', 0, 2]}}, {'class_name': '__keras_tensor__', 'config': {'shape': [None, 256], 'dtype': 'float32', 'keras_history': ['bidirectional', 0, 4]}}]], 'kwargs': {}}]}, {'module': 'keras.layers', 'class_name': 'LSTM', 'config': {'name': 'decoder_lstm', 'trainable': True, 'dtype': {'module': 'keras', 'class_name': 'DTypePolicy', 'config': {'name': 'float32'}, 'registered_name': None, 'shared_object_id': 1864770501904}, 'return_sequences': True, 'return_state': True, 'go_backwards': False, 'stateful': False, 'unroll': False, 'zero_output_for_mask': False, 'units': 512, 'activation': 'tanh', 'recurrent_activation': 'sigmoid', 'use_bias': True, 'kernel_initializer': {'module': 'keras.initializers', 'class_name': 'GlorotUniform', 'config': {'seed': None}, 'registered_name': None, 'shared_object_id': 1864770940768}, 'recurrent_initializer': {'module': 'keras.initializers', 'class_name': 'OrthogonalInitializer', 'config': {'seed': None, 'gain': 1.0}, 'registered_name': None, 'shared_object_id': 1864770944128}, 'bias_initializer': {'module': 'keras.initializers', 'class_name': 'Zeros', 'config': {}, 'registered_name': None, 'shared_object_id': 1864770944272}, 'unit_forget_bias': True, 'kernel_regularizer': None, 'recurrent_regularizer': None, 'bias_regularizer': None, 'activity_regularizer': None, 'kernel_constraint': None, 'recurrent_constraint': None, 'bias_constraint': None, 'dropout': 0.0, 'recurrent_dropout': 0.0, 'seed': None}, 'registered_name': None, 'build_config': {'shapes_dict': {'sequences_shape': [None, 22, 100], 'initial_state_shape': [[None, 512], [None, 512]]}}, 'name': 'decoder_lstm', 'inbound_nodes': [{'args': [{'class_name': '__keras_tensor__', 'config': {'shape': [None, 22, 100], 'dtype': 'float32', 'keras_history': ['decoder_embedding', 0, 0]}}], 'kwargs': {'initial_state': [{'class_name': '__keras_tensor__', 'config': {'shape': [None, 512], 'dtype': 'float32', 'keras_history': ['concatenate', 0, 0]}}, {'class_name': '__keras_tensor__', 'config': {'shape': [None, 512], 'dtype': 'float32', 'keras_history': ['concatenate_1', 0, 0]}}], 'training': False}}]}, {'module': None, 'class_name': 'BahdanauAttention', 'config': {'units': 256, 'trainable': True, 'dtype': {'module': 'keras', 'class_name': 'DTypePolicy', 'config': {'name': 'float32'}, 'registered_name': None, 'shared_object_id': 1864770501904}}, 'registered_name': 'BahdanauAttention', 'build_config': {'input_shape': [None, 22, 512]}, 'name': 'bahdanau_attention', 'inbound_nodes': [{'args': [{'class_name': '__keras_tensor__', 'config': {'shape': [None, 22, 512], 'dtype': 'float32', 'keras_history': ['decoder_lstm', 0, 0]}}, {'class_name': '__keras_tensor__', 'config': {'shape': [None, 20, 512], 'dtype': 'float32', 'keras_history': ['bidirectional', 0, 0]}}], 'kwargs': {}}]}, {'module': 'keras.layers', 'class_name': 'Concatenate', 'config': {'name': 'concat_layer', 'trainable': True, 'dtype': {'module': 'keras', 'class_name': 'DTypePolicy', 'config': {'name': 'float32'}, 'registered_name': None, 'shared_object_id': 1864770501904}, 'axis': -1}, 'registered_name': None, 'build_config': {'input_shape': [[None, 22, 512], [None, 22, 512]]}, 'name': 'concat_layer', 'inbound_nodes': [{'args': [[{'class_name': '__keras_tensor__', 'config': {'shape': [None, 22, 512], 'dtype': 'float32', 'keras_history': ['decoder_lstm', 0, 0]}}, {'class_name': '__keras_tensor__', 'config': {'shape': [None, 22, 512], 'dtype': 'float32', 'keras_history': ['bahdanau_attention', 0, 0]}}]], 'kwargs': {}}]}, {'module': 'keras.layers', 'class_name': 'Dense', 'config': {'name': 'output_dense', 'trainable': True, 'dtype': {'module': 'keras', 'class_name': 'DTypePolicy', 'config': {'name': 'float32'}, 'registered_name': None, 'shared_object_id': 1864770501904}, 'units': 10000, 'activation': 'softmax', 'use_bias': True, 'kernel_initializer': {'module': 'keras.initializers', 'class_name': 'GlorotUniform', 'config': {'seed': None}, 'registered_name': None}, 'bias_initializer': {'module': 'keras.initializers', 'class_name': 'Zeros', 'config': {}, 'registered_name': None}, 'kernel_regularizer': None, 'bias_regularizer': None, 'kernel_constraint': None, 'bias_constraint': None}, 'registered_name': None, 'build_config': {'input_shape': [None, 22, 1024]}, 'name': 'output_dense', 'inbound_nodes': [{'args': [{'class_name': '__keras_tensor__', 'config': {'shape': [None, 22, 1024], 'dtype': 'float32', 'keras_history': ['concat_layer', 0, 0]}}], 'kwargs': {}}]}], 'input_layers': [['encoder_inputs', 0, 0], ['decoder_inputs', 0, 0]], 'output_layers': [['output_dense', 0, 0]]}, 'registered_name': 'Functional', 'build_config': {'input_shape': None}, 'compile_config': None}.

Exception encountered: <class '__main__.BahdanauAttention'> could not be deserialized properly. Please ensure that components that are Python object instances (layers, models, etc.) returned by `get_config()` are explicitly deserialized in the model's `from_config()` method.

config={'module': None, 'class_name': 'BahdanauAttention', 'config': {'units': 256, 'trainable': True, 'dtype': {'module': 'keras', 'class_name': 'DTypePolicy', 'config': {'name': 'float32'}, 'registered_name': None, 'shared_object_id': 1864770501904}}, 'registered_name': 'BahdanauAttention', 'build_config': {'input_shape': [None, 22, 512]}, 'name': 'bahdanau_attention', 'inbound_nodes': [{'args': [{'class_name': '__keras_tensor__', 'config': {'shape': [None, 22, 512], 'dtype': 'float32', 'keras_history': ['decoder_lstm', 0, 0]}}, {'class_name': '__keras_tensor__', 'config': {'shape': [None, 20, 512], 'dtype': 'float32', 'keras_history': ['bidirectional', 0, 0]}}], 'kwargs': {}}]}.

Exception encountered: Error when deserializing class 'BahdanauAttention' using config={'units': 256, 'trainable': True, 'dtype': 'float32'}.

Exception encountered: BahdanauAttention.__init__() got an unexpected keyword argument 'trainable'
Необходимо обучить модель командой 'train'.

Консольная программа для обучения и использования Seq2Seq модели вопросов и ответов.
Доступные команды:
 - train : Обучить (или переобучить) модель на предоставленных данных.
 - ask <ваш вопрос> : Получить ответ на заданный вопрос.
 - exit : Выйти из программы.

Введите команду: train
WARNING:tensorflow:From D:\miniconda\Lib\site-packages\keras\src\backend\tensorflow\core.py:204: The name tf.placeholder is deprecated. Please use tf.compat.v1.placeholder instead.

D:\miniconda\Lib\site-packages\keras\src\layers\layer.py:932: UserWarning: Layer 'bahdanau_attention' (of type BahdanauAttention) was passed an input with a mask attached to it. However, this layer does not support masking and will therefore destroy the mask information. Downstream layers will not see the mask.
  warnings.warn(
Model: "functional"
┌───────────────────────────────┬───────────────────────────┬─────────────────┬────────────────────────────┐
│ Layer (type)                  │ Output Shape              │         Param # │ Connected to               │
├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤
│ encoder_inputs (InputLayer)   │ (None, 20)                │               0 │ -                          │
├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤
│ encoder_embedding (Embedding) │ (None, 20, 100)           │       1,000,000 │ encoder_inputs[0][0]       │
├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤
│ not_equal (NotEqual)          │ (None, 20)                │               0 │ encoder_inputs[0][0]       │
├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤
│ decoder_inputs (InputLayer)   │ (None, 22)                │               0 │ -                          │
├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤
│ bidirectional (Bidirectional) │ [(None, 20, 512), (None,  │         731,136 │ encoder_embedding[0][0],   │
│                               │ 256), (None, 256), (None, │                 │ not_equal[0][0]            │
│                               │ 256), (None, 256)]        │                 │                            │
├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤
│ decoder_embedding (Embedding) │ (None, 22, 100)           │       1,000,000 │ decoder_inputs[0][0]       │
├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤
│ concatenate (Concatenate)     │ (None, 512)               │               0 │ bidirectional[0][1],       │
│                               │                           │                 │ bidirectional[0][3]        │
├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤
│ concatenate_1 (Concatenate)   │ (None, 512)               │               0 │ bidirectional[0][2],       │
│                               │                           │                 │ bidirectional[0][4]        │
├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤
│ decoder_lstm (LSTM)           │ [(None, 22, 512), (None,  │       1,255,424 │ decoder_embedding[0][0],   │
│                               │ 512), (None, 512)]        │                 │ concatenate[0][0],         │
│                               │                           │                 │ concatenate_1[0][0]        │
├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤
│ bahdanau_attention            │ (None, 22, 512)           │         262,913 │ decoder_lstm[0][0],        │
│ (BahdanauAttention)           │                           │                 │ bidirectional[0][0]        │
├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤
│ concat_layer (Concatenate)    │ (None, 22, 1024)          │               0 │ decoder_lstm[0][0],        │
│                               │                           │                 │ bahdanau_attention[0][0]   │
├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤
│ output_dense (Dense)          │ (None, 22, 10000)         │      10,250,000 │ concat_layer[0][0]         │
└───────────────────────────────┴───────────────────────────┴─────────────────┴────────────────────────────┘
 Total params: 14,499,473 (55.31 MB)
 Trainable params: 14,499,473 (55.31 MB)
 Non-trainable params: 0 (0.00 B)
Начало обучения модели...
Epoch 1/100
D:\miniconda\Lib\site-packages\keras\src\models\functional.py:225: UserWarning: The structure of `inputs` doesn't match the expected structure: ['encoder_inputs', 'decoder_inputs']. Received: the structure of inputs=('*', '*')
  warnings.warn(
2024-11-11 12:19:49.419275: E tensorflow/core/util/util.cc:131] oneDNN supports DT_BOOL only on platforms with AVX-512. Falling back to the default Eigen-based implementation if present.

Epoch 1: val_loss improved from inf to 9.13479, saving model to qa_model_seq2seq.keras
4/4 - 10s - 2s/step - accuracy: 0.1881 - loss: 9.2006 - val_accuracy: 0.2448 - val_loss: 9.1348
Epoch 2/100

Epoch 2: val_loss improved from 9.13479 to 7.62339, saving model to qa_model_seq2seq.keras
4/4 - 2s - 539ms/step - accuracy: 0.2620 - loss: 8.8500 - val_accuracy: 0.2448 - val_loss: 7.6234
Epoch 3/100

Epoch 3: val_loss improved from 7.62339 to 6.51804, saving model to qa_model_seq2seq.keras
4/4 - 2s - 555ms/step - accuracy: 0.2620 - loss: 6.7746 - val_accuracy: 0.2448 - val_loss: 6.5180
Epoch 4/100

Epoch 4: val_loss did not improve from 6.51804
4/4 - 1s - 292ms/step - accuracy: 0.2620 - loss: 5.6332 - val_accuracy: 0.2448 - val_loss: 6.6956
Epoch 5/100

Epoch 5: val_loss did not improve from 6.51804
4/4 - 1s - 303ms/step - accuracy: 0.2620 - loss: 5.2015 - val_accuracy: 0.2448 - val_loss: 7.1158
Epoch 6/100

Epoch 6: val_loss did not improve from 6.51804
4/4 - 1s - 296ms/step - accuracy: 0.2620 - loss: 5.0873 - val_accuracy: 0.2448 - val_loss: 7.5170
Epoch 7/100

Epoch 7: val_loss did not improve from 6.51804
4/4 - 1s - 299ms/step - accuracy: 0.2620 - loss: 5.0013 - val_accuracy: 0.2448 - val_loss: 7.8516
Epoch 8/100

Epoch 8: val_loss did not improve from 6.51804
4/4 - 1s - 292ms/step - accuracy: 0.2620 - loss: 4.9385 - val_accuracy: 0.2448 - val_loss: 8.1203
Epoch 9/100

Epoch 9: val_loss did not improve from 6.51804
4/4 - 1s - 287ms/step - accuracy: 0.2620 - loss: 4.8711 - val_accuracy: 0.2448 - val_loss: 8.2800
Epoch 10/100

Epoch 10: val_loss did not improve from 6.51804
4/4 - 1s - 291ms/step - accuracy: 0.2513 - loss: 4.7943 - val_accuracy: 0.2343 - val_loss: 8.4078
Epoch 11/100

Epoch 11: val_loss did not improve from 6.51804
4/4 - 1s - 300ms/step - accuracy: 0.2620 - loss: 4.7097 - val_accuracy: 0.2448 - val_loss: 8.5208
Epoch 12/100

Epoch 12: val_loss did not improve from 6.51804
4/4 - 1s - 291ms/step - accuracy: 0.2620 - loss: 4.6536 - val_accuracy: 0.2448 - val_loss: 8.6115
Epoch 13/100

Epoch 13: val_loss did not improve from 6.51804
4/4 - 1s - 288ms/step - accuracy: 0.2620 - loss: 4.6125 - val_accuracy: 0.2448 - val_loss: 8.6759
Epoch 13: early stopping
Restoring model weights from the end of the best epoch: 3.
Обучение завершено.
Токенизаторы сохранены как tokenizer_q.pickle и tokenizer_a.pickle.
Traceback (most recent call last):
  File "C:\Users\abeli\PycharmProjects\pythonProject4\.venv\qa_rnn.py", line 424, in <module>
    main()
  File "C:\Users\abeli\PycharmProjects\pythonProject4\.venv\qa_rnn.py", line 406, in main
    qa.train()
  File "C:\Users\abeli\PycharmProjects\pythonProject4\.venv\qa_rnn.py", line 303, in train
    self.build_inference_models()
  File "C:\Users\abeli\PycharmProjects\pythonProject4\.venv\qa_rnn.py", line 231, in build_inference_models
    encoder_lstm = self.model.get_layer('encoder_lstm')
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\miniconda\Lib\site-packages\keras\src\utils\traceback_utils.py", line 122, in error_handler
    raise e.with_traceback(filtered_tb) from None
  File "D:\miniconda\Lib\site-packages\keras\src\models\model.py", line 208, in get_layer
    raise ValueError(
ValueError: No such layer: encoder_lstm. Existing layers are: ['encoder_inputs', 'encoder_embedding', 'decoder_inputs', 'bidirectional', 'decoder_embedding', 'concatenate', 'concatenate_1', 'decoder_lstm', 'bahdanau_attention', 'concat_layer', 'output_dense'].

C:\Users\abeli\PycharmProjects\pythonProject4\.venv>pause
Для продолжения нажмите любую клавишу . . .