【机器学习合集】人脸表情分类任务Pytorch实现TensorBoardX的使用 ->(个人学习记录笔记)

人脸表情分类任务

  • 注意:整个项目来自阿里云天池,下面是开发人员的联系方式,本人仅作为学习记录!!!
  • 该文章原因,学习该项目,完善注释内容,针对新版本的Pytorch进行部分代码调整
  • 本文章采用pytorch2.0.1版本,python3.10版本

源码链接

这是一个使用pytorch实现的简单的2分类任务
项目结构:- net.py: 网络定义脚本- train.py:模型训练脚本- inference.py:模型推理脚本- run_train.sh 训练可执行文件- run_inference.sh 推理可执行文件# Copyright 2019 longpeng2008. All Rights Reserved.
# Licensed under the Apache License, Version 2.0 (the "License");
# If you find any problem,please contact us longpeng2008to2012@gmail.com 

1. 网络结构

# coding:utf8import torch
import torch.nn as nn
import torch.nn.functional as F
import numpy as np# 3层卷积神经网络simpleconv3定义
# 包括3个卷积层,3个BN层,3个ReLU激活层,3个全连接层class simpleconv3(nn.Module):# 初始化函数def __init__(self, nclass):# 继承父类super(simpleconv3, self).__init__()# 3通道 输入图片大小为3*48*48,输出特征图大小为12*23*23,卷积核大小为3*3,步长为2'''输出特征图大小 = [(输入大小 - 卷积核大小) / 步长] + 1输入大小是 48x48卷积核大小是 3x3步长是 2将这些值代入公式,您将得到输出特征图的大小:输出特征图大小 = [(48 - 3) / 2] + 1 = (45 / 2) + 1 = 22.5 + 1 = 23'''self.conv1 = nn.Conv2d(3, 12, 3, 2)# 批量标准化操作 12个特征通道self.bn1 = nn.BatchNorm2d(12)# 输入图片大小为12*23*23,输出特征图大小为24*11*11,卷积核大小为3*3,步长为2'''输出特征图大小 = [(输入大小 - 卷积核大小) / 步长] + 1输入大小是 23x23卷积核大小是 3x3步长是 2将这些值代入公式,您将得到输出特征图的大小:输出特征图大小 = [(23 - 3) / 2] + 1 = (20 / 2) + 1 = 10 + 1 = 11'''self.conv2 = nn.Conv2d(12, 24, 3, 2)# 批量标准化操作 24个特征通道self.bn2 = nn.BatchNorm2d(24)# 输入图片大小为24*11*11,输出特征图大小为48*5*5,卷积核大小为3*3,步长为2'''输出特征图大小 = [(输入大小 - 卷积核大小) / 步长] + 1输入大小是 11x11卷积核大小是 3x3步长是 2将这些值代入公式,您将得到输出特征图的大小:输出特征图大小 = [(11 - 3) / 2] + 1 = (8 / 2) + 1 = 4 + 1 = 5'''self.conv3 = nn.Conv2d(24, 48, 3, 2)# 批量标准化操作 48个特征通道self.bn3 = nn.BatchNorm2d(48)# 输入向量长为48*5*5=1200,输出向量长为1200 展平self.fc1 = nn.Linear(48 * 5 * 5, 1200)# 1200 -> 128self.fc2 = nn.Linear(1200, 128)  # 输入向量长为1200,输出向量长为128# 128 -> 类别数self.fc3 = nn.Linear(128, nclass)  # 输入向量长为128,输出向量长为nclass,等于类别数# 前向函数def forward(self, x):# relu函数,不需要进行实例化,直接进行调用# conv,fc层需要调用nn.Module进行实例化# 先卷积后标准化再激活x = F.relu(self.bn1(self.conv1(x)))x = F.relu(self.bn2(self.conv2(x)))x = F.relu(self.bn3(self.conv3(x)))# 更改形状 改为1维x = x.view(-1, 48 * 5 * 5)# 全连接再激活x = F.relu(self.fc1(x))x = F.relu(self.fc2(x))x = self.fc3(x)return xif __name__ == '__main__':import torchx = torch.randn(1, 3, 48, 48)model = simpleconv3(2)y = model(x)print(model)'''simpleconv3((conv1): Conv2d(3, 12, kernel_size=(3, 3), stride=(2, 2))(bn1): BatchNorm2d(12, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv2): Conv2d(12, 24, kernel_size=(3, 3), stride=(2, 2))(bn2): BatchNorm2d(24, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv3): Conv2d(24, 48, kernel_size=(3, 3), stride=(2, 2))(bn3): BatchNorm2d(48, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(fc1): Linear(in_features=1200, out_features=1200, bias=True)(fc2): Linear(in_features=1200, out_features=128, bias=True)(fc3): Linear(in_features=128, out_features=2, bias=True))'''

