Pytorch入门实战第七周:咖啡豆识别(VGG-16复现)

本文围绕Python搭建VGG - 16模型展开。前期进行数据导入、处理与划分,手动搭建VGG - 16模型并训练,对结果可视化和评估。还调用官方VGG - 16框架对比,通过调整学习率使验证集准确率达100%,并了解了模型轻量化知识。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

前言

一、前期准备

二、手动搭建VGG-16模型

2.1 VGG-16的基本介绍

2.2 手动搭建VGG-16模型

2.3 查看模型详情

三、训练模型

3.1 编写训练函数

3.2 编写测试函数

3.3 正式训练

四、结果可视化

4.1 Loss和Accuracy图

4.2 指定图片进行预测

4.3 模型评估

五、尝试

5.1 调用官方的VGG-16框架

5.2 调整使得验证集准确率达到100%

5.3 轻量化模型

总结


前言

  • 🍨 本文为[🔗365天深度学习训练营](https://mp.weixin.qq.com/s/0dvHCaOoFnW8SCp3JpzKxg) 中的学习记录博客
  • 🍖 原作者:[K同学啊](https://mtyjkh.blog.youkuaiyun.com/)

说在前面:

  • 本周学习目标:基本要求——自己搭建VGG-16网络框架、调用官方的VGG-16网络框架、如何查看模型的参数量以及相关指标;拔高要求——验证集准确率达到100%、使用PPT画出VGG-16算法框架图;探索——在不影响准确率的前提下轻量化模型(目前VGG-16的total params是134276932
  • 我的环境:Python3.8、Pycharm2020、torch1.12.1+cu113
  • 数据来源:[K同学啊](https://mtyjkh.blog.youkuaiyun.com/))

一、前期准备

1.1 导入所需的包并设置GPU

(有GPU优先使用GPU,没有的话就使用CPU)

代码如下:

#一、前期准备
'''
1.1设置GPU
'''
import torch
import torch.nn as nn
import torchvision.transforms as transforms
import torchvision
from torchvision import transforms, datasets
import os,PIL,pathlib,warnings
#import torch.nn.functional as F
import matplotlib.pyplot as plt
from PIL import Image
from torchvision.models import vgg16
import copy

warnings.filterwarnings("ignore")        #忽略警告信息--???怎么突然增加一个这个

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
print(device)

打印输出:cuda

1.2 导入数据

1.数据下载并设置相应的文件目录以便图片读取,将数据下载放在对应代码目录下新建的data目录

  • 数据集介绍:一共是四类的咖啡豆的照片,每类对应200张人脸图,一共是800张图片,分别放在4个子文件下,每个子文件夹即为咖啡豆的种类

导入数据的步骤:

 1)使用函数将字符串类型的文件夹路径转换为pathlib.Path对象

 2)使用glob方法获取data_dir路径下的所有文件路径,并以列表的形式存储在data_paths中

 3)利用split()函数对data_paths中的每个文件路径执行分割操作,获取各个文件所属的类别名称并储存在classNames中

数据文件导入代码如下:

'''
1.2 导入数据
'''
data_dir = './data/'
data_dir = pathlib.Path(data_dir)
data_paths = list(data_dir.glob('*'))
classNames = [str(path).split("\\")[1] for path in data_paths]
print(classNames)

打印结果为:['Dark', 'Green', 'Light', 'Medium']

1.3 图片处理

torchvision.transforms是pytorch中的图像预处理包。一般用Compose把多个步骤整合到一起 
1)Resize:将输入图片resize成统一尺寸
2)ToTensor:将PIL Image或numpy.ndarray转换为tensor,并归一化到[0,1]之间
3)Normalize:标准化处理-->转换为标准正态分布,使模型更容易收敛;其中mean=[0.485,0.456,0.406]与std=[0.229,0.224,0.225] 从数据集中随机抽样计算得到的
ImageFolder类来创建一个数据集对象,total_data将是一个包含所有图像数据的数据集对象,可以用于训练神经网络模型

代码如下:

'''
1.3 图片转换
'''
train_transforms = transforms.Compose([
    transforms.Resize([224, 224]),  # 将输入图片resize成统一尺寸
    # transforms.RandomHorizontalFlip(), # 随机水平翻转
    transforms.ToTensor(),          # 将PIL Image或numpy.ndarray转换为tensor,并归一化到[0,1]之间
    transforms.Normalize(           # 标准化处理-->转换为标准正太分布(高斯分布),使模型更容易收敛
        mean=[0.485, 0.456, 0.406],
        std=[0.229, 0.224, 0.225])  # 其中 mean=[0.485,0.456,0.406]与std=[0.229,0.224,0.225] 从数据集中随机抽样计算得到的。
])

