第P4周:猴痘病识别

news2024/12/23 13:52:37
  • 🍨 本文为🔗365天深度学习训练营 中的学习记录博客
  • 🍦 参考文章:Pytorch实战 | 第P4周:猴痘病识别
  • 🍖 原作者:K同学啊|接辅导、项目定制

一、前期准备

1.设置GPU 

''' 设置GPU '''
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
print("Using {} device".format(device))

没有GPU则使用CPU 

 

2.导入数据、数据预处理

import os,PIL,random,pathlib
data_dir = r'D:\P4'
data_dir = pathlib.Path(data_dir)

data_paths = list(data_dir.glob('*'))
class_names = [path.name for path in data_paths]
print(class_names)

 

 

import pathlib
import torchvision.transforms as transforms
from torchvision import datasets
total_datadir = r'D:\P4'

train_transforms = transforms.Compose([
    transforms.Resize([224, 224]),
    transforms.ToTensor(),
    transforms.Normalize(
        mean=[0.485, 0.456, 0.406],
        std=[0.229, 0.224, 0.225]
    )
])

total_data = datasets.ImageFolder(total_datadir, transform=train_transforms)
print(total_data)

定义数据预处理操作 train_transforms

  • transforms.Resize([224, 224]):将输入图像的尺寸调整为 224x224 像素,这通常是训练深度学习模型所使用的常见图像尺寸。
  • transforms.ToTensor():将图像数据转换为PyTorch张量,并将像素值归一化到范围 [0, 1]。
  • transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]):对图像进行标准化处理,将像素值标准化为标准正态分布(高斯分布),这有助于模型更快地收敛。

使用 datasets.ImageFolder 加载图像数据集:

  • total_datadir 是包含图像数据集的目录路径。
  • transform=train_transforms 指定了要应用的数据预处理操作。

 3.标签映射

在DatasetFolder中,class_to_idx是一个字典,将类别名映射到类别标签(从0开始),其中类别名是文件夹的名称,类别标签是与之相关联的数字。

为什么要做标签映射呢?

  • 将类别名映射到类别标签是因为在训练深度学习模型时,通常使用类别标签来表示每个样本的类别。
  • 在训练模型时,输入数据被转换为张量,并且每个张量的标签是一个数字,表示与之相关联的类别。
  • 类别标签使得模型可以根据真实标签和预测标签之间的误差来更新模型权重,从而使模型学习到如何将输入数据映射到正确的输出标签。

 

print(total_data.class_to_idx)

二、划分数据集

import torch
from torch.utils.data import DataLoader

# total_data 包含了数据集,我们可以从 total_data 中划分出训练集和测试集
# 例如,可以按照一定的比例划分数据集,或者根据需要自定义训练集和测试集

# 划分数据集示例:
# 假设数据集总共有100个样本,可以将前80个样本用于训练,后20个用于测试
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])

batch_size = 32

train_dl = DataLoader(train_dataset, batch_size=batch_size, shuffle=True, num_workers=1)
test_dl = DataLoader(test_dataset, batch_size=batch_size, shuffle=True, num_workers=1)

三、 构建 CNN 网络

import torch
import torch.nn as nn
import torch.nn.functional as F

class Network(nn.Module):
    def __init__(self):
        super(Network, self).__init__()
        self.conv1 = nn.Conv2d(3, 6, 5)
        self.conv2 = nn.Conv2d(6, 16, 5)
        self.fc1 = nn.Linear(16 * 53 * 53, 120)
        self.fc2 = nn.Linear(120, 84)
        self.fc3 = nn.Linear(84, 2)
        self.dropout = nn.Dropout(0.5)  # Adding dropout with a probability of 0.5

    def forward(self, x):
        x = F.max_pool2d(F.relu(self.conv1(x)), 2)
        x = F.max_pool2d(F.relu(self.conv2(x)), 2)
        x = x.view(-1, 16 * 53 * 53)
        x = F.relu(self.fc1(x))
        x = self.dropout(x)  # Applying dropout after the first fully connected layer
        x = F.relu(self.fc2(x))
        x = self.dropout(x)  # Applying dropout after the second fully connected layer
        x = self.fc3(x)
        x = F.log_softmax(x, dim=1)
        return x