2. 训练函数

部分代码内容与作者不同

  • scheduler.step()与optimizer.step()修改前后顺序
  • RandomSizedCrop改为RandomCrop
  • transforms.Scale修改为transforms.Resize
# coding:utf8
from __future__ import print_function, division
import os
import torch
import torch.nn as nn
import torch.optim as optim
# 使用tensorboardX进行可视化
from tensorboardX import SummaryWriter
from torch.optim import lr_scheduler
from torchvision import datasets, transformsfrom net import simpleconv3writer = SummaryWriter('logs')  # 创建一个SummaryWriter的示例,默认目录名字为runs# 训练主函数
def train_model(model, criterion, optimizer, scheduler, num_epochs=25):"""训练模型Args:model: 模型criterion: loss函数optimizer: 优化器scheduler: 学习率调度器num_epochs: 训练轮次Returns:"""# 开始训练for epoch in range(num_epochs):# 打印训练轮次print(f'Epoch {epoch+1}/{num_epochs}')for phase in ['train', 'val']:if phase == 'train':# 设置为训练模式model.train(True)else:# 设置为验证模式model.train(False)# 损失变量running_loss = 0.0# 精度变量running_accs = 0.0number_batch = 0# 从dataloaders中获得数据for data in dataloaders[phase]:inputs, labels = dataif use_gpu:inputs = inputs.cuda()labels = labels.cuda()# 清空梯度optimizer.zero_grad()# 前向运行outputs = model(inputs)# 使用max()函数对输出值进行操作,得到预测值索引_, preds = torch.max(outputs.data, 1)# 计算损失loss = criterion(outputs, labels)if phase == 'train':# 误差反向传播loss.backward()# 参数更新optimizer.step()running_loss += loss.data.item()running_accs += torch.sum(preds == labels).item()number_batch += 1# 调整学习率scheduler.step()# 得到每一个epoch的平均损失与精度epoch_loss = running_loss / number_batchepoch_acc = running_accs / dataset_sizes[phase]# 收集精度和损失用于可视化if phase == 'train':writer.add_scalar('data/trainloss', epoch_loss, epoch)writer.add_scalar('data/trainacc', epoch_acc, epoch)else:writer.add_scalar('data/valloss', epoch_loss, epoch)writer.add_scalar('data/valacc', epoch_acc, epoch)print('{} Loss: {:.4f} Acc: {:.4f}'.format(phase, epoch_loss, epoch_acc))writer.close()return modelif __name__ == '__main__':# 图像统一缩放大小image_size = 60# 图像裁剪大小,即训练输入大小crop_size = 48# 分类类别数nclass = 2# 创建模型model = simpleconv3(nclass)# 数据目录data_dir = './data'# 模型缓存接口if not os.path.exists('models'):os.mkdir('models')# 检查GPU是否可用,如果是使用GPU,否使用CPUuse_gpu = torch.cuda.is_available()if use_gpu:model = model.cuda()print(model)# 创建数据预处理函数,训练预处理包括随机裁剪缩放、随机翻转、归一化,验证预处理包括中心裁剪,归一化data_transforms = {'train': transforms.Compose([transforms.RandomCrop(48),  # 随机大小、长宽比裁剪图片size=48 RandomSizedCrop改为RandomCroptransforms.RandomHorizontalFlip(),  # 随机水平翻转 默认概率p=0.5transforms.ToTensor(),  # 将原始的PILImage格式或者numpy.array格式的数据格式化为可被pytorch快速处理的张量类型transforms.Normalize([0.5, 0.5, 0.5], [0.5, 0.5, 0.5])  # 数据标准化 要将图像三个通道的数据 整理到 [-1,1] 之间 ,可以加快模型的收敛]),'val': transforms.Compose([transforms.Resize(64),  # Scale用于调整图像的大小,现在采用transforms.Resize()代替transforms.CenterCrop(48),  # 从图像中心裁剪图片尺寸size=48transforms.ToTensor(),transforms.Normalize([0.5, 0.5, 0.5], [0.5, 0.5, 0.5])]),}# 使用torchvision的dataset ImageFolder接口读取数据image_datasets = {x: datasets.ImageFolder(os.path.join(data_dir, x), data_transforms[x]) for x in ['train', 'val']}# 创建数据指针,设置batch大小,shuffle,多进程数量dataloaders = {x: torch.utils.data.DataLoader(image_datasets[x],batch_size=16,  # 每个小批次包含16个样本shuffle=True,   # 是否随机打乱数据num_workers=4)  # 加载数据的子进程数for x in ['train', 'val']}# 获得数据集大小dataset_sizes = {x: len(image_datasets[x]) for x in ['train', 'val']}# 优化目标使用交叉熵,优化方法使用带动量项的SGD,学习率迭代策略为step,每隔100个epoch,变为原来的0.1倍criterion = nn.CrossEntropyLoss()# 优化器 传入权重阈值,学习率0.1 动量(momentum)是一个控制梯度下降方向的超参数。# 它有助于加速训练,特别是在存在平坦区域或局部极小值时。动量的值通常在0到1之间。较大的动量值会使参数更新更平滑。在这里,动量设置为0.9。optimizer_ft = optim.SGD(model.parameters(), lr=0.1, momentum=0.9)'''lr_scheduler.StepLR 是PyTorch中的学习率调度器(learning rate scheduler),用于在训练神经网络时动态调整学习率。lr_scheduler.StepLR 允许您在训练的不同阶段逐步减小学习率,以帮助优化过程。optimizer_ft:这是您用于优化模型参数的优化器,通常是 optim.SGD 或其他PyTorch优化器的实例。学习率调度器将监控这个优化器的状态,并根据其规则更新学习率。step_size=100:这是学习率更新的周期,也称为学习率下降步数。在每个 step_size 个训练周期之后,学习率将减小。gamma=0.1:这是学习率减小的因子。在每个 step_size 个训练周期之后,学习率将乘以 gamma。这意味着学习率将以 gamma 的倍数逐步减小。'''exp_lr_scheduler = lr_scheduler.StepLR(optimizer_ft, step_size=100, gamma=0.1)model = train_model(model=model,criterion=criterion,optimizer=optimizer_ft,scheduler=exp_lr_scheduler,num_epochs=10)torch.save(model.state_dict(), 'models/model.pt')

