Регистрация | Вход
import torchimport torch.nn as nnimport torch.optim as optimimport torchvisionfrom torchvision import transformsimport time# === 1. Загрузка MNIST ===transform = transforms.Compose([ transforms.ToTensor(), transforms.Normalize((0.1307,), (0.3081,)), # нормализация MNIST transforms.Lambda(lambda x: x.view(-1)) # 28x28 → 784])train_dataset = torchvision.datasets.MNIST( root="./data", train=True, download=True, transform=transform)test_dataset = torchvision.datasets.MNIST( root="./data", train=False, download=True, transform=transform)# Используем DataLoader для стабильной итерации и шифлаtrain_loader = torch.utils.data.DataLoader(train_dataset, batch_size=64, shuffle=True)test_loader = torch.utils.data.DataLoader(test_dataset, batch_size=1000, shuffle=False)# === 2. Конфигурация сети ===class MLP(nn.Module): def __init__(self): super().__init__() self.net = nn.Sequential( nn.Linear(784, 512), nn.ReLU(), nn.Dropout(0.2), nn.Linear(512, 256), nn.ReLU(), nn.Dropout(0.2), nn.Linear(256, 10) ) def forward(self, x): return self.net(x)# === 3. Настройки ===device = torch.device("cuda" if torch.cuda.is_available() else "cpu")model = MLP().to(device)# Adam вместо SGDoptimizer = optim.Adam(model.parameters(), lr=1e-3)criterion = nn.CrossEntropyLoss()# === 4. Обучение ===print("Training started...")start = time.time()epochs = 50 for epoch in range(epochs): model.train() total_loss = 0 for xb, yb in train_loader: xb, yb = xb.to(device), yb.to(device) optimizer.zero_grad() preds = model(xb) loss = criterion(preds, yb) loss.backward() optimizer.step() total_loss += loss.item() # === Оценка на тесте === model.eval() correct = 0 total = 0 with torch.no_grad(): for xb, yb in test_loader: xb, yb = xb.to(device), yb.to(device) preds = model(xb) correct += (preds.argmax(dim=1) == yb).sum().item() total += yb.size(0) acc = correct / total print(f"Epoch {epoch+1}/{epochs} | Loss: {total_loss/len(train_loader):.4f} | Test Accuracy: {acc*100:.2f}%")end = time.time()print(f"\nTraining time: {end - start:.2f} seconds")print("Done!")
import torchimport torch.nn as nnimport torch.optim as optimimport torchvisionfrom torchvision import transformsimport time# === 1. Загрузка MNIST ===transform = transforms.Compose([ transforms.ToTensor(), transforms.Normalize((0.1307,), (0.3081,)), # нормализация transforms.Lambda(lambda x: x.view(-1)) # 28x28 → 784])train_dataset = torchvision.datasets.MNIST( root="./data", train=True, download=True, transform=transform)test_dataset = torchvision.datasets.MNIST( root="./data", train=False, download=True, transform=transform)learn_inputs = torch.stack([x for x, _ in train_dataset])learn_labels = torch.tensor([y for _, y in train_dataset]).long()test_inputs = torch.stack([x for x, _ in test_dataset])test_labels = torch.tensor([y for _, y in test_dataset]).long()# === 2. Определение модели ===class MLP(nn.Module): def __init__(self): super().__init__() self.net = nn.Sequential( nn.Linear(784, 128), nn.ReLU(), nn.Linear(128, 64), nn.ReLU(), nn.Linear(64, 10) ) def forward(self, x): return self.net(x)# === 3. Настройки ===device = torch.device("cuda" if torch.cuda.is_available() else "cpu")num_models = 50epochs = 15batch_size = 64# === 4. Обучение ансамбля ===ensemble = []start_time = time.time()print(f"Training {num_models} models...")for m in range(num_models): model = MLP().to(device) optimizer = optim.SGD(model.parameters(), lr=0.1) criterion = nn.CrossEntropyLoss() for epoch in range(epochs): perm = torch.randperm(len(learn_inputs)) inputs = learn_inputs[perm] labels = learn_labels[perm] for i in range(0, len(inputs), batch_size): xb = inputs[i:i+batch_size].to(device) yb = labels[i:i+batch_size].to(device) optimizer.zero_grad() preds = model(xb) loss = criterion(preds, yb) loss.backward() optimizer.step() # уменьшение lr for g in optimizer.param_groups: g['lr'] *= 0.95 ensemble.append(model) print(f"Model {m+1}/{num_models} trained.")end_time = time.time()# === 5. Усреднение предсказаний ансамбля ===print("\nEvaluating ensemble...")with torch.no_grad(): all_preds = torch.zeros((len(test_inputs), 10), device=device) for model in ensemble: preds = model(test_inputs.to(device)) all_preds += torch.softmax(preds, dim=1) all_preds /= num_models # усреднение вероятностей acc = (all_preds.argmax(dim=1) == test_labels.to(device)).float().mean().item()print(f"\nEnsemble Accuracy: {acc*100:.2f}%")print(f"Total training time: {end_time - start_time:.2f} seconds")print("Done!")