исправь и напиши исправления целиком
<!DOCTYPE html>
<html lang="ru">
<head>
  <meta charset="UTF-8">
  <title>Вопрос-Ответ на базе LSTM с использованием GPU</title>
  <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@latest"></script>
  <style>
    /* Ваши стили остаются без изменений */
    body {
      font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
      background-color: #f5f5f5;
      margin: 0;
      padding: 0;
      display: flex;
      flex-direction: column;
      align-items: center;
      min-height: 100vh;
    }
    header {
      background-color: #4CAF50;
      color: white;
      width: 100%;
      padding: 20px 0;
      text-align: center;
      box-shadow: 0 4px 6px rgba(0,0,0,0.1);
    }
    main {
      flex: 1;
      width: 90%;
      max-width: 800px;
      margin: 20px 0;
      background-color: white;
      padding: 30px;
      border-radius: 8px;
      box-shadow: 0 4px 6px rgba(0,0,0,0.1);
    }
    #status {
      margin-bottom: 20px;
      color: #333;
      font-weight: bold;
    }
    #question {
      width: 100%;
      padding: 12px 20px;
      margin-bottom: 20px;
      box-sizing: border-box;
      border: 2px solid #ccc;
      border-radius: 4px;
      font-size: 16px;
      transition: border-color 0.3s;
    }
    #question:focus {
      border-color: #4CAF50;
      outline: none;
    }
    #askButton {
      background-color: #4CAF50;
      color: white;
      padding: 12px 24px;
      border: none;
      border-radius: 4px;
      font-size: 16px;
      cursor: pointer;
      transition: background-color 0.3s;
    }
    #askButton:disabled {
      background-color: #a5d6a7;
      cursor: not-allowed;
    }
    #askButton:hover:not(:disabled) {
      background-color: #45a049;
    }
    #answer {
      margin-top: 30px;
      padding: 20px;
      background-color: #e8f5e9;
      border-left: 6px solid #4CAF50;
      border-radius: 4px;
      font-size: 18px;
      color: #333;
    }
    .loader {
      border: 8px solid #f3f3f3;
      border-top: 8px solid #4CAF50;
      border-radius: 50%;
      width: 40px;
      height: 40px;
      animation: spin 1s linear infinite;
      display: none;
      margin: 20px auto;
    }
    @keyframes spin {
      0% { transform: rotate(0deg); }
      100% { transform: rotate(360deg); }
    }
    @media (max-width: 600px) {
      main {
        padding: 20px;
      }
      #answer {
        font-size: 16px;
      }
      #question {
        font-size: 14px;
      }
      #askButton {
        font-size: 14px;
        padding: 10px 20px;
      }
    }
  </style>