3. 预测

执行以下内容,或者自行安排数据集

## 使用方法 python3 inference.py 模型路径 图片路径
python3 inference.py models/model.pt data/train/0/1neutral.jpg
python3 inference.py models/model.pt data/train/1/1smile.jpg
# coding:utf8import sys
import numpy as np
import torch
from PIL import Image
from torchvision import transforms# 全局变量
# sys.argv[1] 权重文件
# sys.argv[2] 图像文件夹testsize = 48  # 测试图大小
from net import simpleconv3# 定义模型
net = simpleconv3(2)
# 设置推理模式,使得dropout和batchnorm等网络层在train和val模式间切换
net.eval()
# 停止autograd模块的工作,以起到加速和节省显存
torch.no_grad()# 载入模型权重
modelpath = sys.argv[1]
net.load_state_dict(torch.load(modelpath, map_location=lambda storage, loc: storage))# 定义预处理函数
data_transforms = transforms.Compose([transforms.Resize(48),transforms.ToTensor(),transforms.Normalize([0.5, 0.5, 0.5], [0.5, 0.5, 0.5])])# 读取3通道图片,并扩充为4通道tensor
imagepath = sys.argv[2]
image = Image.open(imagepath)
imgblob = data_transforms(image).unsqueeze(0)# 获得预测结果predict,得到预测的标签值label
predict = net(imgblob)
index = np.argmax(predict.detach().numpy())
# print(predict)
# print(index)if index == 0:print('the predict of ' + sys.argv[2] + ' is ' + str('none'))
else:print('the predict of ' + sys.argv[2] + ' is ' + str('smile'))

