pytorch实现好莱坞明星识别

news2025/1/12 19:02:42
  •  🍨 本文为🔗365天深度学习训练营 中的学习记录博客
  • 🍦 参考文章地址: 365天深度学习训练营-第P6周:好莱坞明星识别
  • 🍖 作者:K同学啊

 

一、前期准备

1.设置GPU

import torch
from torch import nn
import torchvision
from torchvision import transforms,datasets,models
import matplotlib.pyplot as plt
import os,PIL,pathlib
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
device
device(type='cuda')

2.导入数据

data_dir = './hlw/'
data_dir = pathlib.Path(data_dir)

data_paths = list(data_dir.glob('*'))
classNames = [str(path).split('\\')[1] for path in data_paths]
classNames
['Angelina Jolie',
 'Brad Pitt',
 'Denzel Washington',
 'Hugh Jackman',
 'Jennifer Lawrence',
 'Johnny Depp',
 'Kate Winslet',
 'Leonardo DiCaprio',
 'Megan Fox',
 'Natalie Portman',
 'Nicole Kidman',
 'Robert Downey Jr',
 'Sandra Bullock',
 'Scarlett Johansson',
 'Tom Cruise',
 'Tom Hanks',
 'Will Smith']
train_transforms = transforms.Compose([
    transforms.Resize([224,224]),# resize输入图片
    transforms.ToTensor(), # 将PIL Image或numpy.ndarray转换成tensor
    transforms.Normalize(
        mean = [0.485, 0.456, 0.406],
        std = [0.229,0.224,0.225]) # 从数据集中随机抽样计算得到
])

total_data = datasets.ImageFolder(data_dir,transform=train_transforms)
total_data
Dataset ImageFolder
    Number of datapoints: 1800
    Root location: hlw
    StandardTransform
Transform: Compose(
               Resize(size=[224, 224], interpolation=PIL.Image.BILINEAR)
               ToTensor()
               Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
           )

3.数据集划分

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])
train_dataset,test_dataset
(<torch.utils.data.dataset.Subset at 0x12f8aceda00>,
 <torch.utils.data.dataset.Subset at 0x12f8acedac0>)
train_size,test_size
(1440, 360)
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)

 

4. 数据可视化

imgs, labels = next(iter(train_dl))
imgs.shape

 torch.Size([32, 3, 224, 224])

import numpy as np

 # 指定图片大小,图像大小为20宽、5高的绘图(单位为英寸inch)
plt.figure(figsize=(20, 5)) 
for i, imgs in enumerate(imgs[:20]):
    npimg = imgs.numpy().transpose((1,2,0))
    npimg = npimg * np.array((0.229, 0.224, 0.225)) + np.array((0.485, 0.456, 0.406))
    npimg = npimg.clip(0, 1)
    # 将整个figure分成2行10列,绘制第i+1个子图。
    plt.subplot(2, 10, i+1)
    plt.imshow(npimg)
    plt.axis('off')

for X,y in test_dl:
    print('Shape of X [N, C, H, W]:', X.shape)
    print('Shape of y:', y.shape)
    break
Shape of X [N, C, H, W]: torch.Size([32, 3, 224, 224])
Shape of y: torch.Size([32])

二、构建简单的CNN网络

from torchvision.models import vgg16
    
model = vgg16(pretrained = True).to(device)
for param in model.parameters():
    param.requires_grad = False

model.classifier._modules['6'] = nn.Linear(4096,len(classNames))