model = Network()
print(model)

四、训练模型

1. 设置超参数 

# 定义损失函数和优化器
loss_fn = nn.CrossEntropyLoss()
leaining_rate = 0.001
opt = torch.optim.Adam(model.parameters(),lr=leaining_rate)

2.编写训练函数

# 训练函数
def train(dataloader, model, loss_fn, optimizer):
    size = len(dataloader.dataset)
    num_batches = len(dataloader)

    train_loss, train_acc = 0, 0
    for x, y in dataloader:
        x, y  = x.to(device), y.to(device)

        # Compute prediction error
        pred = model(x) # 网络输出
        loss = loss_fn(pred, y) # 计算损失

        optimizer.zero_grad() # 梯度清零
        loss.backward() # 反向传播
        optimizer.step() # 更新参数

        train_acc += (pred.argmax(1) == y).type(torch.float).sum().item()
        train_loss += loss.item()

    train_acc /= size
    train_loss /= num_batches

    return train_acc, train_loss

# 测试函数
def test(dataloader, model, loss_fn):
    size = len(dataloader.dataset)
    num_batches = len(dataloader)

    test_loss, test_acc = 0, 0
    with torch.no_grad():
        for x, y in dataloader:
            x, y  = x.to(device), y.to(device)

            pred = model(x)
            loss = loss_fn(pred, y)

            test_loss += loss_fn(pred, y).item()
            test_acc += (pred.argmax(1) == y).type(torch.float).sum().item()

    test_acc /= size
    test_loss /= num_batches

    return test_acc, test_loss

3.正式训练

epochs     = 20
train_loss = []
train_acc  = []
test_loss  = []
test_acc   = []

for epoch in range(epochs):
    model.train()
    epoch_train_acc, epoch_train_loss = train(train_dl, model, loss_fn, opt)
    
    model.eval()
    epoch_test_acc, epoch_test_loss = test(test_dl, model, loss_fn)
    
    train_acc.append(epoch_train_acc)
    train_loss.append(epoch_train_loss)
    test_acc.append(epoch_test_acc)
    test_loss.append(epoch_test_loss)
    
    template = ('Epoch:{:2d}, Train_acc:{:.1f}%, Train_loss:{:.3f}, Test_acc:{:.1f}%,Test_loss:{:.3f}')
    print(template.format(epoch+1, epoch_train_acc*100, epoch_train_loss, epoch_test_acc*100, epoch_test_loss))
print('Done')

 