4. TensorBoardX的使用

TensorBoardX 是一个用于在 PyTorch 中可视化训练过程和结果的工具。它是 TensorBoard 的 Python 版本,用于创建交互式、实时的训练和评估图表。以下是一些使用 TensorBoardX 的一般步骤:

  1. 安装 TensorBoardX:首先,您需要安装 TensorBoardX 库。您可以使用以下命令安装它:

    pip install tensorboardX
    
  2. 导入库:在您的 PyTorch 代码中,导入 TensorBoardX 库:

    from tensorboardX import SummaryWriter
    
  3. 创建 SummaryWriter:创建一个 SummaryWriter 对象,以将日志数据写入 TensorBoard 日志目录。

    writer = SummaryWriter()
    
  4. 记录数据:在训练循环中,使用 writer.add_* 方法来记录各种数据,例如标量、图像、直方图等。以下是一些示例:

    • 记录标量数据:

      writer.add_scalar('loss', loss, global_step)
      
    • 记录图像数据:

      writer.add_image('image', image, global_step)
      
    • 记录直方图数据:

      writer.add_histogram('weights', model.conv1.weight, global_step)
      
    • 记录文本数据:

      writer.add_text('description', 'This is a description.', global_step)
      
  5. 启动 TensorBoard 服务器:在命令行中,使用以下命令启动 TensorBoard 服务器:

    tensorboard --logdir=/path/to/log/directory
    

    其中 /path/to/log/directory 是存储 TensorBoardX 日志的目录。

  6. 查看可视化结果:在浏览器中打开 TensorBoard 的 Web 界面,通常位于 http://localhost:6006,您可以在该界面上查看可视化结果。

请注意,您可以根据需要记录不同类型的数据,并根据训练过程的不同阶段定期记录数据。TensorBoardX 提供了丰富的可视化工具,以帮助您监视和分析模型的训练过程。

确保在训练循环中适时记录数据,并使用 TensorBoardX 查看结果,以更好地理解和改进您的深度学习模型。


这是 TensorBoard 启动时的一般信息,表明TensorBoard运行在本地主机(localhost)。如果您想使 TensorBoard 可以在网络上访问,可以采取以下几种方法:

  1. 使用代理:您可以使用代理服务器来将 TensorBoard 的端口暴露到网络上。这通常需要在代理服务器上进行一些配置,以便外部用户可以访问 TensorBoard。代理服务器可以是诸如 Nginx 或 Apache 之类的 Web 服务器。

  2. 使用 --bind_all 参数:在启动 TensorBoard 时,您可以使用 --bind_all 参数,以将 TensorBoard 绑定到所有网络接口。这样,TensorBoard 将可以在本地网络上的任何 IP 地址上访问,而不仅仅是本地主机。例如:

    tensorboard --logdir=/path/to/log/directory --bind_all
    
  3. 使用 --host 参数:您还可以使用 --host 参数来指定 TensorBoard 的主机名(hostname),以使其在指定的主机上可用。例如:

    tensorboard --logdir=/path/to/log/directory --host=0.0.0.0
    

    这将允许 TensorBoard 在所有网络接口上运行,从而在网络上的任何 IP 地址上访问。