</head>
<body>
  <header>
    <h1>Вопрос-Ответ на базе LSTM с использованием GPU</h1>
  </header>
  <main>
    <div id="status">Инициализация...</div>
    <input type="text" id="question" placeholder="Введите ваш вопрос здесь">
    <button id="askButton" onclick="getAnswer()" disabled>Получить ответ</button>
    <div class="loader" id="loader"></div>
    <p id="answer"></p>
  </main>

  <script>
    // Данные для обучения (20 пар вопрос-ответ)
    const data = [
      {
        "question": "Что такое искусственный интеллект?",
        "answer": "Искусственный интеллект – раздел информатики, посвященный созданию систем, способных выполнять задачи, требующие человеческого интеллекта."
      },
      {
        "question": "Кто такой Альберт Эйнштейн?",
        "answer": "Альберт Эйнштейн – немецкий физик-теоретик, один из основоположников современной теоретической физики."
      },
      {
        "question": "Что такое теория относительности?",
        "answer": "Теория относительности – физическая теория пространства-времени и гравитации, созданная Альбертом Эйнштейном."
      },
      {
        "question": "Что изучает квантовая механика?",
        "answer": "Квантовая механика изучает физические явления на масштабах атомов и субатомных частиц."
      },
      {
        "question": "Кто написал 'Войну и мир'?",
        "answer": "Роман 'Война и мир' написал Лев Николаевич Толстой."
      },
      {
        "question": "Что такое фотосинтез?",
        "answer": "Фотосинтез – процесс преобразования энергии света в химическую энергию в растениях."
      },
      {
        "question": "Какая самая высокая гора в мире?",
        "answer": "Самая высокая гора в мире – Эверест, высотой 8848 метров."
      },
      {
        "question": "Кто создал первую периодическую таблицу?",
        "answer": "Периодическую таблицу элементов создал Дмитрий Иванович Менделеев."
      },
      {
        "question": "Что такое ДНК?",
        "answer": "ДНК – молекула, несущая генетическую информацию живых организмов."
      },
      {
        "question": "Что такое глобальное потепление?",
        "answer": "Глобальное потепление – долгосрочное повышение средней температуры климатической системы Земли."
      },
      {
        "question": "Кто написал симфонию №9?",
        "answer": "Симфонию №9 написал Людвиг ван Бетховен."
      },
      {
        "question": "Что такое интернет?",
        "answer": "Интернет – глобальная система объединенных компьютерных сетей для хранения и передачи информации."
      },
      {
        "question": "Что изучает астрономия?",
        "answer": "Астрономия изучает небесные тела и явления вне атмосферы Земли."
      },
      {
        "question": "Кто такой Исаак Ньютон?",
        "answer": "Исаак Ньютон – английский физик и математик, основоположник классической механики."
      },
      {
        "question": "Что такое клетка?",
        "answer": "Клетка – основная структурная и функциональная единица живых организмов."
      },
      {
        "question": "Что такое электромагнитное излучение?",
        "answer": "Электромагнитное излучение – форма передачи энергии через волны, включающая свет и радиоволны."
      },
      {
        "question": "Кто первый человек в космосе?",
        "answer": "Первый человек в космосе – Юрий Алексеевич Гагарин."
      },
      {
        "question": "Что такое гравитация?",
        "answer": "Гравитация – сила притяжения между массами, описываемая законом всемирного тяготения."
      },
      {
        "question": "Что изучает биология?",
        "answer": "Биология изучает жизнь и живые организмы, их структуру, функции и эволюцию."
      },
      {
        "question": "Что такое Великая Китайская стена?",
        "answer": "Великая Китайская стена – серия укреплений, построенных для защиты Китая от нашествий."
      }
    ];

    // Глобальные переменные
    let model;
    let tokenizer;
    let uniqueAnswers; // Делается глобальной
    const sequenceLength = 20; // Максимальная длина последовательности

    /**
     * Инициализация бекенда TensorFlow.js для использования GPU
     */
    async function initializeBackend() {
      const statusElem = document.getElementById('status');
      statusElem.innerText = 'Инициализация бекенда...';

      try {
        // Получаем список доступных бекендов
        const backends = await tf.listBackends();

        if (backends.includes('webgl')) {
          // Устанавливаем бекенд WebGL
          await tf.setBackend('webgl');
          await tf.ready();
          statusElem.innerText = 'Бекенд WebGL инициализирован. Используется GPU.';
        } else {
          statusElem.innerText = 'Бекенд WebGL не поддерживается. Используется CPU.';
        }
      } catch (error) {
        console.error('Ошибка при инициализации бекенда:', error);
        statusElem.innerText = 'Ошибка инициализации бекенда. Используется CPU.';
      }
    }

    /**
     * Предобработка данных: токенизация и создание словаря
     */
    async function preprocessData() {
      const statusElem = document.getElementById('status');
      statusElem.innerText = 'Подготовка данных...';

      // Объединяем все вопросы и ответы для построения словаря
      const texts = data.flatMap(item => [item.question, item.answer]);

      // Функция для очистки текста от пунктуации и приведения к нижнему регистру
      const cleanText = (text) => {
        return text.replace(/[.,\/#!$%\^&\*;:{}=\-_`~()?"«»]/g, '').toLowerCase();
      };

      // Очистка текстов и разбивка на слова
      const cleanedTexts = texts.map(cleanText);
      const wordList = cleanedTexts.flatMap(text => text.split(/\s+/));

      // Создаем уникальный словарь
      const vocab = Array.from(new Set(wordList));

      // Индексирование слов (начиная с 1, 0 зарезервирован для паддинга)
      const wordIndex = {};
      vocab.forEach((word, index) => {
        wordIndex[word] = index + 1;
      });

      // Обратный словарь для декодирования
      const indexWord = {};
      Object.entries(wordIndex).forEach(([word, index]) => {
        indexWord[index] = word;
      });

      // Функция преобразования текста в последовательность индексов
      const textsToSequences = (texts) => {
        return texts.map(text => {
          return cleanText(text).split(/\s+/).map(word => wordIndex[word] || 0);
        });
      };

      tokenizer = {
        wordIndex,
        indexWord,
        textsToSequences
      };
    }

    /**
     * Создание модели LSTM
     * @param {number} vocabSize - Размер словаря
     */
    function createModel(vocabSize) {
      const statusElem = document.getElementById('status');
      statusElem.innerText = 'Создание модели...';

      model = tf.sequential();

      // Слой Embedding для преобразования индексов слов в векторные представления
      model.add(tf.layers.embedding({
        inputDim: vocabSize,
        outputDim: 128,
        inputLength: sequenceLength
      }));

      // Cлой LSTM для обработки последовательностей
      model.add(tf.layers.lstm({
        units: 256,
        returnSequences: false
      }));

      // Полносвязный слой с softmax активацией для классификации
      model.add(tf.layers.dense({
        units: vocabSize,
        activation: 'softmax'
      }));

      // Компиляция модели с использованием функции потерь и оптимизатора
      model.compile({
        loss: 'sparseCategoricalCrossentropy',
        optimizer: tf.train.adam(),
        metrics: ['accuracy']
      });
    }

    /**
     * Обучение модели на данных
     */
    async function trainModel() {
      const statusElem = document.getElementById('status');
      statusElem.innerText = 'Обучение модели...';

      // Извлекаем вопросы и ответы из данных
      const questions = data.map(item => item.question);
      const answers = data.map(item => item.answer);

      // Преобразуем тексты в последовательности индексов
      const questionSequences = tokenizer.textsToSequences(questions);
      const answerSequences = tokenizer.textsToSequences(answers);

      // Преобразуем ответы в классы (каждый уникальный ответ - отдельный класс)
      uniqueAnswers = Array.from(new Set(answers)); // Сохранение глобально
      const answerToClass = {};
      uniqueAnswers.forEach((ans, idx) => {
        answerToClass[ans] = idx;
      });
      const classLabels = answers.map(ans => answerToClass[ans]);

      // Преобразуем вопросы в тензоры
      const xs = tf.tensor2d(questionSequences.map(seq => padSequence(seq, sequenceLength)));

      // Преобразуем метки в тензоры
      const ys = tf.tensor1d(classLabels, 'int32');

      // Отображаем прогресс обучения
      const loader = document.getElementById('loader');
      loader.style.display = 'block';

      // Обучаем модель
      await model.fit(xs, ys, {
        epochs: 200, // Увеличено количество эпох для лучшего обучения
        batchSize: 4,
        shuffle: true,
        callbacks: {
          onEpochEnd: (epoch, logs) => {
            statusElem.innerText = `Обучение модели... Эпоха ${epoch + 1}/200, Потеря: ${logs.loss.toFixed(4)}, Точность: ${(logs.acc * 100).toFixed(2)}%`;
            console.log(`Эпоха ${epoch + 1}: Потеря = ${logs.loss.toFixed(4)}, Точность = ${(logs.acc * 100).toFixed(2)}%`);
          }
        }
      });

      // Освобождаем память
      xs.dispose();
      ys.dispose();

      loader.style.display = 'none';
      statusElem.innerText = 'Обучение завершено. Модель готова к использованию.';
      document.getElementById('askButton').disabled = false;
    }

    /**
     * Добавление паддинга к последовательности
     * @param {Array<number>} seq - Последовательность индексов
     * @param {number} length - Максимальная длина последовательности
     * @returns {Array<number>} - Паддированная последовательность
     */
    function padSequence(seq, length) {
      if (seq.length > length) {
        return seq.slice(seq.length - length); // Обрезаем в начале
      } else if (seq.length < length) {
        return Array(length - seq.length).fill(0).concat(seq); // Добавляем паддинг в начале
      } else {
        return seq;
      }
    }

    /**
     * Генерация ответа на введенный вопрос
     */
    async function getAnswer() {
      const questionInput = document.getElementById('question');
      const answerElem = document.getElementById('answer');
      const statusElem = document.getElementById('status');
      const loader = document.getElementById('loader');

      const question = questionInput.value.trim();
      if (!question) {
        answerElem.innerText = 'Пожалуйста, введите вопрос.';
        return;
      }

      statusElem.innerText = 'Генерация ответа...';
      loader.style.display = 'block';

      // Преобразуем вопрос в последовательность индексов
      const questionSequence = tokenizer.textsToSequences([question]);
      const paddedQuestion = padSequence(questionSequence[0], sequenceLength);
      const inputTensor = tf.tensor2d([paddedQuestion]);

      try {
        // Делаем предсказание
        const prediction = model.predict(inputTensor);

        // Убедимся, что предсказание имеет тип float32
        const predictionFloat = prediction.cast('float32');

        const predictedClass = (await predictionFloat.argMax(-1).data())[0];

        // Получаем ответ по предсказанному классу
        const answer = uniqueAnswers[predictedClass] || 'Извините, ответ не найден.';

        // Отображаем ответ
        answerElem.innerText = answer;
        statusElem.innerText = 'Модель готова к использованию.';
        
        // Освобождаем память
        predictionFloat.dispose();
        prediction.dispose();
      } catch (error) {
        console.error('Ошибка при генерации ответа:', error);
        answerElem.innerText = 'Произошла ошибка при генерации ответа.';
        statusElem.innerText = 'Ошибка. Попробуйте позже.';
      } finally {
        inputTensor.dispose();
        loader.style.display = 'none';
      }
    }

    /**
     * Инициализация приложения
     */
    async function init() {
      await initializeBackend(); // Инициализация бекенда WebGL
      await preprocessData();     // Предобработка данных
      const vocabSize = Object.keys(tokenizer.wordIndex).length + 1; // +1 для паддинга
      createModel(vocabSize);     // Создание модели
      await trainModel();         // Обучение модели
    }

    // Запуск инициализации при загрузке страницы
    window.onload = init;
  </script>
</body>
</html>