代码在运行时出现下列问题可能是以下原因导致: 

Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "D:\Python\lib\multiprocessing\spawn.py", line 116, in spawn_main
    exitcode = _main(fd, parent_sentinel)
  File "D:\Python\lib\multiprocessing\spawn.py", line 125, in _main
    prepare(preparation_data)
  File "D:\Python\lib\multiprocessing\spawn.py", line 236, in prepare
    _fixup_main_from_path(data['init_main_from_path'])
  File "D:\Python\lib\multiprocessing\spawn.py", line 287, in _fixup_main_from_path
    main_content = runpy.run_path(main_path,
  File "D:\Python\lib\runpy.py", line 289, in run_path
    return _run_module_code(code, init_globals, run_name,
  File "D:\Python\lib\runpy.py", line 96, in _run_module_code
    _run_code(code, mod_globals, init_globals,
  File "D:\Python\lib\runpy.py", line 86, in _run_code
    exec(code, run_globals)
  File "c:\Users\刘鸿逸\Desktop\python\01.py", line 156, in <module>
    epoch_train_acc, epoch_train_loss = train(train_dl, model, loss_fn, opt)
  File "c:\Users\刘鸿逸\Desktop\python\01.py", line 105, in train
    for X, y in dataloader:  # 获取图片及其标签
  File "D:\Python\lib\site-packages\torch\utils\data\dataloader.py", line 441, in __iter__
    return self._get_iterator()
  File "D:\Python\lib\site-packages\torch\utils\data\dataloader.py", line 388, in _get_iterator
    return _MultiProcessingDataLoaderIter(self)
  File "D:\Python\lib\site-packages\torch\utils\data\dataloader.py", line 1042, in __init__
    w.start()
  File "D:\Python\lib\multiprocessing\process.py", line 121, in start
    self._popen = self._Popen(self)
  File "D:\Python\lib\multiprocessing\context.py", line 224, in _Popen
    return _default_context.get_context().Process._Popen(process_obj)
  File "D:\Python\lib\multiprocessing\context.py", line 336, in _Popen
    return Popen(process_obj)
  File "D:\Python\lib\multiprocessing\popen_spawn_win32.py", line 45, in __init__
    prep_data = spawn.get_preparation_data(process_obj._name)
  File "D:\Python\lib\multiprocessing\spawn.py", line 154, in get_preparation_data
    _check_not_importing_main()
  File "D:\Python\lib\multiprocessing\spawn.py", line 134, in _check_not_importing_main
    raise RuntimeError('''
RuntimeError:
        An attempt has been made to start a new process before the
        current process has finished its bootstrapping phase.

        This probably means that you are not using fork to start your
        child processes and you have forgotten to use the proper idiom
        in the main module:

            if __name__ == '__main__':
                freeze_support()
                ...

        The "freeze_support()" line can be omitted if the program
        is not going to be frozen to produce an executable.

这个错误是由于在Windows操作系统上使用多进程时,未按照正确的方式设置了启动子进程的方法引起的。它提示需要在主模块中添加适当的if __name__ == '__main__':块以正确启动子进程。下面解释一下报错的含义以及如何解决它: 

  • 为了解决这个问题,应该确保在主模块中使用if __name__ == '__main__':块来包装主要的执行代码,这是一种在使用多进程时常见的做法。
  • 在主模块中包装代码后,子进程将只在主进程中执行,而不会在导入模块时执行。这可以防止上述报错。

修改后完整代码:

import torch
import torch.nn as nn
import torchvision.transforms as transforms
import torchvision
from torchvision import transforms, datasets
import os
import PIL
import pathlib

# Your code for data loading, model definition, training, and testing should go here

if __name__ == '__main__':
    device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

    print(device)

    import os,PIL,random,pathlib
    data_dir = r'D:\P4'
    data_dir = pathlib.Path(data_dir)

    data_paths = list(data_dir.glob('*'))
    class_names = [path.name for path in data_paths]
    print(class_names)

    total_datadir = r'D:\P4'
    # 关于transforms.Compose的更多介绍可以参考:https://blog.csdn.net/qq_38251616/article/details/124878863
    train_transforms = 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(total_datadir, transform=train_transforms)
    print(total_data)

    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)

    batch_size = 32

    train_dl = torch.utils.data.DataLoader(train_dataset,
                                           batch_size=batch_size,
                                           shuffle=True,
                                           num_workers=1)
    test_dl = torch.utils.data.DataLoader(test_dataset,
                                          batch_size=batch_size,
                                          shuffle=True,
                                          num_workers=1)

    import torch.nn.functional as F

    class Network_bn(nn.Module):
        def __init__(self):
            super(Network_bn, self).__init__()
            """
            nn.Conv2d()函数:
            第一个参数(in_channels)是输入的channel数量
            第二个参数(out_channels)是输出的channel数量
            第三个参数(kernel_size)是卷积核大小
            第四个参数(stride)是步长,默认为1
            第五个参数(padding)是填充大小,默认为0
            """
            self.conv1 = nn.Conv2d(in_channels=3, out_channels=12, kernel_size=5, stride=1, padding=0)
            self.bn1 = nn.BatchNorm2d(12)
            self.conv2 = nn.Conv2d(in_channels=12, out_channels=12, kernel_size=5, stride=1, padding=0)
            self.bn2 = nn.BatchNorm2d(12)
            self.pool = nn.MaxPool2d(2,2)
            self.conv4 = nn.Conv2d(in_channels=12, out_channels=24, kernel_size=5, stride=1, padding=0)
            self.bn4 = nn.BatchNorm2d(24)
            self.conv5 = nn.Conv2d(in_channels=24, out_channels=24, kernel_size=5, stride=1, padding=0)
            self.bn5 = nn.BatchNorm2d(24)
            self.fc1 = nn.Linear(24*50*50, len(class_names))

        def forward(self, x):
            x = F.relu(self.bn1(self.conv1(x)))      
            x = F.relu(self.bn2(self.conv2(x)))     
            x = self.pool(x)                        
            x = F.relu(self.bn4(self.conv4(x)))     
            x = F.relu(self.bn5(self.conv5(x)))  
            x = self.pool(x)                        
            x = x.view(-1, 24*50*50)
            x = self.fc1(x)

            return x

    device = "cuda" if torch.cuda.is_available() else "cpu"
    print("Using {} device".format(device))

    model = Network_bn().to(device)
    print(model)

    loss_fn    = nn.CrossEntropyLoss() # 创建损失函数
    learn_rate = 1e-4 # 学习率
    opt        = torch.optim.SGD(model.parameters(),lr=learn_rate)

    # 训练循环
    def train(dataloader, model, loss_fn, optimizer):
        size = len(dataloader.dataset)  # 训练集的大小,一共60000张图片
        num_batches = len(dataloader)   # 批次数目,1875(60000/32)

        train_loss, train_acc = 0, 0  # 初始化训练损失和正确率

        for X, y in dataloader:  # 获取图片及其标签
            X, y = X.to(device), y.to(device)

            # 计算预测误差
            pred = model(X)          # 网络输出
            loss = loss_fn(pred, y)  # 计算网络输出和真实值之间的差距,targets为真实值,计算二者差值即为损失

            # 反向传播
            optimizer.zero_grad()  # grad属性归零
            loss.backward()        # 反向传播
            optimizer.step()       # 每一步自动更新

            # 记录acc与loss
            train_acc  += (pred.argmax(1) == y).type(torch.float).sum().item()
            train_loss += loss.item()

        train_acc  /= size
        train_loss /= num_batches

        return train_acc, train_loss

    def test (dataloader, model, loss_fn):
        size        = len(dataloader.dataset)  # 测试集的大小,一共10000张图片
        num_batches = len(dataloader)          # 批次数目,313(10000/32=312.5,向上取整)
        test_loss, test_acc = 0, 0

        # 当不进行训练时,停止梯度更新,节省计算内存消耗
        with torch.no_grad():
            for imgs, target in dataloader:
                imgs, target = imgs.to(device), target.to(device)

                # 计算loss
                target_pred = model(imgs)
                loss        = loss_fn(target_pred, target)

                test_loss += loss.item()
                test_acc  += (target_pred.argmax(1) == target).type(torch.float).sum().item()

        test_acc  /= size
        test_loss /= num_batches

        return test_acc, test_loss

    epochs     = 17
    train_loss = []
    train_acc  = []
    test_loss  = []
    test_acc   = []

    for epoch in range(epochs):
        model.train()
        epoch_train_acc, epoch_train_loss = train(train_dl, model, loss_fn, opt)

        model.eval()
        epoch_test_acc, epoch_test_loss = test(test_dl, model, loss_fn)

        train_acc.append(epoch_train_acc)
        train_loss.append(epoch_train_loss)
        test_acc.append(epoch_test_acc)
        test_loss.append(epoch_test_loss)

        template = ('Epoch:{:2d}, Train_acc:{:.1f}%, Train_loss:{:.3f}, Test_acc:{:.1f}%,Test_loss:{:.3f}')
        print(template.format(epoch+1, epoch_train_acc*100, epoch_train_loss, epoch_test_acc*100, epoch_test_loss))
    print('Done')

 

验证集正确率达到88%以上。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/989813.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

mysql drop table 死锁

1.场景 mysql出现大量的drop table阻塞操作 2.从会话表 processlist 里面和事务表INNODB_TRX里面并找不到正在占用锁的会话和事务 3.分析锁信息&#xff1a; INNODB_LOCKs 和INNODB_LOCK_waits 4.有问题的查询&#xff1a;可能会导致整个db的阻塞吗&#xff1f; | 2576901 | …

基于AERMOD模型在大气环境影响评价中的实践技术应用

随着我国经济快速发展&#xff0c;我国面临着日益严重的大气污染问题。近年来&#xff0c;严重的大气污染问题已经明显影响国计民生&#xff0c;引起政府、学界和人们越来越多的关注。大气污染是工农业生产、生活、交通、城市化等方面人为活动的综合结果&#xff0c;同时气象因…

Windows 12 开源网页版

前言 Windows 12 网页版是一个开源项目,使用标准网络技术,例如 Html、CSS 和 Javascript, 希望让用户在网络上预先体验 Windows 12 Windows 12 网页版download Windows 12 网页版 gitlab项目Windows 12 网页版 download参考download 开始菜单 ​ 功能 ​

tab切换,左右加箭头,点击箭头实现tab切换

和正常tab切换一样原理&#xff0c;点击箭头多了步计算 <template><div><div class"tab-container"><p>{{projectName}}</p><div class"banner"><div v-for"(tab, index) in tabs" :key"index&quo…

完整的神经网络模型训练步骤——以CIFAR10数据集为例(pytorch版本)

完整步骤 准备数据集 DataLoader加载数据集 搭建网络模型 创建网络模型实例 定义损失函数 定义优化器 设置网络训练参数 开始训练 验证模型 保存模型 训练结果可视化&#xff08;使用tensorboard完成&#xff09; 数据集介绍 CIFAR10 是由 Hinton 的学生 Alex Krizhevsky、Il…

使用dockerfile文件部署Python+PyWebIO项目

1、安装docker 教程详见之前的内容。https://blog.csdn.net/weixin_44691253/category_12101661.html 2、打包好Python项目 之前的文章中有提到我编写测试工具使用的框架&#xff1a;PythonRequestsPyWebIO框架详解&#xff0c;编写测试工具提高团队测试效率 打包项目时&am…

LlamaIndex:将个人数据添加到LLM

推荐&#xff1a;使用 NSDT场景编辑器 快速搭建3D应用场景 LlamaIndex是基于大型语言模型&#xff08;LLM&#xff09;的应用程序的数据框架。像 GPT-4 这样的 LLM 是在大量公共数据集上预先训练的&#xff0c;允许开箱即用的令人难以置信的自然语言处理能力。但是&#xff0c;…

Ei、Scopus双检索 | 2024年第三届人工智能与机器学习前沿国际会议(FAIML 2024)

会议简介 Brief Introduction 2024年第三届人工智能与机器学习前沿国际会议(FAIML 2024) 会议时间&#xff1a;2024年4月26日-28日 召开地点&#xff1a;中国宜昌 大会官网&#xff1a;www.faiml.org FAIML 2024将围绕“人工智能与机器学习”的最新研究领域而展开&#xff0c;为…

扫地僧静态站群:神马SEO养权重站,快速出收录/权重

扫地僧静态站群:神马SEO养权重站,快速出收录/权重神马搜索权重需要慢养耐心 技巧也需要 百分百出权重率也不是梦图中权重为【站长工具】与爱站结果差距较大

Multimodal Video Pre-trainin

视频领域的多模态预训练工作近年来逐渐兴起。多模态模型通常融合了图像、视频、文本等多类特征&#xff0c;性能优于单模态模型。预训练模型通常以自监督的方式在大批量数据集上进行训练&#xff0c;而后服务于下游任务。本文梳理了近年来视频多模态预训练领域的相关工作&#…

Redis多机数据库实现

Redis多机数据库实现 为《Redis设计与实现》笔记 复制 客户端可以使用SLAVEOF命令将指定服务器设置为该服务器的主服务器 127.0.0.1:12345> SLAVEOF 127.0.0.1 6379127.0.0.1:6379将被设置为127.0.0.1:123456的主服务器 旧版复制功能的实现 Redis的复制功能分为同步&a…

扫地僧静态养站王站群:搜狗SEO站群收录养站效果

扫地僧静态养站王站群:Sogou搜狗SEO出站及收录效果,扫地僧静态站群采用了静态生成式的方式&#xff0c;只需要一个后台管理系统即可管理多个网站&#xff0c;大大提高了建站效率。建站大概45天左右&#xff0c;收录率百分之三十至百分之五十左右 如果对购买的域名进行把控&…

Spring系列文章1:Spring入门程序

一、什么是spring 一个java框架、java语言开发&#xff0c;轻量级、开源框架、在j2se、j2ee中都可以使用。它是一个管理对象的容器&#xff0c;Spring 容器不装文本&#xff0c;数字。装的是java对象。 核心技术&#xff1a;ioc、aop 官网地址 https://spring.io 项目列表…

汇编-外中断

我们知道, CPU在计算机系统中, 除了能够执行指令,进行运算以外,还应该能够对外部设备进行控制,接收它们的输入,向它们进行输出。也就是说, CPU除了有运算能力外, 还要有I/O(Input/Output, 输入/输出) 能力。比如, 我们按下键盘上的一个键, CPU最终要能够处理这个键。…

栈trace(kprobe)

最近在看CPU/GPU的调用&#xff0c;于是就有了&#xff1a; 与事件跟踪器类似&#xff0c;不需要通过 current_tracer 激活。相反&#xff0c;通过 /sys/kernel/tracing/kprobe_events 添加探测点&#xff0c;并通过 /sys/kernel/tracing/events/kprobes/<EVENT>/enable…

图片怎么转换成pdf格式?好方法必须分享

图片怎么转换成pdf格式&#xff1f;也许一些朋友会问&#xff0c;为什么要将图片转换成PDF文件呢&#xff1f;众所周知&#xff0c;PDF文件格式具有较高的安全性和兼容性&#xff0c;并且不容易编辑。因此&#xff0c;在打印时&#xff0c;将图片转换成PDF格式后再进行打印可以…

Ubuntu-22.04通过RDP协议连接远程桌面

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、RDP是什么&#xff1f;二、配置1.打开远程桌面功能2.验证服务3.防火墙配置4.测试效果 总结 前言 由于一些特殊需要&#xff0c;我需要通过远程桌面连接到U…

0017Java程序设计-spr农业过程化管理系统

摘 要目 录系统设计开发环境 摘 要 本农业过程化管理系统就是建立在充分利用现在完善科技技术这个理念基础之上&#xff0c;并使用IT技术进行对农业过程化的管理&#xff0c;从而保证种植户能种植出优质的农作物&#xff0c;可以实现农业过程化的在线管理&#xff0c;这样保证…

传输层-TCP 的安全机制和高效策略

可靠性&#xff1a; 之前我们在UDP中谈到了&#xff0c;UDP不可靠但是简单&#xff0c;TCP可靠但是也要做更多的工作&#xff0c;那这些工作具体是什么呢&#xff1f;接下来让我们详细了解一下。 确认应答机制&#xff08;ACK机制&#xff09; 序号&#xff1a;我们可以把TCP…

Qt配置使用MSVC编译器

Qt配置使用MSVC编译器_qt msvc-CSDN博客注意:Qt支持的MSVC就是2017和2015&#xff0c;所以vs也要下载2017&#xff0c;不要直接用最新的&#xff0c;安装路径都用默认的。程序运行失败时可以尝试windeployqt拷贝库文件到本地&#xff0c;然后有可能就能运行了。VS官网下载Visua…