请根据您的需求和网络设置选择适当的方法。如果只需要在本地访问 TensorBoard,无需进行任何更改。如果需要在网络上访问,可以使用上述选项之一。不过,请注意,为了安全起见,最好将 TensorBoard 限制在受信任的网络上,或者使用身份验证和授权来保护访问。


效果展示
在这里插入图片描述

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

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

相关文章

快速入门Elasticsearch:安装、基本概念、分词器和文档基本操作详解

本文主要介绍快速入门 Elasticsearch,从 安装 、 基本概念 、 分词器 、*** 文档基本操作 *** 这 4 个方面快速入门。 Elasticsearch 是一款近实时的搜索引擎,底层是基于 Lucene 做搜索,再此基础上加入了分布式的特性,以便支持海…

2022年12月 Python(一级)真题解析#中国电子学会#全国青少年软件编程等级考试

Python等级考试(1~6级)全部真题・点这里 一、单选题(共25题,每题2分,共50分) 第1题 关于Python语言的注释,以下选项中描述错误的是?( ) A: Python语言有两种注释方式:单行注释和多行注释 B: Python语言的单行注释以#开头 C: Python多行注释使用###来做为标记 D: …

RabbitMQ高级篇 笔记

这是一些高级的内容。 RabbitMQ还是运行在网络上的,倘若遇到了网络故障,mq自己挂了,出异常了,都会造成最终状态不一致的问题。这就是可靠性问题。 可靠性:一个消息发送出去之后,至少被消费1次。 要解决这3个…

十九、类型信息(1)

本章概要 为什么需要 RTTI RTTI(RunTime Type Information,运行时类型信息)能够在程序运行时发现和使用类型信息 RTTI 把我们从只能在编译期进行面向类型操作的禁锢中解脱了出来,并且让我们可以使用某些非常强大的程序。对 RTTI …

Hadoop分布式安装

首先准备好三台服务器或者虚拟机,我本机安装了三个虚拟机,安装虚拟机的步骤参考我之前的一篇 virtualBox虚拟机安装多个主机访问虚拟机虚拟机访问外网配置-CSDN博客 jdk安装 参考文档:Linux 环境下安装JDK1.8并配置环境变量_linux安装jdk1.8并…

Zoho Mail荣登福布斯2023年企业邮箱榜单,引领行业新方向!

几十年来,电子邮件一直是电子通信的重要形式,并且在未来的许多年里,它可能会无处不在。尽管有大量免费电子邮件服务可供用户和企业使用,但其中许多服务缺乏专门的功能,例如适合办公室使用的集中管理。 福布斯小型企业顾…

1024特别剪辑: 使用Python Turtle 库绘制一棵随机生成的树

🎈个人主页:🎈 :✨✨✨初阶牛✨✨✨ 🐻强烈推荐优质专栏: 🍔🍟🌯C的世界(持续更新中) 🐻推荐专栏1: 🍔🍟🌯C语言初阶 🐻推荐专栏2: 🍔…

MYSQL(事务+锁+MVCC+SQL执行流程)理解(2)

一)MYSQL中的锁(知识补充) 可以通过In_use字段来进行判断是否针对于表进行加了锁 1)对于undo log日志来说:新增类型的,在事务提交之后就可以清除掉了,修改类型的,事务提交之后不能立即清除掉这些日志会用于mvcc只有当没有事务用到该版本信息时…

【原创】解决Kotlin无法使用@Slf4j注解的问题

