利用Pytorch实现一个完整的基于深度学习的人脸表情识别项目

本文涉及的产品
视觉智能开放平台,图像资源包5000点
视觉智能开放平台,视频资源包5000点
视觉智能开放平台,分割抠图1万点
简介: 利用Pytorch实现一个完整的基于深度学习的人脸表情识别项目

9c6c95759f9de96d3bc0754b71cef88f.jpg该任务基于图像分类网络Alex实现。


✨1 train脚本

从设备,数据集,模型,优化器,损失函数,进度条,模型评估和参数保存等方面进行总结说明。

🌭1.1 设备

cpu或者单卡gpu

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

多卡gpu待补充…

🍕1.2 数据集

这部分包含数据增强,重载DataSet类,DataLoader打包三项操作,下面一一介绍:

🎆 1.2.1 图像增强

表情识别属于分类任务,数据预处理比较简单:

  1. ToTensor将数据转化为Tensor数据。
  2. RandomResizedCrop将图像裁剪到224的大小(这是网络要求的)。
  3. RandomHorizontalFlip增强图像的泛化性。
  4. Normalize归一化使得数据的分布更加均匀,减少模型学到数据分布的可能性。
data_transform = {
    "train": transforms.Compose([
        transforms.ToTensor(),
        transforms.RandomResizedCrop(224),
        transforms.RandomHorizontalFlip(),
        transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
    ]),
    "val": transforms.Compose([
        transforms.ToTensor(),
        transforms.RandomResizedCrop(224),
        transforms.RandomHorizontalFlip(),
        transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
    ]),
}

需要注意的是,cv2打开的图像数据类型是numpy,不能进行ToTensor之外的图像增强操作。因此,该步必须放在第一个。

🍔1.2.2 MMAFEDB表情识别数据集介绍

百度网盘(5pi5)

22ec56274cc948818acd20892e938541.png

下载数据集并解压后,内容如下:

  1. labels.txt:标签种类
  2. train_list.txtval_list.txtval_list.txt:分别是训练数据,验证数据和测试数据,每条内容未图像路径 标签
  3. 各文件夹名称即分类标签,内部是该分类的图像数据。

🌭1.2.3 重载DataSet

点击此处进入之前总结过的自定义数据集的总结

处理MMAFEDB的详细代码见第二节。导入数据集代码为:

train_dataset = MMAFEDB(root_path, is_type="train", transform=data_transform["train"])
val_dataset = MMAFEDB(root_path, is_type="eval", transform=data_transform["val"])

其中root_pathtxt文件的父路径。is_type可选参数,为"train"或"eval"或"test",即导入的是什么数据。transform是图像增强操作。

🎃1.2.4 DataLoader打包

假设已经创建DataSet的重载类,即数据集导入完成。打包操作为:

# 打包
train_loader = torch.utils.data.DataLoader(
    train_dataset,
    batch_size=512,
    shuffle=True,
    # num_workers=nw,
)
val_loader = torch.utils.data.DataLoader(
    val_dataset,
    batch_size=512,
    shuffle=True
)

更具体的参数见1.2.3链接第二节

🎄1.3 模型

分类模型有很多:Alex,GooleNet,ResNet,MobileNet…这里选用AlexNet,其它后续也会进行尝试,待补充…

🎈1.4 优化器和损失函数

损失函数的一些总结

优化器待补充…梯度下降算法推荐看刘建平老师的博客

这里是使用了Pytorch包装好的Adam优化器和交叉熵损失函数

optimizer = torch.optim.Adam(model.parameters(), lr=0.0002)  # 总结
loss_function = torch.nn.CrossEntropyLoss()

✨1.5 模型及参数的加载和保存

🍕1.5.1 模型的加载和保存

保存模型用到torch.save(model, save_dir)函数,其中model是自定义的模型对象,save_dir是保存路径:

save_dir = ""  # 保存路径,自定义
torch.save(model, save_dir)

而加载该模型应该是:

torch.load(save_path)  # save_path是保存的模型的路径

🎆1.5.2 权重的加载和保存

保存权重分为两步:获取权重和保存参数:

  1. model.state_dict()获取参数:
paramters = model.state_dict()
  1. torch.save保存
torch.save(paramters, save_path)  # save_path是保存路径,自定义

加载模型,仍然用torch.load

paramters = torch.load(save_path)  # save_path是权重文件的保存路径

只是后面,我们需要load_state_dict将参数赋予模型

model.load_state_dict(paramters)

🍔1.6 模型评估

这里先简单采用正确率

    # 验证部分
    model.eval()
    acc = 0.0
    best_acc = 0.0
    with torch.no_grad():
        for i, data in enumerate(val_loader):
            img, label = data
            output = model(img.to(device))
            pred = torch.max(output, dim=1)[1]
            acc += torch.eq(pred, label.to(device)).sum().item()  # TODO 1 累加batch个中预测和标签一致的数量
    acc = acc / len(val_dataset)  # TODO 2 所有数据acc累加除所有数据的数量
    print("acc: {}".format(acc))
    if acc > best_acc:
        best_acc = acc
        torch.save(model.state_dict(), "./weights/best.pth")

