人脸表情识别是通过神经网络从图像中提取表情特征,并将表情归为某一类别的学习任务,是分类任务的一种实际应用。它能够更准确地理解用户的情感状态,并提供个性化服务。目前,人脸表情识别技术已经应用于众多领域,如智能交互、虚拟现实等。随着技术的不断发展,深度学习模型将持续优化,不断提高识别准确率和效率,并与其他技术结合,如增强学习、迁移学习等,进一步提升性能,为人机交互带来更好的体验。
01、人脸表情数据准备
在本文中,我们使用JAFFE(The Japanese Female Facial Expression)数据集。该数据集发布于1998年,是一个小型的人脸图像数据集,共包含213张图片。JAFFE数据集选取了10名日本女学生,每个人根据指示在实验环境下做出7种表情,包括:愤怒(Angry,AN)、厌恶(Disgust,DI)、恐惧(Fear,FE)、高兴(Happy,HA)、悲伤(Sad,SA)、惊讶(Surprise,SU)以及中性(Neutral,NE)。
创建项目文件夹后,假设将下载好的数据集放入该项目文件夹中,目录地址为"./jaffe"。根据实验的需要,我们先对数据集进行简单的划分,划分后的地址为"./data/jaffe",后续训练则使用该划分后的目录地址。
首先导入所需要的工具包:
import os
import wandb
import random
import shutil
import torch
import torch.nn as nn
import torchvision.transforms as transforms
from torchvision.datasets import ImageFolder
from torch.utils.data import DataLoader
下面对数据集进行划分。数据集按照4:1的比例分别组成互斥的训练集train和测试集test。训练集和测试集的图片都按照类别分类存储在不同文件夹中,七个不同的类对应七个不同的文件夹。每个类别的图片在训练集和测试集中的比例都是4:1,以保持数据分布的一致性。详细代码如下:
# 对应其中类别
classes = ['NE','HA','AN','DI','FE','SA','SU']
folder_names = ['train', 'test']
# 未划分的数据集地址
src_data_folder = "./jaffe"
# 划分后的数据集保存地址
target_data_folder = "./data/jaffe"
# 划分比例
train_scale = 0.8
# 在目标目录下创建训练集和验证集文件夹
for folder_name in folder_names:
folder_path = os.path.join(target_data_folder, folder_name)
os.mkdir(folder_path)
# 在folder_path目录下创建类别文件夹
for class_name in classes:
class_folder_path = os.path.join(folder_path, class_name)
os.mkdir(class_folder_path)
# 获取所有的图片
files = os.listdir(src_data_folder)
data = [file for file in files if file.endswith('tiff') and not file.startswith('.')]
# 随机打乱图片顺序
random.shuffle(data)
# 统计保存各类图片数量
class_sum = dict.fromkeys(classes, 0)
for file in data:
class_sum[file[3:5]] += 1
# 记录训练集各类别图片的个数
class_train = dict.fromkeys(classes, 0)
# 记录测试集各类别图片的个数
class_test = dict.fromkeys(classes, 0)
# 遍历每个图片划分
for file in data:
# 得到原图片目录地址
src_img_path = os.path.join(src_data_folder, file)
# 如果训练集中该类别个数未达划分数量,则复制图片并分配进入训练集
if class_train[file[3:5]] < class_sum[file[3:5]]*train_scale:
target_img_path = os.path.join(os.path.join(target_data_folder, 'train'), file[3:5])
shutil.copy2(src_img_path, target_img_path)
class_train[file[3:5]] += 1
# 否则,进入测试集
else:
target_img_path = os.path.join(os.path.join(target_data_folder, 'test'), file[3:5])
shutil.copy2(src_img_path, target_img_path)
class_test[file[3:5]] += 1
# 输出标明数据集划分情况
for class_name in classes:
print("-" * 10)
print("{}类共{}张图片,划分完成:".format(class_name, class_sum[class_name]))
print("训练集:{}张,测试集:{}张".format(class_train[class_name], class_test[class_name]))
使用上述代码划分好的数据集格式如图1所示:
图1 数据集划分后的格式
通过调用torchvision.transforms模块,对上述划分的数据集进行预处理,并使用ImageFolder数据加载器加载数据。ImageFolder是一个通用的图像数据加载器,它可以加载如上述格式般分类存储的数据,并对图像类别进行预处理操作。按照分类后文件夹的顺序返回从0到n(n为类别数量)的索引,该索引就是各类别文件夹中图像的分类标签。代码如下:
# 数据加载及预处理
transform_train = transforms.Compose([
transforms.Resize(32),
transforms.RandomHorizontalFlip(),
transforms.ToTensor(),
transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))
])
transform_test = transforms.Compose([
transforms.Resize(32),
transforms.ToTensor(),
transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))
])
# 加载数据
train_set = ImageFolder(
root="./data/jaffe/train",
transform=transform_train
)
test_set = ImageFolder(
root="./data/jaffe/test",
transform=transform_test
)
train_loader = DataLoader(
train_set, batch_size=8, shuffle=True)
test_loader = DataLoader(
test_set, batch_size=8, shuffle=False)
02、基于ResNet神经网络的人脸表情识别
(一)网络定义
在本文中,使用ResNet-18网络进行训练。因为JAFFE数据集中只有七个类别,所以输出层只需要七个神经元,即num_classes等于7。
# ResNet-18生成方法
def ResNet-18(num_classes = 1000):
model = ResNet(BasicBlock, [2, 2, 2, 2], num_classes)
return model
net = ResNet-18(num_classes=7)
网络也可以调用Pytorch中torchvision.models模块中集成的ResNet网络,通过简单的调用就可以使用,效果与上述代码是相同的。在调用torchvision.models模块中的ResNet网络时,输出层的num_classes参数也需要设置为7。代码如下:
from torchvision.models import ResNet-18
net = ResNet-18(num_classes = 7)
(二)整体训练流程在模型的训练过程中,使用PyTorch中的nn.CrossEntropyLoss()计算损失,使用Adam优化器对网络参数进行优化。以下是人脸表情识别任务的训练代码:
if __name__ == "__main__":
# 定义训练使用的设备
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
net = ResNet-18(num_classes=7)
train(net, train_loader, test_loader, device, l_r=0.00003, num_epochs=30)
更多内容,敬请关注下方图书!
▊《深度学习与人工智能实战》
张重生 编著
本书按照知识由浅入深、循序渐进的规律编写而成。内容分为三大部分,第一部分是Python和PyTorch编程基础,介绍常用的函数及其用法;第二部分是初级深度学习算法与技术,含基础卷积神经网络的实现,目标识别、人脸表情识别等实战;第三部分是高级深度学习算法和技术,含孪生神经网络、度量学习、蒸馏学习、目标检测、图像分割、图像生成等技术及实战。本书的附录还提供了常用PyTorch函数速查手册。本书根据深度学习技术的特点,将内容划分为数据准备、神经网络模型实现、损失函数实现、整体训练流程和效果展示五部分。这种章节内容安排方式逻辑清楚,可操作性强、更易理解。
撰 稿 人:杨健亭责任编辑: 李馨馨审 核 人:曹新宇