Pytorch从零开始实战06

news2024/11/7 7:35:41

Pytorch从零开始实战——明星识别

本系列来源于365天深度学习训练营

原作者K同学

文章目录

  • Pytorch从零开始实战——明星识别
    • 环境准备
    • 数据集
    • 模型选择
    • 开始训练
    • 模型可视化
    • 模型预测
    • 总结

环境准备

本文基于Jupyter notebook,使用Python3.8,Pytorch2.0.1+cu118,torchvision0.15.2,需读者自行配置好环境且有一些深度学习理论基础。本次实验的目的是了解如何设置动态学习率。
第一步,导入常用包。

import torch
import torch.nn as nn
import matplotlib.pyplot as plt
import torchvision
import torchvision.transforms as transforms
import torchvision.datasets as datasets
import torch.nn.functional as F
import random
from time import time
import numpy as np
import pandas as pd
import datetime
import gc
import os
import copy
os.environ['KMP_DUPLICATE_LIB_OK']='True'  # 用于避免jupyter环境突然关闭
torch.backends.cudnn.benchmark=True  # 用于加速GPU运算的代码

设置随机数种子

torch.manual_seed(55)
torch.cuda.manual_seed(55)
torch.cuda.manual_seed_all(55)
random.seed(55)
np.random.seed(55)

创建设备对象

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
device # device(type='cuda')

数据集

本次数据集使用的一系列明星图片,每一位明星的图片存放在对应的文件夹中,文件夹名为明星的姓名。
使用pathlib查看类别名称

import pathlib
data_dir = './data/star'
data_dir = pathlib.Path(data_dir) # 转成pathlib.Path对象
data_paths = list(data_dir.glob('*')) 
classNames = [str(path).split("/")[2] for path in data_paths]
classNames

在这里插入图片描述
使用transforms将图片进行预处理,并且使用datasets整合数据集,每个姓名标签对应的一个数字标签。

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("./data/star/", transform=train_transforms)
total_data.class_to_idx

在这里插入图片描述
查看随机五张图片。
在这里插入图片描述
将数据集以8比2划分为训练集和测试集,使用DataLoader划分批次和随机打乱。

train_size = int(0.8 * len(total_data))
test_size  = len(total_data) - train_size
train_ds, test_ds = torch.utils.data.random_split(total_data, [train_size, test_size])

batch_size = 32
train_dl = torch.utils.data.DataLoader(train_ds,
                                        batch_size=batch_size,
                                        shuffle=True,
                                      )
test_dl = torch.utils.data.DataLoader(test_ds,
                                        batch_size=batch_size,
                                        shuffle=True,
                                     )

len(train_dl.dataset), len(test_dl.dataset) # (1440, 360)

模型选择

本次实验我们直接调用官方的数据集,使用官方预训练的VGG16,冻结模型参数,只训练最后一层的参数。

# 调用官方vgg16
from torchvision.models import vgg16
model = vgg16(pretrained = True).to(device) # 加载预训练的vgg16模型

for param in model.parameters():
    param.requires_grad = False # 冻结模型的参数,只训练最后一层的参数

model.classifier._modules['6'] = nn.Linear(4096, len(classNames)) # 修改vgg16模型中最后一层全连接层,输出目标类别个数
model.to(device)  
model

在这里插入图片描述
创建模型,使用summary查看参数,VGG16的参数还是比较多的。

from torchsummary import summary
# 将模型转移到GPU中
model = model.to(device)
summary(model, input_size=(3, 224, 224))

在这里插入图片描述

开始训练

定义训练函数

def train(dataloader, model, loss_fn, opt):
    size = len(dataloader.dataset)
    num_batches = len(dataloader)
    train_acc, train_loss = 0, 0

    for X, y in dataloader:
        X, y = X.to(device), y.to(device)
        pred = model(X)
        loss = loss_fn(pred, y)

        opt.zero_grad()
        loss.backward()
        opt.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_acc, test_loss = 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_acc += (pred.argmax(1) == y).type(torch.float).sum().item()
            test_loss += loss.item()

    test_acc /= size
    test_loss /= num_batches
    return test_acc, test_loss

设置超参数,本次使用官方的学习率衰减,学习率每经过 4 个 epoch 就会以 0.92 的指数衰减。

