[pytorch] 利用Alexnet训练cifar10

论文地址:ImageNet Classification with Deep Convolutional Neural Networks
Alexnet的网络结构如图所示
Alexnet结构
cifar10数据集一共包含10个类别的RGB彩色图像,每个类别分别有6000张,共60000张大小为32x32的图片。其中50000个作为训练集,10000个作为测试集。
cifar10数据集
代码如下:
注意这里将cifar10图片上采样为224*224,以接近原始版本Alexnet;输出类别由1000修改为10。

# 导入模块
import torch
from torch import nn, optim
from torch.utils.data import DataLoader
from torchvision import datasets, transforms, models
from torchvision.transforms.functional import InterpolationMode
import random
import matplotlib.pyplot as plt

# 下载以及转换cifar10
transform = transforms.Compose([transforms.Resize((224, 224), interpolation=InterpolationMode.BICUBIC),
                                transforms.ToTensor(),
                                transforms.Normalize(mean=[0.4914, 0.4822, 0.4465], std=[0.247, 0.2435, 0.2616]) # 此为训练集上的均值与方差
                                ])
train_images = datasets.CIFAR10('./', train=True, download=True, transform=transform)
test_images = datasets.CIFAR10('./', train=False, download=True, transform=transform)

# batch size设置为256
train_data = DataLoader(train_images, batch_size=256, shuffle=True, num_workers=2)
test_data = DataLoader(test_images, batch_size=256, num_workers=2)

# Alexnet
class Model(nn.Module):
  def __init__(self):
    super().__init__()
    self.net = nn.Sequential(nn.Conv2d(3, 96, kernel_size=11, stride=4, padding=1), nn.ReLU(),
                             nn.MaxPool2d(kernel_size=3, stride=2), 
                             nn.Conv2d(96, 256, kernel_size=5, padding=2), nn.ReLU(),
                             nn.MaxPool2d(kernel_size=3, stride=2),
                             nn.Conv2d(256, 384, kernel_size=3, padding=1), nn.ReLU(),
                             nn.Conv2d(384, 384, kernel_size=3, padding=1), nn.ReLU(),
                             nn.Conv2d(384, 256, kernel_size=3, padding=1), nn.ReLU(),
                             nn.MaxPool2d(kernel_size=3, stride=2),
                             nn.Flatten(), nn.Linear(256*5*5, 4096), nn.ReLU(),
                             nn.Dropout(0.5),
                             nn.Linear(4096, 4096), nn.ReLU(),
                             nn.Dropout(0.5),
                             nn.Linear(4096, 10))
    
  def forward(self, X):
    return self.net(X)

# 参数初始化
def initial(layer):
  if isinstance(layer, nn.Linear) or isinstance(layer, nn.Conv2d):
    nn.init.xavier_normal_(layer.weight.data)


device = torch.device('cuda') if torch.cuda.is_available() else torch.device('cpu')
net = Model().to(device)
net.apply(initial)

epochs = 17 # 随便设置的epoch
lr = 0.01	# 学习率
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(), lr=lr, momentum=0.9, weight_decay=0.0005)

# 训练与测试
train_loss, test_loss, train_acc, test_acc = [], [], [], [] # 用来记录每个epoch的训练、测试误差以及准确率
for i in range(epochs):
  # 训练
  net.train()
  temp_loss, temp_correct = 0, 0
  for X, y in train_data:
    X = X.to(device)
    y = y.to(device)
    y_hat = net(X)
    loss = criterion(y_hat, y)
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()

    # 计算每次loss与预测正确的个数
    label_hat = torch.argmax(y_hat, dim=1)
    temp_correct += (label_hat == y).sum()
    temp_loss += loss

  print(f'epoch:{i+1}  train loss:{temp_loss/len(train_data):.3f}, train Aacc:{temp_correct/50000*100:.2f}%', end='\t')
  train_loss.append((temp_loss/len(train_data)).item())
  train_acc.append((temp_correct/50000).item())

  # 测试
  temp_loss, temp_correct = 0, 0
  net.eval()
  with torch.no_grad():
    for X, y in test_data:
      X = X.to(device)
      y = y.to(device)
      y_hat = net(X)
      loss = criterion(y_hat, y)

      label_hat = torch.argmax(y_hat, dim=1)
      temp_correct += (label_hat == y).sum()
      temp_loss += loss

    print(f'test loss:{temp_loss/len(test_data):.3f}, test acc:{temp_correct/10000*100:.2f}%')
    test_loss.append((temp_loss/len(test_data)).item())
    test_acc.append((temp_correct/10000).item())