代码中两行注释即正确率的计算方法。

需要注意的是,len(val_dataset)即可得到所有数据的数量,在其它任务中肯定会用到。

✨2 重载DataSet(代码)

from torch.utils.data import Dataset
import os
import cv2
from torchvision import transforms
import torch
class MMAFEDB(Dataset):
    def __init__(self, path: str, is_type: str, transform=None):
        """
        :param path: Parent path of the dataset
        :param transform:
        """
        assert os.path.exists(path), "no path:{}".format(path)
        self.path = path
        self.type = is_type
        self.transform = transform
        self.img_path = []
        self.label = []
        self.load_path()
    def __len__(self):
        return len(self.img_path)
    def __getitem__(self, index):
        img_path = self.img_path[index]
        label = self.label[index]
        img = cv2.imread(img_path)
        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        if self.transform is not None:
            img = self.transform(img)
        label = torch.as_tensor(int(label))
        return img, label
    def load_path(self):
        try:
            if self.type == "train":
                with open(os.path.join(self.path, "train_list.txt"), "r", encoding="utf-8") as file:
                    lines = file.readlines()
            elif self.type == "eval":
                with open(os.path.join(self.path, "val_list.txt"), "r", encoding="utf-8") as file:
                    lines = file.readlines()
            elif self.type == "test":
                with open(os.path.join(self.path, "test_list.txt"), "r", encoding="utf-8") as file:
                    lines = file.readlines()
        except FileExistsError as e:
            print(e)
        for line in lines:
            img_path, cl = line.split()
            img_path = os.path.join(self.path, img_path)
            self.img_path.append(img_path)
            self.label.append(cl)
if __name__ == "__main__":
    data_transform = {
        "train": transforms.Compose([
            transforms.ToTensor(),
            transforms.RandomResizedCrop(224),
            transforms.RandomHorizontalFlip(),
            transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
        ]),
        "val": "",
    }
    dataset = MMAFEDB("E:/DataSet/MMAFEDB", is_type="train", transform=data_transform["train"])
    for data in dataset:
        print(2)

if __name__ == "__main__"中是用以测试的代码,首要关注MMAFEDB类:

  1. load_path函数将txt文件中的图片数据路径和label提取出来,存入self.img_pathself.label

5cb75b015cfb43a195b5d1d9afe68c74.png__getitem__函数通过index,提取一张图像和对应label。然后进行图像增强操作(img = self.transform(img)),通过label = torch.as_tensor(int(label))将label的数据类型转化为Tensor。这里主要用as_tensor而不是to_tensor,主要是因为to_tensor会将数据除255,as_tensor数据保持不变。因此to_Tensor用于image,给image进行归一化。as_Tensor用于label,保持原有标签。

✨ 4 一些注意点

  1. 模型to设备时不用多赋予一次值,即不用model = model.to(device),只需要执行model.to(device)即可。
  2. 训练前优化器权重要清零optimizer.zero_grad()
  3. 利用model和loss_functional计算式,设备必须统一,数据类型也必须是张量。
  4. model.train()model.eval()作用是开启/关闭dropout和BN操作,如果没有使用与否没有区别。
  5. with torch.no_grad()关闭自动求导,验证时必须开启。


