ToB企服应用市场:ToB评测及商务社交产业平台

标题: Pytorch实现图像分类-水果数据集分类--深度学习大作业 [打印本页]

作者: 前进之路    时间: 2024-7-26 12:56
标题: Pytorch实现图像分类-水果数据集分类--深度学习大作业
目次
1.概述 
2.计划
3.实现
4.实验 

5.总结


1.概述 

本次深度学习大作业,我利用AlexNet模子对"Fruits-360"数据会合的两部门水果和蔬菜图片举行分类
2.计划

模子计划:Alexnet网络

由于输入图像数据为RGB图像,在模子的计划时调整,并在计划全连接层时引入了动态尺寸计算方法,保证了模子的通用性和顺应性。
3.实现

 代码如下:
  1. import torch
  2. import torch.nn as nn
  3. import torchvision
  4. import torchvision.transforms as transforms
  5. from torch.utils.data import DataLoader
  6. import torch.nn.functional as F
  7. from torch import nn, optim
  8. # 数据预处理
  9. image_size = (224, 224)
  10. data_transforms = transforms.Compose([
  11.     transforms.RandomHorizontalFlip(),
  12.     transforms.Resize(image_size),
  13.     transforms.ToTensor(),
  14.     transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]),
  15. ])
  16. #导入数据集
  17. import torchvision.datasets as datasets
  18. train_data=datasets.ImageFolder (root='fruits-360-original-size/fruits-360-original-size/Training',transform=data_transforms)
  19. test_data=datasets.ImageFolder (root='fruits-360-original-size/fruits-360-original-size/Test',transform=data_transforms)
  20. # print(train_data.classes)
  21. # print('..............')
  22. # print(test_data.classes)
  23. #DataLoader
  24. batchsize=10#每个批次(batch)中包含的样本数量
  25. train_loader = DataLoader(train_data, batch_size=batchsize, shuffle=True, num_workers=1)
  26. test_loader = DataLoader(test_data, batch_size=batchsize, shuffle=False, num_workers=1)  # 测试时不需打乱数据
  27. #创建模型
  28. class AlexNet(nn.Module):
  29.     def __init__(self):
  30.         super(AlexNet, self).__init__()
  31.         self.conv = nn.Sequential(
  32.             nn.Conv2d(3, 96, 5, 1, 2),#输入通道数,输出通道数,卷积核大小,步长,填充(!!!rgb图像所以是三个通道,开始没注意以为灰度图像)
  33.             nn.ReLU(),
  34.             nn.MaxPool2d(3, 2),
  35.             nn.Conv2d(96, 256, 5, 1, 2),
  36.             nn.ReLU(),
  37.             nn.MaxPool2d(3, 2),
  38.             nn.Conv2d(256, 384, 3, 1, 1),
  39.             nn.ReLU(),
  40.             nn.Conv2d(384, 384, 3, 1, 1),
  41.             nn.ReLU(),
  42.             nn.Conv2d(384, 256, 3, 1, 1),
  43.             nn.ReLU(),
  44.             nn.MaxPool2d(3, 2)
  45.         )
  46.         # 计算全连接层输入大小
  47.         self.fc_input_size = self._get_fc_input_size()
  48.         self.fc = nn.Sequential(
  49.             nn.Linear(self.fc_input_size, 4096),
  50.             nn.ReLU(),
  51.             nn.Dropout(0.5),#随机丢弃
  52.             nn.Linear(4096, 4096),
  53.             nn.ReLU(),
  54.             nn.Dropout(0.5),
  55.             nn.Linear(4096, 2)#修改为2因为输出只有两个类
  56.         )
  57.     def forward(self, img):
  58.         # 通过卷积层前向传播,img是输入图像张量
  59.         feature = self.conv(img)
  60.         feature = feature.view(img.size(0), -1)#展平
  61.         # 通过全连接层(fc)进行前向传播,得到最终的输出
  62.         output = self.fc(feature)
  63.         return output
  64.    
  65.     #动态计算全连接层(FC层)所需要的输入尺寸
  66.     def _get_fc_input_size(self):
  67.         # 创建一个与训练/测试时相同尺寸和通道数的随机张量,用于通过卷积层
  68.         x = torch.randn(1, 3, image_size[0], image_size[1])# 其中3对应RGB图像的通道数,image_size是从外部传入的图像预处理后的尺寸,默认为(224, 224)
  69.         x = self.conv(x)
  70.         return x.view(-1).size(0)#展平后的向量长度
  71. # 实例化模型、损失函数和优化器
  72. model = AlexNet().to(device="cuda" if torch.cuda.is_available() else "cpu")
  73. criterion = nn.CrossEntropyLoss()
  74. optimizer = optim.SGD(model.parameters(), lr=0.001, momentum=0.9)
  75. # 训练函数
  76. def train(model, device, train_loader, optimizer, criterion):
  77.     model.train()
  78.     # 遍历训练数据加载器中的每个批次
  79.     for batch_idx, (data, target) in enumerate(train_loader):
  80.         data, target = data.to(device), target.to(device)#这样更快
  81.         # 梯度清零,防止梯度累积
  82.         optimizer.zero_grad()
  83.         output = model(data)#预测输出
  84.    
  85.         loss = criterion(output, target)
  86.         loss.backward()
  87.         optimizer.step()
  88.         # 每10个batch打印一次训练信息
  89.         if (batch_idx + 1) % 10 == 0 or (batch_idx + 1) == len(train_loader):
  90.             print(f'训练轮次: {epoch + 1}/{num_epochs} 损失: {loss.item():.6f}')
  91. # 测试函数
  92. def test(model, device, test_loader):
  93.     model.eval()
  94.     test_loss = 0
  95.     correct = 0
  96.     #避免在测试过程中计算和存储梯度,节省内存并加速计算
  97.     with torch.no_grad():
  98.         for data, target in test_loader:
  99.             data, target = data.to(device), target.to(device)
  100.             output = model(data)
  101.             test_loss += criterion(output, target).item()  # 累加批次损失
  102.             pred = output.argmax(dim=1, keepdim=True)  # 获取预测概率最大的类别索引
  103.             correct += pred.eq(target.view_as(pred)).sum().item()#累加预测正确的数量
  104.     test_loss /= len(test_loader.dataset)  # 平均损失
  105.     # 打印测试结果,包括平均损失、正确预测的总数、总样本数以及准确率
  106.     print(f'\n测试集: 平均损失: {test_loss:.6f}, 正确: {correct}/{len(test_loader.dataset)} ({100. * correct / len(test_loader.dataset):.2f}%)\n')
  107. # 主训练循环
  108. num_epochs = 10  # 设置训练轮数
  109. device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
  110. model.to(device)
  111. for epoch in range(num_epochs):
  112.     print(f'第{epoch + 1}轮训练开始')
  113.     train(model, device, train_loader, optimizer, criterion)
  114.     test(model, device, test_loader)
复制代码
4.实验 

实验过程:首先对数据举行预处理,然后导入数据聚集和数据加载,然后对模子举行构造,然后对模子举行训练和测试
实验结果如下:
 


5.总结

      在实验中由于利用AlexNet网络对RGB图像举行图像分类,所以不是灰度图像的输入通道为1,而是改成3,一开始没想到这点,然后对于模子的输出来说,由于我是在电脑上跑的,内存不太够,我对于Fruits-360数据集举行删减,最后剩下两个类别,所以模子的输出应该改成2,然后还有一些训练过程中的错误,实现了深度学习的图像分类,锻炼了实践能力以及综合能力
 
 


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4