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

本文涉及的产品
视觉智能开放平台,分割抠图1万点
视觉智能开放平台,图像资源包5000点
视觉智能开放平台,视频资源包5000点
简介: 利用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 TensorFlow
深度学习工具和框架详细指南:PyTorch、TensorFlow、Keras
在深度学习的世界中,PyTorch、TensorFlow和Keras是最受欢迎的工具和框架,它们为研究者和开发者提供了强大且易于使用的接口。在本文中,我们将深入探索这三个框架,涵盖如何用它们实现经典深度学习模型,并通过代码实例详细讲解这些工具的使用方法。
|
5天前
|
机器学习/深度学习 人工智能 自然语言处理
ModelScope深度学习项目低代码开发
低代码开发平台通过丰富的预训练模型库、高度灵活的预训练模型和强大的微调训练功能,简化深度学习项目开发。以阿里魔搭为例,提供大量预训练模型,支持快速迭代与实时反馈,减少从头训练的时间和资源消耗。开发者可轻松调整模型参数,适应特定任务和数据集,提升模型性能。ModelScope平台进一步增强这些功能,提供模型搜索、体验、管理与部署、丰富的模型和数据资源、多模态任务推理及社区协作,助力高效、环保的AI开发。
147 65
|
15天前
|
机器学习/深度学习 数据可视化 算法
PyTorch生态系统中的连续深度学习:使用Torchdyn实现连续时间神经网络
神经常微分方程(Neural ODEs)是深度学习领域的创新模型,将神经网络的离散变换扩展为连续时间动力系统。本文基于Torchdyn库介绍Neural ODE的实现与训练方法,涵盖数据集构建、模型构建、基于PyTorch Lightning的训练及实验结果可视化等内容。Torchdyn支持多种数值求解算法和高级特性,适用于生成模型、时间序列分析等领域。
162 77
PyTorch生态系统中的连续深度学习:使用Torchdyn实现连续时间神经网络
|
3月前
|
机器学习/深度学习 监控 PyTorch
深度学习工程实践:PyTorch Lightning与Ignite框架的技术特性对比分析
在深度学习框架的选择上,PyTorch Lightning和Ignite代表了两种不同的技术路线。本文将从技术实现的角度,深入分析这两个框架在实际应用中的差异,为开发者提供客观的技术参考。
76 7
|
4月前
|
机器学习/深度学习 算法框架/工具 Python
基于深度学习的手写数字识别项目GUI(Deep Learning Project – Handwritten Digit Recognition using Python)
基于深度学习的手写数字识别项目GUI(Deep Learning Project – Handwritten Digit Recognition using Python)
144 0
|
4月前
|
机器学习/深度学习 人工智能 算法
【玉米病害识别】Python+卷积神经网络算法+人工智能+深度学习+计算机课设项目+TensorFlow+模型训练
玉米病害识别系统,本系统使用Python作为主要开发语言,通过收集了8种常见的玉米叶部病害图片数据集('矮花叶病', '健康', '灰斑病一般', '灰斑病严重', '锈病一般', '锈病严重', '叶斑病一般', '叶斑病严重'),然后基于TensorFlow搭建卷积神经网络算法模型,通过对数据集进行多轮迭代训练,最后得到一个识别精度较高的模型文件。再使用Django搭建Web网页操作平台,实现用户上传一张玉米病害图片识别其名称。
104 0
【玉米病害识别】Python+卷积神经网络算法+人工智能+深度学习+计算机课设项目+TensorFlow+模型训练
|
4月前
|
机器学习/深度学习 算法 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实现代码。
626 1
深度学习笔记(十三):IOU、GIOU、DIOU、CIOU、EIOU、Focal EIOU、alpha IOU、SIOU、WIOU损失函数分析及Pytorch实现
|
4月前
|
机器学习/深度学习 算法 数据可视化
如果你的PyTorch优化器效果欠佳,试试这4种深度学习中的高级优化技术吧
在深度学习领域,优化器的选择对模型性能至关重要。尽管PyTorch中的标准优化器如SGD、Adam和AdamW被广泛应用,但在某些复杂优化问题中,这些方法未必是最优选择。本文介绍了四种高级优化技术:序列最小二乘规划(SLSQP)、粒子群优化(PSO)、协方差矩阵自适应进化策略(CMA-ES)和模拟退火(SA)。这些方法具备无梯度优化、仅需前向传播及全局优化能力等优点,尤其适合非可微操作和参数数量较少的情况。通过实验对比发现,对于特定问题,非传统优化方法可能比标准梯度下降算法表现更好。文章详细描述了这些优化技术的实现过程及结果分析,并提出了未来的研究方向。
73 1
|
4月前
|
机器学习/深度学习 数据采集 自然语言处理
【NLP自然语言处理】基于PyTorch深度学习框架构建RNN经典案例:构建人名分类器
【NLP自然语言处理】基于PyTorch深度学习框架构建RNN经典案例:构建人名分类器
|
1天前
|
机器学习/深度学习 自然语言处理 监控
深入探索:深度学习在时间序列预测中的强大应用与实现
时间序列分析是数据科学和机器学习中一个重要的研究领域,广泛应用于金融市场、天气预报、能源管理、交通预测、健康监控等多个领域。时间序列数据具有顺序相关性,通常展示出时间上较强的依赖性,因此简单的传统回归模型往往不能捕捉其中复杂的动态特征。深度学习通过其非线性建模能力和层次结构的特征提取能力,能够有效地捕捉复杂的时间相关性和非线性动态变化模式,从而在时间序列分析中展现出极大的潜力。

热门文章

最新文章

推荐镜像

更多