完整教程:【无标题】
Day45
# 在data_loader.py中增强数据预处理def create_data_loaders(data_dir, batch_size, img_size): # 训练集增强:随机裁剪、翻转、旋转、亮度调整等 train_transform = transforms.Compose([ transforms.RandomResizedCrop(img_size), transforms.RandomHorizontalFlip(), transforms.RandomRotation(10), transforms.ColorJitter(brightness=0.2, contrast=0.2), transforms.ToTensor(), transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]) # ImageNet标准 ]) # 测试集只需调整大小和标准化 test_transform = transforms.Compose([ transforms.Resize((img_size, img_size)), transforms.ToTensor(), transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]) ]) # 加载数据集 train_dataset = datasets.ImageFolder(os.path.join(data_dir, 'train'), transform=train_transform) test_dataset = datasets.ImageFolder(os.path.join(data_dir, 'test'), transform=test_transform) # 创建数据加载器 train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True, num_workers=4) test_loader = DataLoader(test_dataset, batch_size=batch_size, shuffle=False, num_workers=4) return train_loader, test_loader, train_dataset.classes # 在train.py中添加早停和学习率调度def train_model(model, train_loader, test_loader, criterion, optimizer, num_epochs, device): best_acc = 0.0 best_model_weights = copy.deepcopy(model.state_dict()) early_stop_counter = 0 early_stop_patience = 5 # 如果5个epoch没有提升,则停止训练 # 学习率调度器:当验证集准确率停滞时,降低学习率 scheduler = optim.lr_scheduler.ReduceLROnPlateau( optimizer, mode='max', factor=0.5, patience=2, verbose=True ) for epoch in range(num_epochs): # 训练阶段 model.train() running_loss = 0.0 correct = 0 total = 0 for batch_idx, (inputs, targets) in enumerate(train_loader): inputs, targets = inputs.to(device), targets.to(device) optimizer.zero_grad() outputs = model(inputs) loss = criterion(outputs, targets) loss.backward() optimizer.step() running_loss += loss.item() _, predicted = outputs.max(1) total += targets.size(0) correct += predicted.eq(targets).sum().item() if (batch_idx + 1) % 100 == 0: print(f'Epoch: {epoch+1}/{num_epochs} | Batch: {batch_idx+1}/{len(train_loader)} ' f'| 单Batch损失: {loss.item():.4f} | 累计平均损失: {running_loss/(batch_idx+1):.4f}') train_loss = running_loss / len(train_loader) train_acc = 100. * correct / total print(f'Epoch {epoch+1}/{num_epochs} | 训练准确率: {train_acc:.2f}%') # 验证阶段 model.eval() test_loss = 0 correct = 0 total = 0 with torch.no_grad(): for inputs, targets in test_loader: inputs, targets = inputs.to(device), targets.to(device) outputs = model(inputs) loss = criterion(outputs, targets) test_loss += loss.item() _, predicted = outputs.max(1) total += targets.size(0) correct += predicted.eq(targets).sum().item() test_acc = 100. * correct / total print(f'Epoch {epoch+1}/{num_epochs} | 测试准确率: {test_acc:.2f}%') # 更新学习率 scheduler.step(test_acc) # 保存最佳模型 if test_acc > best_acc: best_acc = test_acc best_model_weights = copy.deepcopy(model.state_dict()) torch.save(best_model_weights, 'best_model.pth') early_stop_counter = 0 print("已保存最佳模型") else: early_stop_counter += 1 print(f"早停计数器: {early_stop_counter}/{early_stop_patience}") # 早停检查 if early_stop_counter >= early_stop_patience: print(f"早停: 在{early_stop_patience}个epoch内验证集准确率没有提升") break # 加载最佳模型 model.load_state_dict(best_model_weights) return model # 在main.py中调整优化器参数# 定义损失函数和优化器,添加L2正则化criterion = nn.CrossEntropyLoss()optimizer = optim.Adam(model.parameters(), lr=learning_rate, weight_decay=1e-5) # 添加L2正则化

浙公网安备 33010602011771号