前言 主要还是辟谣之前的网上的用法,当然也会给出最终的使用方法。这可是Kotlin,关Slf4j何事!? 辟谣内容:创建注解来解决这个问题 例如: Target(AnnotationTarget.CLASS) Retention(AnnotationRetentio…

Spark内核调度

目录 一、DAG (1)概念 (2)Job和Action关系 (3)DAG的宽窄依赖关系和阶段划分 二、Spark内存迭代计算 三、spark的并行度 (1)并行度设置 (2)集群中如何规划并…

javascript IP地址正则表达式

/^(1[0-9]{2}|2[0-4][0-9]|25[0-5]|(\d){1,2})\.(1[0-9]{2}|2[0-4][0-9]|25[0-5]|(\d){1,2}|0)\.(1[0-9]{2}|2[0-4][0-9]|25[0-5]|(\d){1,2}|0)\.(1[0-9]{2}|2[0-4][0-9]|25[0-5]|(\d){1,2}|0)$/g.test(10.2.35.8) 注: 一定不要把表达式赋值给变量,直接…

FPGA/SoC控制机械臂

FPGA/SoC控制机械臂 机器人技术处于工业 4.0、人工智能和边缘革命的前沿。让我们看看如何创建 FPGA 控制的机器人手臂。 介绍 机器人技术与人工智能和机器学习一起处于工业 4.0 和边缘革命的最前沿。 因此,我认为创建一个基础机器人手臂项目会很有趣,我们…

听GPT 讲Rust源代码--library/std(3)

rust标准库std中的src目录主要包含以下内容和模块: alloc:内存分配相关函数,比如alloc::boxed::Box、alloc::string::String等。 ascii:ASCII相关工具函数。 char:字符相关类型和函数,如Char、char等。 cmp:比较相关trait和函数,如Ord、Eq、PartialOrd等。 env:环境变量相关功能…

什么是React中的有状态组件(stateful component)和无状态组件(stateless component)?

聚沙成塔每天进步一点点 ⭐ 专栏简介 前端入门之旅:探索Web开发的奇妙世界 欢迎来到前端入门之旅!感兴趣的可以订阅本专栏哦!这个专栏是为那些对Web开发感兴趣、刚刚踏入前端领域的朋友们量身打造的。无论你是完全的新手还是有一些基础的开发…

微信小程序如何跳转页面

1.wx.navigateTo:用于跳转到其他页面,并保留当前页面。通过该 API 跳转后,可以通过返回按钮回到原页面。 wx.navigateTo({url: /pages/otherPage/otherPage })2.wx.redirectTo:用于跳转到其他页面,并关闭当前页面。通…

Linux中关于glibc包导致的服务器死机或者linux命令无法使用的情况

glibc是gnu发布的libc库,即c运行库。glibc是linux系统中最底层的api,几乎其它任何运行库都会依赖于glibc。glibc除了封装linux操作系统所提供的系统服务外,它本身也提供了许多其它一些必要功能服务的实现。由于 glibc 囊括了几乎所有的 UNIX …

量子计算与量子密码(入门级)

量子计算与量子密码 写在最前面一些可能带来的有趣的知识和潜在的收获 1、Introduction导言四个特性不确定性(自由意志论)Indeterminism不确定性Uncertainty叠加原理(线性)superposition (linearity)纠缠entanglement 虚数的常见基本运算欧拉公式&#x…

基于C/C++的UG二次开发流程

文章目录 基于C/C的UG二次开发流程1 环境搭建1.1 新建工程1.2 项目属性设置1.3 添加入口函数并生成dll文件1.4 执行程序1.5 ufsta入口1.5.1 创建程序部署目录结构1.5.2 创建菜单文件1.5.3 设置系统环境变量1.5.4 制作对话框1.5.5 创建代码1.5.6 部署和执行 基于C/C的UG二次开发…

hypercube背景设置为白色,绘制高光谱3D立方体

import scipy pip install wxpython PyOpenGL和Spectral需要本地安装 可参考链接https://blog.csdn.net/qq_43204333/article/details/119837870 参考:https://blog.csdn.net/Tiandailan/article/details/132719745?spm1001.2014.3001.5506Mouse Functions:left-cl…

看完这篇 教你玩转渗透测试靶机Vulnhub——Hacksudo: Aliens

Vulnhub靶机Bluemoon: 2021渗透测试详解 Vulnhub靶机介绍:Vulnhub靶机下载:Vulnhub靶机安装:Vulnhub靶机漏洞详解:①:信息收集:②:数据库后台传木马:③:反弹shell&#x…