Исправь синтетические ошибки import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader, TensorDataset
from sklearn.model_selection import TimeSeriesSplit
from sklearn.metrics import classification_report
import numpy as np
import matplotlib.pyplot as plt

# Гиперпараметры
WINDOW_SIZE = 7
EMBED_DIM = 64
NUM_HEADS = 4
BATCH_SIZE = 32
EPOCHS = 200
LEARNING_RATE = 1e-4
NUM_CLASSES = 3

# Генерация данных (замените на свои 137+ значений)
data = np.array([...])  # Ваши данные здесь

# 1. Расширенная аугментация временных рядов
def advanced_augmentation(series, num_aug=5):
    augmented = []
    for _ in range(num_aug):
        noise = np.random.normal(0, 0.02, size=series.shape)
        scaled = series * np.random.uniform(0.9, 1.1)
        augmented.append(series + noise)
        augmented.append(scaled)
    return np.concatenate([series] + augmented)

# 2. Временные преобразования и фичи
def create_time_features(data):
    features = []
    for i in range(len(data)):
        window = data[max(0,i-5):i+1]
        features.append([
            data[i],                               # Исходное значение
            np.mean(window),                      # SMA
            np.std(window),                       # Волатильность
            (data[i] - np.min(window)) / (np.max(window) - np.min(window) + 1e-7  # Относительная позиция
        ])
    return np.array(features)

# 3. Подготовка данных
augmented_data = advanced_augmentation(data)
processed_data = create_time_features(augmented_data)

# 4. Создание последовательностей с продвинутой логикой
def create_advanced_sequences(data, window_size):
    X, y = [], []
    for i in range(len(data)-window_size):
        seq = data[i:i+window_size]
        target = data[i+window_size][0]  # Прогнозируем исходное значение
        
        # Динамическая классификация
        avg = np.mean(seq[:,0])
        std = np.std(seq[:,0])
        threshold = 0.5*std
        
        if target > avg + threshold:
            label = 2  # Рост
        elif target < avg - threshold:
            label = 0  # Падение
        else:
            label = 1  # Стабильность
            
        X.append(seq)
        y.append(label)
    return np.array(X), np.array(y)

X, y = create_advanced_sequences(processed_data, WINDOW_SIZE)

# 5. Преобразование в тензоры PyTorch
X = torch.tensor(X, dtype=torch.float32)
y = torch.tensor(y, dtype=torch.long)

# 6. Современная архитектура модели
class TemporalTransformer(nn.Module):
    def __init__(self, input_dim, embed_dim, num_heads, num_classes, num_layers=2):
        super().__init__()
        self.embedding = nn.Linear(input_dim, embed_dim)
        self.positional_encoding = nn.Parameter(torch.zeros(1, WINDOW_SIZE, embed_dim))
        
        encoder_layer = nn.TransformerEncoderLayer(
            d_model=embed_dim,
            nhead=num_heads,
            dim_feedforward=embed_dim*4,
            dropout=0.1
        )
        self.transformer = nn.TransformerEncoder(encoder_layer, num_layers=num_layers)
        
        self.tcn = nn.Sequential(
            nn.Conv1d(embed_dim, embed_dim, kernel_size=3, padding=1),
            nn.ReLU(),
            nn.BatchNorm1d(embed_dim),
            nn.Conv1d(embed_dim, embed_dim, kernel_size=3, padding=1),
            nn.ReLU(),
            nn.BatchNorm1d(embed_dim)
        )
        
        self.classifier = nn.Sequential(
            nn.Linear(embed_dim, embed_dim//2),
            nn.ReLU(),
            nn.Linear(embed_dim//2, num_classes)
        )
    
    def forward(self, x):
        # Встраивание и позиционное кодирование
        x = self.embedding(x) + self.positional_encoding
        
        # Transformer Encoder
        x = x.permute(1, 0, 2)  # (seq_len, batch, features)
        x = self.transformer(x)
        x = x.permute(1, 2, 0)  # (batch, features, seq_len)
        
        # Temporal Convolution
        x = self.tcn(x)
        x = x.mean(dim=-1)  # Global Average Pooling
        
        # Классификация
        return self.classifier(x)

# 7. Focal Loss для дисбаланса классов
class FocalLoss(nn.Module):
    def __init__(self, alpha=0.25, gamma=2.0):
        super().__init__()
        self.alpha = alpha
        self.gamma = gamma

    def forward(self, inputs, targets):
        ce_loss = nn.functional.cross_entropy(inputs, targets, reduction='none')
        pt = torch.exp(-ce_loss)
        return (self.alpha * (1-pt)**self.gamma * ce_loss).mean()

# 8. Инициализация модели и оптимизатора
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = TemporalTransformer(
    input_dim=4,
    embed_dim=EMBED_DIM,
    num_heads=NUM_HEADS,
    num_classes=NUM_CLASSES
).to(device)

criterion = FocalLoss()
optimizer = optim.AdamW(model.parameters(), lr=LEARNING_RATE, weight_decay=1e-4)
scheduler = optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=EPOCHS)

# 9. Обучение с кросс-валидацией
tscv = TimeSeriesSplit(n_splits=5)
best_val_acc = 0

for fold, (train_idx, val_idx) in enumerate(tscv.split(X)):
    print(f"\nTraining Fold {fold+1}")
    
    X_train, X_val = X[train_idx].to(device), X[val_idx].to(device)
    y_train, y_val = y[train_idx].to(device), y[val_idx].to(device)
    
    train_dataset = TensorDataset(X_train, y_train)
    val_dataset = TensorDataset(X_val, y_val)
    
    train_loader = DataLoader(train_dataset, batch_size=BATCH_SIZE, shuffle=True)
    val_loader = DataLoader(val_dataset, batch_size=BATCH_SIZE)
    
    for epoch in range(EPOCHS):
        model.train()
        train_loss = 0.0
        for batch_X, batch_y in train_loader:
            optimizer.zero_grad()
            outputs = model(batch_X)
            loss = criterion(outputs, batch_y)
            loss.backward()
            optimizer.step()
            train_loss += loss.item()
        
        scheduler.step()
        
        # Валидация
        model.eval()
        val_loss = 0.0
        correct = 0
        with torch.no_grad():
            for batch_X, batch_y in val_loader:
                outputs = model(batch_X)
                val_loss += criterion(outputs, batch_y).item()
                preds = outputs.argmax(dim=1)
                correct += (preds == batch_y).sum().item()
        
        val_acc = correct / len(val_dataset)
        if val_acc > best_val_acc:
            torch.save(model.state_dict(), 'best_model.pth')
            best_val_acc = val_acc
        
        print(f"Epoch {epoch+1}/{EPOCHS} | Train Loss: {train_loss/len(train_loader):.4f} | Val Loss: {val_loss/len(val_loader):.4f} | Val Acc: {val_acc:.4f}")

# 10. Оценка модели
model.load_state_dict(torch.load('best_model.pth'))
model.eval()
with torch.no_grad():
    outputs = model(X.to(device))
    y_pred = outputs.argmax(dim=1).cpu().numpy()

print("Final Classification Report:")
print(classification_report(y.numpy(), y_pred, target_names=['Down', 'Neutral', 'Up']))

# 11. Визуализация
plt.figure(figsize=(15, 6))
plt.plot(y.numpy(), label='True')
plt.plot(y_pred, '--', alpha=0.7, label='Predicted')
plt.title('True vs Predicted Labels')
plt.legend()
plt.show()