输出为:

epoch:1  train loss:1.791, train Aacc:33.77%	test loss:1.544, test acc:44.03%
epoch:2  train loss:1.285, train Aacc:53.90%	test loss:1.144, test acc:60.33%
epoch:3  train loss:1.009, train Aacc:64.55%	test loss:0.882, test acc:69.84%
epoch:4  train loss:0.839, train Aacc:70.70%	test loss:0.807, test acc:72.48%
epoch:5  train loss:0.701, train Aacc:75.82%	test loss:0.727, test acc:75.22%
epoch:6  train loss:0.618, train Aacc:78.51%	test loss:0.660, test acc:77.59%
epoch:7  train loss:0.529, train Aacc:81.80%	test loss:0.639, test acc:77.91%
epoch:8  train loss:0.446, train Aacc:84.68%	test loss:0.667, test acc:78.64%
epoch:9  train loss:0.383, train Aacc:86.66%	test loss:0.591, test acc:80.92%
epoch:10  train loss:0.328, train Aacc:88.60%	test loss:0.621, test acc:80.45%
epoch:11  train loss:0.266, train Aacc:90.57%	test loss:0.632, test acc:81.27%
epoch:12  train loss:0.211, train Aacc:92.75%	test loss:0.629, test acc:82.48%
epoch:13  train loss:0.178, train Aacc:93.75%	test loss:0.655, test acc:81.68%
epoch:14  train loss:0.142, train Aacc:95.10%	test loss:0.648, test acc:82.74%
epoch:15  train loss:0.130, train Aacc:95.39%	test loss:0.726, test acc:83.01%
epoch:16  train loss:0.100, train Aacc:96.57%	test loss:0.831, test acc:81.86%
epoch:17  train loss:0.090, train Aacc:96.89%	test loss:0.688, test acc:82.73%

训练与测试曲线如下:
训练与测试曲线

最后我们可视化一下模型预测的性能,我们在测试集上随机挑选12张图片输入网络进行预测。

plt.figure(figsize=(16, 14))
for i in range(12):
  img_data, label_id = random.choice(list(zip(test_images.data, test_images.targets)))
  img = transforms.ToPILImage()(img_data)
  predict_id = torch.argmax(net(transform(img).unsqueeze(0).to(device)))
  predict = test_images.classes[predict_id]
  label = test_images.classes[label_id]
  plt.subplot(3, 4, i+1)
  plt.imshow(img)
  plt.title(f'truth:{label}\npredict:{predict}')