model.to(device)
model
VGG(
  (features): Sequential(
    (0): Conv2d(3, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (1): ReLU(inplace=True)
    (2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (3): ReLU(inplace=True)
    (4): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
    (5): Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (6): ReLU(inplace=True)
    (7): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (8): ReLU(inplace=True)
    (9): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
    (10): Conv2d(128, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (11): ReLU(inplace=True)
    (12): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (13): ReLU(inplace=True)
    (14): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (15): ReLU(inplace=True)
    (16): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
    (17): Conv2d(256, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (18): ReLU(inplace=True)
    (19): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (20): ReLU(inplace=True)
    (21): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (22): ReLU(inplace=True)
    (23): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
    (24): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (25): ReLU(inplace=True)
    (26): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (27): ReLU(inplace=True)
    (28): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (29): ReLU(inplace=True)
    (30): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
  )
  (avgpool): AdaptiveAvgPool2d(output_size=(7, 7))
  (classifier): Sequential(
    (0): Linear(in_features=25088, out_features=4096, bias=True)
    (1): ReLU(inplace=True)
    (2): Dropout(p=0.5, inplace=False)
    (3): Linear(in_features=4096, out_features=4096, bias=True)
    (4): ReLU(inplace=True)
    (5): Dropout(p=0.5, inplace=False)
    (6): Linear(in_features=4096, out_features=17, bias=True)
  )
)
# 查看要训练的层
params_to_update = model.parameters()
# params_to_update = []
for name,param in model.named_parameters():
    if param.requires_grad == True:
#         params_to_update.append(param)
        print("\t",name)

三、训练模型

1.优化器设置

# 优化器设置
optimizer = torch.optim.Adam(params_to_update, lr=1e-4)#要训练什么参数/
scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=5, gamma=0.92)#学习率每5个epoch衰减成原来的1/10
loss_fn = nn.CrossEntropyLoss()

2.编写训练函数

# 训练循环
def train(dataloader, model, loss_fn, optimizer):
    size = len(dataloader.dataset)  # 训练集的大小,一共900张图片
    num_batches = len(dataloader)   # 批次数目,29(900/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

3.编写测试函数

def test (dataloader, model, loss_fn):
    size        = len(dataloader.dataset)  # 测试集的大小,一共10000张图片
    num_batches = len(dataloader)          # 批次数目,8(255/32=8,向上取整)
    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

4、正式训练

训练输出层

epochs     = 20
train_loss = []
train_acc  = []
test_loss  = []
test_acc   = []
best_acc = 0
filename='checkpoint.pth'

for epoch in range(epochs):
    model.train()
    epoch_train_acc, epoch_train_loss = train(train_dl, model, loss_fn, optimizer)
    
    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_train_acc
        state = {
            'state_dict': model.state_dict(),#字典里key就是各层的名字,值就是训练好的权重
            'best_acc': best_acc,
            'optimizer' : optimizer.state_dict(),
        }
        torch.save(state, filename)
        
        
    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')
print('best_acc:',best_acc)
Epoch: 1, Train_acc:12.2%, Train_loss:2.701, Test_acc:13.9%,Test_loss:2.544
Epoch: 2, Train_acc:20.8%, Train_loss:2.386, Test_acc:20.6%,Test_loss:2.377
Epoch: 3, Train_acc:26.1%, Train_loss:2.228, Test_acc:22.5%,Test_loss:2.274
...
Epoch:19, Train_acc:51.6%, Train_loss:1.528, Test_acc:35.8%,Test_loss:1.864
Epoch:20, Train_acc:53.9%, Train_loss:1.499, Test_acc:35.3%,Test_loss:1.852
Done
best_acc: 0.37430555555555556

继续训练所有层

for param in model.parameters():
    param.requires_grad = True

# 再继续训练所有的参数,学习率调小一点
optimizer = torch.optim.Adam(model.parameters(), lr=1e-4)
scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=5, gamma=0.92)

# 损失函数
criterion = nn.CrossEntropyLoss()
# 加载之前训练好的权重参数
checkpoint = torch.load(filename)
best_acc = checkpoint['best_acc']
model.load_state_dict(checkpoint['state_dict'])
epochs     = 20
train_loss = []
train_acc  = []
test_loss  = []
test_acc   = []
best_acc = 0
filename='best_vgg16.pth'

for epoch in range(epochs):
    model.train()
    epoch_train_acc, epoch_train_loss = train(train_dl, model, loss_fn, optimizer)
    
    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
        state = {
            'state_dict': model.state_dict(),#字典里key就是各层的名字,值就是训练好的权重
            'best_acc': best_acc,
            'optimizer' : optimizer.state_dict(),
        }
        torch.save(state, filename)
        
        
    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')
print('best_acc:',best_acc)
Epoch: 1, Train_acc:41.0%, Train_loss:1.654, Test_acc:57.5%,Test_loss:1.301
Epoch: 2, Train_acc:72.3%, Train_loss:0.781, Test_acc:58.9%,Test_loss:1.139
Epoch: 3, Train_acc:87.0%, Train_loss:0.381, Test_acc:67.8%,Test_loss:1.079
...
Epoch:19, Train_acc:99.3%, Train_loss:0.033, Test_acc:74.2%,Test_loss:0.895
Epoch:20, Train_acc:99.9%, Train_loss:0.003, Test_acc:74.4%,Test_loss:1.001
Done
best_acc: 0.7666666666666667

四、结果可视化

import matplotlib.pyplot as plt
#隐藏警告
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()

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

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

相关文章

获取rdp保存的凭证

获取用户保存的rdp凭证 当获取到一台windows服务器&#xff0c;可以尝试获取本地远程连接的信息&#xff0c;如果用户在登入rdp时勾选了 允许为我保存凭证的选项&#xff0c;则在该用户本地会生成一个凭证文件&#xff0c;我们只需要破解该凭证文件即可获取其明文密码。 通过注…

[含文档+PPT+源码等]基于SSM框架图书借阅管理系统开发与设计

博主介绍&#xff1a;✌在职Java研发工程师、专注于程序设计、源码分享、技术交流、专注于Java技术领域和毕业设计✌ 项目名称 [含文档PPT源码等]基于SSM框架图书借阅管理系统开发与设计 系统介绍 《基于SSM框架图书管理系统开发与设计》 该项目含有源码、配套开发软件、软件安…

元数据相关的术语,你知道几个?

元数据被认为是数据治理的基石&#xff0c;但关于元数据相关的概念&#xff0c;很多人不是那么清楚&#xff0c;今天就和大家详解元数据相关的术语。当然&#xff0c;与元数据相关的概念非常多&#xff0c;以下仅罗列几个常见的。 01 元数据 1.名词解释 元数据最简单的定义…

【关于时间序列的ML】项目 7 :使用机器学习进行每日出生预测

&#x1f50e;大家好&#xff0c;我是Sonhhxg_柒&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流&#x1f50e; &#x1f4dd;个人主页&#xff0d;Sonhhxg_柒的博客_CSDN博客 &#x1f4c3; &#x1f381;欢迎各位→点赞…

u盘无法识别如何修复?恢复U盘,建议尝试下这些方法

我们基本都有使用过U盘&#xff0c;也都遇到过U盘损坏的问题。u盘无法识别如何修复&#xff1f;有没有什么实用的方法呢&#xff1f;来看看这篇文章&#xff0c;简单几步&#xff0c;就可以修复成功。如果在操作过程中&#xff0c;遇到数据丢失&#xff0c;也有方法帮你恢复&am…

ASP.NET开发的医疗健康咨询平台源码 养生知识咨询 寻根问药平台源码 C#源码

一、源码特点&#xff1a; 爱心医生健康知识门户网站是一个权威的医疗科普视频、语音、知识、医疗健康问答平台。 包含所有源代码和数据库&#xff0c;可以直接部署到IIS中使用。 二、菜单功能 网站页面&#xff1a; 1、首页&#xff1a;包含幻灯片。 2…

MySQL面试常问问题(SQL 优化 ) —— 赶快收藏

目录 1.慢SQL如何定位呢&#xff1f; 2.有哪些方式优化慢SQL&#xff1f; 避免不必要的列 分页优化 索引优化 JOIN优化 排序优化 UNION优化 3.怎么看执行计划&#xff08;explain&#xff09;&#xff0c;如何理解其中各个字段的含义&#xff1f; 1.慢SQL如何定位呢&a…

基于python开发的DIY宠物桌面系统(附源码)--可自定义修改

定制你的宠物桌面 最近想要做一个自己独一无二的桌面宠物&#xff0c;可以直接使用python来自己订制。属于一个小项目&#xff0c;这个教程主要包含几个步骤&#xff1a; 准备需要的动图素材 规划自己需要的功能 使用python的PyQt5订制功能 在这个教程中&#xff0c;我主要…

Apache Flink 任务 Tasks 和任务槽 Task Slots

目录 任务槽&#xff08;Task Slots&#xff09; 任务槽数量的设置 任务对任务槽的共享 任务槽和并行度的关系 任务槽&#xff08;Task Slots&#xff09; Flink 中每一个 worker(也就是 TaskManager)都是一个 JVM 进程&#xff0c;它可以启动多个独立的线程&#xff0c;来并…

【数据结构】详解队列和循环队列

目录一.队列1.队列的概念及结构2.队列的实现Queue.hQueue.c二.循环队列1.循环队列的实现2.设计循环队列解题思路代码一.队列 1.队列的概念及结构 队列&#xff1a;只允许在一端进行插入数据操作&#xff0c;在另一端进行删除数据操作的特殊线性表&#xff0c;队列具有先进先出…

四、网络层(六)移动IP

目录 6.1 移动IP的概念 6.2 移动IP的基本工作原理 6.2.1代理发现与注册 6.2.2固定主机向移动主机发送IP数据报 6.2.3移动主机向固定主机发送IP数据报 6.2.4同址转交地址&#xff08;简单了解&#xff09; 6.2.5三角形路由问题&#xff08;简单了解&#xff09; 6.1 移…

事关你“吃住行游购娱”的12项安全国标图解来了

标准是安全建设的“尺子”。近期&#xff0c;国家市场监督管理总局、国家标准化管理委员会发布中华人民共和国国家标准公告&#xff08;2022年第13号&#xff09;&#xff0c;全国信息安全标准化技术委员会归口的14项网络安全国家标准获批发布&#xff0c;其中12项涉及数据安全…

不同类型单板布线策略6大类

类型一PCB布线策略 一 &#xff0c;类型一主要特征如下&#xff1a; 严格的长度规则、严格的串扰规则、拓扑规则、差分规则、电源地规则等。 二&#xff0c;关键网络的处理&#xff1a;总线定义Class&#xff1b; 要求满足一定的拓扑结构、stub及其长度&#xff08;时域&a…

关于模型中的R方

1、一元线性回归 R方在一元线性回归模型中&#xff0c;衡量【响应变量X和预测变量Y】的线性关系。 R方cor&#xff08;X,Y)^2 但是&#xff0c;在多元线性回归模型中&#xff0c;因为涉及多个预测变量&#xff0c;全部R方就是衡量响应变量和多个预测变量当中的关系。 而有关…

阿里云张献涛:高性能计算发展的三大趋势

12 月 12-15 日&#xff0c;第十八届 CCF 全国高性能计算学术年会&#xff08;以下简称 CCF HPC China 2022&#xff09;以线上的方式举行&#xff0c;国内外众多知名专家学者&#xff0c;以及高性能计算产业界的头部企业代表云上相聚&#xff0c;探讨高性能计算的发展趋势。阿…

zabbix6.0安装教程(五):二进制包安装

zabbix6.0安装教程&#xff08;五&#xff09;&#xff1a;二进制包安装 目录一、使用ZABBIX官方存储库二、Red Hat zabbix企业版 Linux/CentOS1. 概述2. 安装注意事项2.1 使用 Timescale DB 导入数据2.2 PHP 7.22.3 配置 SELinux3. Proxy 安装3.1 创建数据库3.2 导入数据3.3 为…

计算机网络原理第5章 运输层(12.24完结)

目录~ 5.1 运输层协议概述 5.1.1 进程之间的通信 从通信和信息处理的角度看&#xff0c;运输层向它上面的应用层提供通信服务&#xff0c;它属于面向通信部分的最高层&#xff0c;同时也是用户功能中的最低层。 当网络的边缘部分中的两个主机使用网络的核心部分的功能进行…

再学C语言12:字符串(3)——转换说明

一、转换说明的意义 意义&#xff1a;把存储在计算机中的二进制格式的数值转换成一系列字符&#xff08;一个字符串&#xff09;以便于显示&#xff1b;实质上是翻译说明&#xff0c;并不会替代原值 应该使转换说明与要打印的值的类型相匹配 参数传递机制 float n1; double …

陈都灵现身海南国际电影节,新片《关索岭》票房有望超《阿凡达》

刚送走了厦门金鸡奖&#xff0c;又迎来了海南电影节&#xff0c;第四届国际电影节&#xff0c;已经在美丽的海南岛拉开帷幕。 众多的中国优秀电影人&#xff0c;都欢聚一堂共话未来&#xff0c;为中国电影的发展献言献策&#xff0c;也展现出电影人的精神风貌。 在本届电影节走…

WMS系统这么重要?一文教你找到理想中的WMS系统

无论是在线上还是线下&#xff0c;相信大家都见过各式各样的仓库&#xff0c;或杂乱或整洁&#xff0c;有的还在使用传统的纸单作业模式&#xff0c;有的已经进入全自动化无人作业模式。然而&#xff0c;随着仓储物流行业竞争愈发激烈&#xff0c;以及数智化转型浪潮席卷而来&a…