lambda1 = lambda epoch: 0.92 ** (epoch // 4)
loss_fn = nn.CrossEntropyLoss()
learn_rate = 0.001
opt = torch.optim.SGD(model.parameters(), lr=learn_rate)
scheduler = torch.optim.lr_scheduler.LambdaLR(opt, lr_lambda=lambda1) # 选定调整方法

开始训练,可能是因为只训练最后一层,模型学习的不是很好。

import time
epochs = 30
train_loss = []
train_acc = []
test_loss = []
test_acc = []

T1 = time.time()

best_acc = 0
best_model = 0

for epoch in range(epochs):

    model.train()
    epoch_train_acc, epoch_train_loss = train(train_dl, model, loss_fn, opt)
    scheduler.step()
    
    model.eval() # 确保模型不会进行训练操作
    epoch_test_acc, epoch_test_loss = test(test_dl, model, loss_fn)

    if epoch_test_acc > best_acc:
        best_acc = epoch_test_acc
        best_model = copy.deepcopy(model)
        
    train_acc.append(epoch_train_acc)
    train_loss.append(epoch_train_loss)
    test_acc.append(epoch_test_acc)
    test_loss.append(epoch_test_loss)
    
    print("epoch:%d, train_acc:%.1f%%, train_loss:%.3f, test_acc:%.1f%%, test_loss:%.3f"
          % (epoch + 1, epoch_train_acc * 100, epoch_train_loss, epoch_test_acc * 100, epoch_test_loss))

T2 = time.time()
print('程序运行时间:%s毫秒' % ((T2 - T1)*1000))

PATH = './best_model.pth'  # 保存的参数文件名
if best_model is not None:
    torch.save(best_model.state_dict(), PATH)
    print('保存最佳模型')
print("Done")

在这里插入图片描述

模型可视化

可视化函数

import warnings
warnings.filterwarnings("ignore")               #忽略警告信息
plt.rcParams['font.sans-serif']    = ['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False      # 用来正常显示负号
plt.rcParams['figure.dpi']         = 100        #分辨率

epochs_range = range(epochs)

plt.figure(figsize=(12, 3))
plt.subplot(1, 2, 1)

plt.plot(epochs_range, train_acc, label='Training Accuracy')
plt.plot(epochs_range, test_acc, label='Test Accuracy')
plt.legend(loc='lower right')
plt.title('Training and Validation Accuracy')

plt.subplot(1, 2, 2)
plt.plot(epochs_range, train_loss, label='Training Loss')
plt.plot(epochs_range, test_loss, label='Test Loss')
plt.legend(loc='upper right')
plt.title('Training and Validation Loss')
plt.show()

在这里插入图片描述

模型预测

定义预测函数

from PIL import Image 

classes = list(total_data.class_to_idx)

def predict_one_image(image_path, model, transform, classes):
    
    test_img = Image.open(image_path).convert('RGB')
    plt.imshow(test_img)  # 展示预测的图片

    test_img = transform(test_img)
    img = test_img.to(device).unsqueeze(0)
    
    model.eval()
    output = model(img)

    _,pred = torch.max(output,1)
    pred_class = classes[pred]
    print(f'预测结果是:{pred_class}')

调用函数,使用模型预测图片

predict_one_image(image_path='./data/star/Angelina Jolie/001_fe3347c0.jpg', 
                  model=model, 
                  transform=train_transforms, 
                  classes=classes)
# 预测结果是:Angelina Jolie

在这里插入图片描述
使用保存的最佳模型查看一下损失。

best_model.eval()
epoch_test_acc, epoch_test_loss = test(test_dl, best_model, loss_fn)
epoch_test_acc, epoch_test_loss # (0.3861111111111111, 1.9115476707617443)

总结

本次调用官方预训练的VGG模型,由于VGG的参数量过大,我们仅训练了最后一层,所以效果不是很好,所以未来数据集比较大的时候,可以放开所有的层重新训练。

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

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

相关文章

订水商城H5实战教程-01需求分析

目录 1 用户分析2 模块分析3 原型设计3.1 首页3.2 商城3.3 一键订购3.4 我的3.5 确认订单3.6 地址管理3.7 编辑地址3.8 搜索3.9 搜索结果3.10 充值3.11 我的订单3.12 开票信息3.13 优惠券3.14 我的空桶3.15 商品详情3.16 购物车3.17 门店信息3.18 订单详情 总结 生活中&#xf…

2023柏鹭杯 express fs

进去看看,发现有个file的参数 查看源码有个?filecheck.html,我们尝试?file/etc/passwd,发现可以直接访问任意文件,但是访问不到flag,可能被waf禁掉了 实际上node不能像php有伪协议可以绕,也没办法用什么编码绕过等&…

Android前台服务和通知

前台服务 Android 13及以上系统需要动态获取通知权限。 //android 13及以上系统动态获取通知权限 if (Build.VERSION.SDK_INT > Build.VERSION_CODES.Q) {checkPostNotificationPermission(); } private void checkPostNotificationPermission() {if (ActivityCompat.chec…

xhadmin多应用Saas框架如何下载安装?

xhadmin是什么? xhadmin 是一套基于最新技术的研发的多应用 Saas 框架,支持在线升级和安装模块及模板,拥有良好的开发框架、成熟稳定的技术解决方案、提供丰富的扩展功能。为开发者赋能,助力企业发展、国家富强,致力于…

小白学java--垃圾回收机制(Garbage Collection)

压测过程中,作为测试会时不时听到研发说命中gc了,如果一头雾水,来看看什么是gc。 1、什么是垃圾回收机制 垃圾回收的执行过程会导致一些额外的开销,例如扫描和标记对象、回收内存空间等操作。这些开销可能会导致一定的性能损失和…

云安全(2)--CAP_SYS_MODULE逃逸

文章目录 测试环境配置实际环境利用 测试环境配置 docker run -it --cap-addSYS_MODULE ubuntu:18.04实际环境利用 cat /proc/self/status|grep Cap然后使用capsh decode一下 capsh --decode00000000a80525fb发现有CAP_SYS_MODULE权限,那么直接往内核注入恶意mo…

Streamlit库开发python交互式Web应用程序

Streamlit是一个开源的Python库,旨在帮助开发人员轻松创建数据科学和机器学习的Web应用程序。它允许您只需几行Python代码即可构建交互式Web应用程序,因此常用于创建数据驱动的应用程序、仪表板和原型。Streamlit以其简单性而闻名,通常被数据…

光影之梦:影视动画渲染的魅力

在动画世界中,光影与色彩是赋予生命与灵魂的魔法。它们将虚无的想象变为具象的画面,让故事情感跃然于屏幕之上。影视动画渲染,正是这一魔法的精妙施展,它以光影为笔,色彩为墨,勾勒出一个个绚丽多姿的梦境。…

洗地机哪个好用?2023年洗地机推荐指南

说到提高家庭幸福生活的家电,洗地机肯定是少不了的,特别对于现在快节奏的生活来说,高效率的解决家务活,而且能够大幅度的提高生活质量。在市场上,消费者面临着选择合适洗地机的难题,因为有各种型号、功能和…

德国大陆博世 ars 548 4D 毫米波雷达 window 系统或者 Ubuntu 系统通讯以及数据解析和显示程序

德国大陆博世 ars 548 4D 毫米波雷达 window 系统或者 Ubuntu ROS 系统通讯以及数据解析和显示程序

这件事,准备考PMP的都必须知道

大家好,我是老原。 新的一月,新的困惑。最近接到的咨询很多,但的确出现了差异化的特质。 以前的粉丝朋友上来就问,我现在是项目经理,主要负责产品研发,我是考PMP还是NPDP好? 现在的粉丝朋友会…

AGC电路,模拟乘法器

文章目录 AGC电路乘法器 AGC电路 注:下面三个没试过 乘法器 TI只有这一种乘法器,跟ADI的AD534一模一样 这个报告里有很多错误 做乘法器最厉害的是ADI

JUC并发编程——各种锁的理解(基于狂神说的学习笔记)

各种锁的理解 公平锁与非公平锁 公平锁:非常公平,不能够插队,先来后到 非公平锁:可以插队,比较灵活(默认都是非公平,如:synchronized,lock) // Lock lock new Reent…

从一次性销售到持续收益:低代码服务商的转型之路

随着低代码市场快速发展,低代码代理商也成为近年来快速崛起的一种新型IT服务提供商,其以敏捷、灵活和高效的优势可以有效地帮助企业加速数字化转型。然而,尽管低代码代理商们的潜力巨大,却共同面临着一个关键的挑战——与客户的合…

瑞芯微RKNN开发·yolov7

官方预训练模型转换 下载yolov7源码解压到本地,并配置基础运行环境。下载官方预训练模型 yolov7-tiny.ptyolov7.pt… 进入yolov7-main目录下,新建文件夹weights,并将步骤2中下载的权重文件放进去。修改models/yolo.py文件 def forward(sel…

【C++】:类和对象(中)之类的默认成员函数——构造函数and析构函数

1.类的6个默认成员函数 如果一个类中什么成员都没有,简称为空类 空类中真的什么都没有吗?并不是,任何类在什么都不写时,编译器会自动生成以下6个默认成员函数 默认成员函数:用户没有显式实现,编译器会生成…

系统设计 - 我们如何通俗的理解那些技术的运行原理 - 第一部分:通信协议(2)

本心、输入输出、结果 文章目录 系统设计 - 我们如何通俗的理解那些技术的运行原理 - 第一部分:通信协议(2)前言SOAP vs REST vs GraphQL vs RPC代码优先与 API 优先HTTP 状态代码API 网关有什么作用步骤说明 我们如何设计有效和安全的 API弘…

Nautilus Chain 与 Coin98 生态达成合作,加速 Zebec 生态亚洲战略进程

目前,行业内首个模块化Layer3架构公链Nautilus Chain已经上线主网,揭示了模块化区块链领域迎来了全新的进程。在主网上线后,Nautilus Chain将扮演Zebec生态中最重要的底层设施角色,并将为Zebec APP以及Zebec Payroll规模性的采用提…

驱动day2作业

编写应用程序控制三盏灯亮灭 head.h #ifndef __HEAD_H__ #define __HEAD_H__ #define PHY_LED1_MODER 0x50006000 #define PHY_LED2_MODER 0x50007000 #define PHY_LED1_ODR 0x50006014 #define PHY_LED2_ODR 0x50007014 #define PHY_RCC 0x50000A28#endif demo1.c #includ…