输出如下:
truth-predict

  • 9
    点赞
  • 61
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
好的,以下是使用PyTorch框架构建AlexNet模型并对CIFAR-10数据集进行训练,最后生成epoch图的代码示例: ```python import torch import torch.nn as nn import torch.optim as optim import torchvision import torchvision.transforms as transforms import matplotlib.pyplot as plt # 构建AlexNet模型 class AlexNet(nn.Module): def __init__(self, num_classes=10): super(AlexNet, self).__init__() self.features = nn.Sequential( nn.Conv2d(3, 64, kernel_size=11, stride=4, padding=2), nn.ReLU(inplace=True), nn.MaxPool2d(kernel_size=3, stride=2), nn.Conv2d(64, 192, kernel_size=5, padding=2), nn.ReLU(inplace=True), nn.MaxPool2d(kernel_size=3, stride=2), nn.Conv2d(192, 384, kernel_size=3, padding=1), nn.ReLU(inplace=True), nn.Conv2d(384, 256, kernel_size=3, padding=1), nn.ReLU(inplace=True), nn.Conv2d(256, 256, kernel_size=3, padding=1), nn.ReLU(inplace=True), nn.MaxPool2d(kernel_size=3, stride=2), ) self.avgpool = nn.AdaptiveAvgPool2d((6, 6)) self.classifier = nn.Sequential( nn.Dropout(), nn.Linear(256 * 6 * 6, 4096), nn.ReLU(inplace=True), nn.Dropout(), nn.Linear(4096, 4096), nn.ReLU(inplace=True), 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 # 准备数据集 transform_train = transforms.Compose([ transforms.RandomCrop(32, padding=4), transforms.RandomHorizontalFlip(), transforms.ToTensor(), transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)) ]) transform_test = transforms.Compose([ transforms.ToTensor(), transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)) ]) trainset = torchvision.datasets.CIFAR10(root='./data', train=True, download=True, transform=transform_train) trainloader = torch.utils.data.DataLoader(trainset, batch_size=128, shuffle=True, num_workers=2) testset = torchvision.datasets.CIFAR10(root='./data', train=False, download=True, transform=transform_test) testloader = torch.utils.data.DataLoader(testset, batch_size=100, shuffle=False, num_workers=2) # 训练模型 device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") net = AlexNet().to(device) criterion = nn.CrossEntropyLoss() optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9) train_loss_list = [] train_acc_list = [] test_loss_list = [] test_acc_list = [] for epoch in range(10): running_loss = 0.0 train_acc = 0 test_acc = 0 for i, data in enumerate(trainloader, 0): inputs, labels = data[0].to(device), data[1].to(device) optimizer.zero_grad() outputs = net(inputs) loss = criterion(outputs, labels) loss.backward() optimizer.step() running_loss += loss.item() _, predicted = torch.max(outputs.data, 1) train_acc += (predicted == labels).sum().item() train_loss = running_loss / len(trainloader) train_accuracy = 100 * train_acc / len(trainset) train_loss_list.append(train_loss) train_acc_list.append(train_accuracy) print('Epoch %d: Train Loss: %.3f, Train Accuracy: %.3f%%' % (epoch+1, train_loss, train_accuracy)) with torch.no_grad(): running_loss = 0.0 for i, data in enumerate(testloader, 0): inputs, labels = data[0].to(device), data[1].to(device) outputs = net(inputs) loss = criterion(outputs, labels) running_loss += loss.item() _, predicted = torch.max(outputs.data, 1) test_acc += (predicted == labels).sum().item() test_loss = running_loss / len(testloader) test_accuracy = 100 * test_acc / len(testset) test_loss_list.append(test_loss) test_acc_list.append(test_accuracy) print('Epoch %d: Test Loss: %.3f, Test Accuracy: %.3f%%' % (epoch+1, test_loss, test_accuracy)) # 生成epoch图 plt.plot(range(1, 11), train_loss_list, label='Train Loss') plt.plot(range(1, 11), test_loss_list, label='Test Loss') plt.xlabel('Epoch') plt.ylabel('Loss') plt.legend() plt.show() plt.plot(range(1, 11), train_acc_list, label='Train Accuracy') plt.plot(range(1, 11), test_acc_list, label='Test Accuracy') plt.xlabel('Epoch') plt.ylabel('Accuracy (%)') plt.legend() plt.show() ``` 在上面的示例中,我们使用PyTorch框架构建了一个AlexNet模型,并使用CIFAR-10数据集对其进行训练。在训练过程中,我们记录了每个epoch的训练损失和准确率,并在训练结束后使用matplotlib库生成了两个图表,分别表示训练损失和准确率随epoch的变化情况。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值