相关文章
|
1月前
|
机器学习/深度学习 监控 PyTorch
深度学习工程实践:PyTorch Lightning与Ignite框架的技术特性对比分析
在深度学习框架的选择上,PyTorch Lightning和Ignite代表了两种不同的技术路线。本文将从技术实现的角度,深入分析这两个框架在实际应用中的差异,为开发者提供客观的技术参考。
52 7
|
2月前
|
机器学习/深度学习 算法 PyTorch
深度学习笔记(十三):IOU、GIOU、DIOU、CIOU、EIOU、Focal EIOU、alpha IOU、SIOU、WIOU损失函数分析及Pytorch实现
这篇文章详细介绍了多种用于目标检测任务中的边界框回归损失函数,包括IOU、GIOU、DIOU、CIOU、EIOU、Focal EIOU、alpha IOU、SIOU和WIOU,并提供了它们的Pytorch实现代码。
366 1
深度学习笔记(十三):IOU、GIOU、DIOU、CIOU、EIOU、Focal EIOU、alpha IOU、SIOU、WIOU损失函数分析及Pytorch实现
|
3月前
|
机器学习/深度学习 PyTorch 调度
在Pytorch中为不同层设置不同学习率来提升性能,优化深度学习模型
在深度学习中,学习率作为关键超参数对模型收敛速度和性能至关重要。传统方法采用统一学习率,但研究表明为不同层设置差异化学习率能显著提升性能。本文探讨了这一策略的理论基础及PyTorch实现方法,包括模型定义、参数分组、优化器配置及训练流程。通过示例展示了如何为ResNet18设置不同层的学习率,并介绍了渐进式解冻和层适应学习率等高级技巧,帮助研究者更好地优化模型训练。
223 4
在Pytorch中为不同层设置不同学习率来提升性能,优化深度学习模型
|
2月前
|
机器学习/深度学习 人工智能 算法
【玉米病害识别】Python+卷积神经网络算法+人工智能+深度学习+计算机课设项目+TensorFlow+模型训练
玉米病害识别系统,本系统使用Python作为主要开发语言,通过收集了8种常见的玉米叶部病害图片数据集('矮花叶病', '健康', '灰斑病一般', '灰斑病严重', '锈病一般', '锈病严重', '叶斑病一般', '叶斑病严重'),然后基于TensorFlow搭建卷积神经网络算法模型,通过对数据集进行多轮迭代训练,最后得到一个识别精度较高的模型文件。再使用Django搭建Web网页操作平台,实现用户上传一张玉米病害图片识别其名称。
78 0
【玉米病害识别】Python+卷积神经网络算法+人工智能+深度学习+计算机课设项目+TensorFlow+模型训练
|
3月前
|
机器学习/深度学习 人工智能 算法
【新闻文本分类识别系统】Python+卷积神经网络算法+人工智能+深度学习+计算机毕设项目+Django网页界面平台
文本分类识别系统。本系统使用Python作为主要开发语言,首先收集了10种中文文本数据集("体育类", "财经类", "房产类", "家居类", "教育类", "科技类", "时尚类", "时政类", "游戏类", "娱乐类"),然后基于TensorFlow搭建CNN卷积神经网络算法模型。通过对数据集进行多轮迭代训练,最后得到一个识别精度较高的模型,并保存为本地的h5格式。然后使用Django开发Web网页端操作界面,实现用户上传一段文本识别其所属的类别。
117 1
【新闻文本分类识别系统】Python+卷积神经网络算法+人工智能+深度学习+计算机毕设项目+Django网页界面平台
|
2月前
|
机器学习/深度学习 算法 数据可视化
如果你的PyTorch优化器效果欠佳,试试这4种深度学习中的高级优化技术吧
在深度学习领域,优化器的选择对模型性能至关重要。尽管PyTorch中的标准优化器如SGD、Adam和AdamW被广泛应用,但在某些复杂优化问题中,这些方法未必是最优选择。本文介绍了四种高级优化技术:序列最小二乘规划(SLSQP)、粒子群优化(PSO)、协方差矩阵自适应进化策略(CMA-ES)和模拟退火(SA)。这些方法具备无梯度优化、仅需前向传播及全局优化能力等优点,尤其适合非可微操作和参数数量较少的情况。通过实验对比发现,对于特定问题,非传统优化方法可能比标准梯度下降算法表现更好。文章详细描述了这些优化技术的实现过程及结果分析,并提出了未来的研究方向。
39 1
|
2月前
|
机器学习/深度学习 算法框架/工具 Python
基于深度学习的手写数字识别项目GUI(Deep Learning Project – Handwritten Digit Recognition using Python)
基于深度学习的手写数字识别项目GUI(Deep Learning Project – Handwritten Digit Recognition using Python)
113 0
|
3月前
|
机器学习/深度学习 人工智能 算法
【果蔬识别系统】Python+卷积神经网络算法+人工智能+深度学习+计算机毕设项目+Django网页界面平台
【果蔬识别系统】Python+卷积神经网络算法+人工智能+深度学习+计算机毕设项目+Django网页界面平台。果蔬识别系统,本系统使用Python作为主要开发语言,通过收集了12种常见的水果和蔬菜('土豆', '圣女果', '大白菜', '大葱', '梨', '胡萝卜', '芒果', '苹果', '西红柿', '韭菜', '香蕉', '黄瓜'),然后基于TensorFlow库搭建CNN卷积神经网络算法模型,然后对数据集进行训练,最后得到一个识别精度较高的算法模型,然后将其保存为h5格式的本地文件方便后期调用。再使用Django框架搭建Web网页平台操作界面,实现用户上传一张果蔬图片识别其名称。
70 0
【果蔬识别系统】Python+卷积神经网络算法+人工智能+深度学习+计算机毕设项目+Django网页界面平台
|
3月前
|
机器学习/深度学习 数据挖掘 PyTorch
🎓PyTorch深度学习入门课:编程小白也能玩转的高级数据分析术
踏入深度学习领域,即使是编程新手也能借助PyTorch这一强大工具,轻松解锁高级数据分析。PyTorch以简洁的API、动态计算图及灵活性著称,成为众多学者与工程师的首选。本文将带你从零开始,通过环境搭建、构建基础神经网络到进阶数据分析应用,逐步掌握PyTorch的核心技能。从安装配置到编写简单张量运算,再到实现神经网络模型,最后应用于图像分类等复杂任务,每个环节都配有示例代码,助你快速上手。实践出真知,不断尝试和调试将使你更深入地理解这些概念,开启深度学习之旅。
50 1
|
2月前
|
机器学习/深度学习 数据采集 自然语言处理
【NLP自然语言处理】基于PyTorch深度学习框架构建RNN经典案例:构建人名分类器
【NLP自然语言处理】基于PyTorch深度学习框架构建RNN经典案例:构建人名分类器

热门文章

最新文章