“python -m experiments.cifar10_test“是什么意思

Python命令行模式:-m选项与模块导入实践

具体解释如下:

  • "python" 是运行 Python 解释器的命令。
  • "-m" 是一个选项,用于指定要运行的模块。
  • "experiments.cifar10_test" 是要运行的 Python 模块的名称。

其中

 

虽说main.py文件在上一级目录中,仍然可以在这个文件里直接import main,然后使用main.py文件

一、实验内容: (1)掌握LeNet、AlexNet、VGG、ResNet等经典CNN模型的核心架构思想,并使用PyTorch构建这些模型。 (2)通过在同一数据集(系统自带CIFAR-10数据集(10类,32×32彩色图像)和自定义猫狗数据集)上训练不同经典CNN模型,系统分析其参数量、计算效率、准确率等性能指标,理解各模型的优缺点。 (3)学会针对不同模型选择合适的优化策略(SGD、Adam),并能根据具体应用场景(如精度要求、资源限制)选择合适的模型。 二、代码示例: # 实验环境: import torch import torch.nn as nn import torch.optim as optim from torch.optim import lr_scheduler import torchvision import torchvision.transforms as transforms from torchsummary import summary import numpy as np import matplotlib.pyplot as plt import time from collections import OrderedDict import copy device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") print(f"Using device: {device}") # 数据集:CIFAR-1010类,32×32彩色图像) # 数据预处理与增强: transform_train = transforms.Compose([ transforms.RandomCrop(32, padding=4), transforms.RandomHorizontalFlip(), transforms.ToTensor(), transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010)) ]) transform_test = transforms.Compose([ transforms.ToTensor(), transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010)) ]) trainset = torchvision.datasets.CIFAR10(root='./data', train=True, download=True, transform=transform_train) testset = torchvision.datasets.CIFAR10(root='./data', train=False, download=True, transform=transform_test) trainloader = torch.utils.data.DataLoader(trainset, batch_size=128, shuffle=True, num_workers=2) testloader = torch.utils.data.DataLoader(testset, batch_size=100, shuffle=False, num_workers=2) # 三种经典CNN模型 # 1 LeNet-5(适配CIFAR-10) class LeNet(nn.Module): def __init__(self, num_classes=10): super(LeNet, self).__init__() self.features = nn.Sequential( nn.Conv2d(3, 6, kernel_size=5), # 3@32x32 -> 6@28x28 nn.ReLU(inplace=True), nn.MaxPool2d(kernel_size=2), # 6@28x28 -> 6@14x14 nn.Conv2d(6, 16, kernel_size=5), # 6@14x14 -> 16@10x10 nn.ReLU(inplace=True), nn.MaxPool2d(kernel_size=2) # 16@10x10 -> 16@5x5 ) self.classifier = nn.Sequential( nn.Linear(16 * 5 * 5, 120), nn.ReLU(inplace=True), nn.Linear(120, 84), nn.ReLU(inplace=True), nn.Linear(84, num_classes) ) def forward(self, x): x = self.features(x) x = torch.flatten(x, 1) x = self.classifier(x) return x # 2 AlexNet(简化版适配CIFAR-10) class AlexNet(nn.Module): def __init__(self, num_classes=10, dropout=0.5): super(AlexNet, self).__init__() self.features = nn.Sequential( nn.Conv2d(3, 64, kernel_size=3, stride=2, padding=1), # 3@32x32 -> 64@16x16 nn.ReLU(inplace=True), nn.MaxPool2d(kernel_size=2), # 64@16x16 -> 64@8x8 nn.Conv2d(64, 192, kernel_size=3, padding=1), # 64@8x8 -> 192@8x8 nn.ReLU(inplace=True), nn.MaxPool2d(kernel_size=2), # 192@8x8 -> 192@4x4 nn.Conv2d(192, 384, kernel_size=3, padding=1), # 192@4x4 -> 384@4x4 nn.ReLU(inplace=True), nn.Conv2d(384, 256, kernel_size=3, padding=1), # 384@4x4 -> 256@4x4 nn.ReLU(inplace=True), nn.Conv2d(256, 256, kernel_size=3, padding=1), # 256@4x4 -> 256@4x4 nn.ReLU(inplace=True), nn.MaxPool2d(kernel_size=2) # 256@4x4 -> 256@2x2 ) self.classifier = nn.Sequential( nn.Dropout(p=dropout), nn.Linear(256 * 2 * 2, 4096), nn.ReLU(inplace=True), nn.Dropout(p=dropout), nn.Linear(4096, 4096), nn.ReLU(inplace=True), nn.Linear(4096, num_classes), ) def forward(self, x): x = self.features(x) x = torch.flatten(x, 1) x = self.classifier(x) return x # 3 VGG-11(简化版) class VGG11(nn.Module): def __init__(self, num_classes=10, dropout=0.5): super(VGG11, self).__init__() self.features = self._make_layers() self.avgpool = nn.AdaptiveAvgPool2d((7, 7)) self.classifier = nn.Sequential( nn.Linear(512 * 7 * 7, 4096), nn.ReLU(True), nn.Dropout(p=dropout), nn.Linear(4096, 4096), nn.ReLU(True), nn.Dropout(p=dropout), nn.Linear(4096, num_classes), ) def forward(self, x): x = self.features(x) x = self.avgpool(x) x = torch.flatten(x, 1) x = self.classifier(x) return x def _make_layers(self): layers = [] in_channels = 3 cfg = [64, 'M', 128, 'M', 256, 256, 'M', 512, 512, 'M', 512, 512, 'M'] for v in cfg: if v == 'M': layers += [nn.MaxPool2d(kernel_size=2, stride=2)] else: layers += [nn.Conv2d(in_channels, v, kernel_size=3, padding=1), nn.BatchNorm2d(v), nn.ReLU(inplace=True)] in_channels = v return nn.Sequential(*layers) # 模型分析对比 def analyze_model(model, model_name): print(f"\n=== {model_name} 模型分析 ===") # 参数量统计 total_params = sum(p.numel() for p in model.parameters()) trainable_params = sum(p.numel() for p in model.parameters() if p.requires_grad) print(f"总参数量: {total_params:,}") print(f"可训练参数量: {trainable_params:,}") # 模型结构概览 summary(model.to(device), (3, 32, 32)) return total_params # 分析三个模型 models = { "LeNet": LeNet(), "AlexNet": AlexNet(), "VGG-11": VGG11() } param_counts = {} for name, model in models.items(): param_counts[name] = analyze_model(model, name) # 统一训练框架 def train_model(model, trainloader, testloader, criterion, optimizer, scheduler, num_epochs=50, model_name='model'): model = model.to(device) best_acc = 0.0 history = {'train_loss': [], 'train_acc': [], 'val_loss': [], 'val_acc': []} for epoch in range(num_epochs): # 训练阶段 model.train() running_loss = 0.0 running_corrects = 0 for inputs, labels in trainloader: inputs, labels = inputs.to(device), labels.to(device) optimizer.zero_grad() outputs = model(inputs) loss = criterion(outputs, labels) loss.backward() optimizer.step() _, preds = torch.max(outputs, 1) running_loss += loss.item() * inputs.size(0) running_corrects += torch.sum(preds == labels.data) if scheduler: scheduler.step() epoch_loss = running_loss / len(trainloader.dataset) epoch_acc = running_corrects.double() / len(trainloader.dataset) history['train_loss'].append(epoch_loss) history['train_acc'].append(epoch_acc.item()) # 验证阶段 model.eval() val_loss = 0.0 val_corrects = 0 with torch.no_grad(): for inputs, labels in testloader: inputs, labels = inputs.to(device), labels.to(device) outputs = model(inputs) loss = criterion(outputs, labels) _, preds = torch.max(outputs, 1) val_loss += loss.item() * inputs.size(0) val_corrects += torch.sum(preds == labels.data) val_loss = val_loss / len(testloader.dataset) val_acc = val_corrects.double() / len(testloader.dataset) history['val_loss'].append(val_loss) history['val_acc'].append(val_acc.item()) if val_acc > best_acc: best_acc = val_acc best_model_wts = copy.deepcopy(model.state_dict()) if epoch % 10 == 0: print(f'Epoch {epoch:2d}: Train Loss: {epoch_loss:.4f} Acc: {epoch_acc:.4f} | Val Loss: {val_loss:.4f} Acc: {val_acc:.4f}') model.load_state_dict(best_model_wts) return model, history, best_acc # 不同优化策略实验 def experiment_with_optimizers(model_class, model_name): print(f"\n=== 优化器对比实验: {model_name} ===") results = {} # 实验1: Adam优化器 model = model_class().to(device) criterion = nn.CrossEntropyLoss() optimizer = optim.Adam(model.parameters(), lr=0.001, weight_decay=5e-4) scheduler = lr_scheduler.StepLR(optimizer, step_size=30, gamma=0.1) model_trained, history, best_acc = train_model( model, trainloader, testloader, criterion, optimizer, scheduler, num_epochs=50, model_name=f"{model_name}_Adam" ) results['Adam'] = {'history': history, 'best_acc': best_acc} # 实验2: SGD with Momentum model = model_class().to(device) optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.9, weight_decay=5e-4) scheduler = lr_scheduler.StepLR(optimizer, step_size=30, gamma=0.1) model_trained, history, best_acc = train_model( model, trainloader, testloader, criterion, optimizer, scheduler, num_epochs=50, model_name=f"{model_name}_SGD" ) results['SGD'] = {'history': history, 'best_acc': best_acc} return results # 对每个模型进行优化器对比 optimizer_results = {} for name, model_class in [('LeNet', LeNet), ('AlexNet', AlexNet), ('VGG-11', VGG11)]: optimizer_results[name] = experiment_with_optimizers(model_class, name) # 结果可视化与分析 def plot_comparison(results_dict, title): plt.figure(figsize=(15, 10)) # 准确率对比 plt.subplot(2, 2, 1) for model_name, optimizers in results_dict.items(): for opt_name, result in optimizers.items(): plt.plot(result['history']['val_acc'], label=f'{model_name}_{opt_name}', alpha=0.7) plt.title('Validation Accuracy Comparison') plt.xlabel('Epoch') plt.ylabel('Accuracy') plt.legend() # 参数量 vs 最佳准确率 plt.subplot(2, 2, 2) model_names = [] best_accs = [] params = [] for model_name in results_dict.keys(): best_acc = max([r['best_acc'] for r in results_dict[model_name].values()]) model_names.append(model_name) best_accs.append(best_acc.cpu().numpy()) params.append(param_counts[model_name]) plt.scatter(params, best_accs) for i, txt in enumerate(model_names): plt.annotate(txt, (params[i], best_accs[i])) plt.xscale('log') plt.title('Model Size vs Best Accuracy') plt.xlabel('Parameters (log scale)') plt.ylabel('Best Accuracy') plt.tight_layout() plt.show() plot_comparison(optimizer_results, 'Model Comparison') 三、实验结果与分析 1. 自定义增加 ResNet等至少一个经典CNN模型进行对比分析。 2. 至少构造一个自定义数据集(比如猫狗数据集)进行实战。 3. 针对所实验的经典CNN模型从参数量、准备率、优缺点、训练时间等角度进行对比分析。 4. 根据实验训练情况对比分析SGD,Adam优化器。 5. 适当调整学习率、批次大小、运用Dropout、BN等策略,分析其性能影响。
10-10
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值