исправь код "import json
import torch
import torch.nn as nn
import torch.optim as optim
import numpy as np
from torch.utils.data import DataLoader, Dataset

# Включаем обнаружение аномалий для диагностики ошибок
torch.autograd.set_detect_anomaly(True)

# 1. Загрузка и подготовка данных
with open('ideas.json', 'r') as f:
    ideas_data = json.load(f)

ideas = [item['idea'] for item in ideas_data]

# Преобразуем идеи в текстовые данные
all_text = " ".join(ideas)
vocab = sorted(set(all_text))
char_to_idx = {u: i for i, u in enumerate(vocab)}
idx_to_char = np.array(vocab)
text_as_int = np.array([char_to_idx[c] for c in all_text])

# Параметры для обучения
seq_length = 100  # Длина последовательности
batch_size = 64
embedding_dim = 256
hidden_dim = 512
vocab_size = len(vocab)

# Создание датасета
class TextDataset(Dataset):
    def __init__(self, text, seq_length):
        self.text = text
        self.seq_length = seq_length

    def __len__(self):
        return len(self.text) - self.seq_length

    def __getitem__(self, idx):
        return (torch.tensor(self.text[idx: idx + self.seq_length], dtype=torch.long), 
                torch.tensor(self.text[idx + 1: idx + self.seq_length + 1], dtype=torch.long))

dataset = TextDataset(text_as_int, seq_length)
train_loader = DataLoader(dataset, batch_size=batch_size, shuffle=True)

# 2. Создание модели LSTM
class IdeaGeneratorLSTM(nn.Module):
    def __init__(self, vocab_size, embedding_dim, hidden_dim, output_dim):
        super(IdeaGeneratorLSTM, self).__init__()
        self.embedding = nn.Embedding(vocab_size, embedding_dim)
        self.lstm = nn.LSTM(embedding_dim, hidden_dim, batch_first=True)
        self.fc = nn.Linear(hidden_dim, output_dim)

    def forward(self, x, hidden=None):
        x = self.embedding(x)
        out, hidden = self.lstm(x, hidden)
        out = self.fc(out)
        return out, hidden

model = IdeaGeneratorLSTM(vocab_size, embedding_dim, hidden_dim, vocab_size)

# 3. Обучение модели
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)

# Функция для обучения модели
def train_model(model, data_loader, criterion, optimizer, epochs=10):
    model.train()
    for epoch in range(epochs):
        hidden = None  # Инициализируем скрытое состояние как None в начале каждой эпохи
        for batch, (x, y) in enumerate(data_loader):
            optimizer.zero_grad()
            output, hidden = model(x, hidden)  # Передаем скрытое состояние в модель
            loss = criterion(output.view(-1, vocab_size), y.view(-1))
            loss.backward()  # Вычисляем градиенты
            optimizer.step()  # Обновляем параметры
            hidden = hidden.detach()  # Отсоединяем скрытое состояние от графа
        print(f'Epoch [{epoch+1}/{epochs}], Loss: {loss.item():.4f}')

train_model(model, train_loader, criterion, optimizer)

# 4. Генерация новых идей
def generate_text(model, start_string, length=100):
    model.eval()
    input_eval = torch.tensor([char_to_idx[c] for c in start_string], dtype=torch.long)
    input_eval = input_eval.unsqueeze(0)  # Добавляем размер для батча
    generated_text = start_string
    hidden = None

    for i in range(length):
        output, hidden = model(input_eval, hidden)
        output = output[:, -1, :].squeeze(0)
        probs = torch.nn.functional.softmax(output, dim=0).detach()
        next_char_idx = torch.multinomial(probs, 1)[0].item()
        next_char = idx_to_char[next_char_idx]
        generated_text += next_char
        input_eval = torch.cat((input_eval[:, 1:], torch.tensor([[next_char_idx]], dtype=torch.long)), dim=1)
        
    return generated_text

# Пример генерации
print(generate_text(model, start_string="Idea: ", length=200))
".