test_transform = transforms.Compose([
    transforms.Resize([224, 224]),  # 将输入图片resize成统一尺寸
    transforms.ToTensor(),          # 将PIL Image或numpy.ndarray转换为tensor,并归一化到[0,1]之间
    transforms.Normalize(           # 标准化处理-->转换为标准正太分布(高斯分布),使模型更容易收敛
        mean=[0.485, 0.456, 0.406],
        std=[0.229, 0.224, 0.225])  # 其中 mean=[0.485,0.456,0.406]与std=[0.229,0.224,0.225] 从数据集中随机抽样计算得到的。
])

total_data = datasets.ImageFolder("./data/",transform=train_transforms)
print(total_data)
print(total_data.class_to_idx)

打印如下:

Dataset ImageFolder
    Number of datapoints: 1200
    Root location: ./data/
    StandardTransform
Transform: Compose(
               Resize(size=[224, 224], interpolation=bilinear, max_size=None, antialias=warn)
               ToTensor()
               Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
           )
{'Dark': 0, 'Green': 1, 'Light': 2, 'Medium': 3}

1.4 划分数据集

取全部数据的80%作为训练集、剩下的20%作为测试集,并随机分割数据集为训练集测试集

torch.utils.data.random_split(dataset, lengths, generator=<torch._C.Generator object>)

随机将一个数据集分割成给定长度的不重叠的新数据集。可选择固定生成器以获得可复现的结果(效果同设置随机种子)。
dataset (Dataset) – 要划分的数据集。
lengths (sequence) – 要划分的长度。
generator (Generator) – 用于随机排列的生成器。

代码如下:

'''
1.4 划分数据集
'''
train_size = int(0.8 * len(total_data))
test_size = len(total_data) - train_size
train_dataset, test_dataset = torch.utils.data.random_split(total_data, [train_size, test_size])
print(train_dataset, test_dataset)

输出结果:<torch.utils.data.dataset.Subset object at 0x00000155ABDFA760> <torch.utils.data.dataset.Subset object at 0x00000155ABDFA7C0>

1.5 查看一个batch_size的数据结构

torch.utils.data.DataLoader():这是Pytorch中用于加载和管理数据的一个实用工具类,它允许以小批次的方式迭代数据集,这对于训练神经网络和其他机器学习任务非常有用。具体参数解释如下:

1)dataset(必需参数):这是你的数据集对象,通常是 torch.utils.data.Dataset 的子类,它包含了你的数据样本。

2)batch_size(可选参数):指定每个小批次中包含的样本数。默认值为 1。

3)shuffle(可选参数):如果设置为 True,则在每个 epoch 开始时对数据进行洗牌,以随机打乱样本的顺序。这对于训练数据的随机性很重要,以避免模型学习到数据的顺序性。默认值为 False。

4)num_workers(可选参数):用于数据加载的子进程数量。通常,将其设置为大于 0 的值可以加快数据加载速度,特别是当数据集很大时。默认值为 0,表示在主进程中加载数据。

5)pin_memory(可选参数):如果设置为 True,则数据加载到 GPU 时会将数据存储在 CUDA 的锁页内存中,这可以加速数据传输到 GPU。默认值为 False。

6)drop_last(可选参数):如果设置为 True,则在最后一个小批次可能包含样本数小于 batch_size 时,丢弃该小批次。这在某些情况下很有用,以确保所有小批次具有相同的大小。默认值为 False。

7)timeout(可选参数):如果设置为正整数,它定义了每个子进程在等待数据加载器传递数据时的超时时间(以秒为单位)。这可以用于避免子进程卡住的情况。默认值为 0,表示没有超时限制。

8)worker_init_fn(可选参数):一个可选的函数,用于初始化每个子进程的状态。这对于设置每个子进程的随机种子或其他初始化操作很有用

代码如下:

batch_size = 32
train_dl = torch.utils.data.DataLoader(train_dataset,
                                       batch_size=batch_size,
                                       shuffle=True,
                                       num_workers=0)
test_dl = torch.utils.data.DataLoader(test_dataset,
                                      batch_size=batch_size,
                                      shuffle=True,
                                      num_workers=0)
for X, y in test_dl:
    print("Shape of X [N, C, H, W]: ", X.shape)
    print("Shape of y: ", y.shape, y.dtype)
    break

打印如下:

Shape of X [N, C, H, W]:  torch.Size([32, 3, 224,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值