PyTorch面部表情识别项目实战
创始人
2024-12-29 10:33:29
0

新书速览|PyTorch深度学习与企业级项目实战-CSDN博客

本书案例比较丰富、比较完整,可以用于课题研究、毕业论文素材,值得大家收藏。

人脸表情是人类信息交流的重要方式,它所包含的人体行为信息与人的情感状态、精神状态、健康状态等有着极为密切的关联。因此,通过对人脸表情的识别可以获得很多有价值的信息,从而分析人类的心理活动和精神状态,并为各种机器视觉和人工智能控制系统的应用提供解决方案。 所以本项目在研究人脸面部表情识别的过程中,借助人工智能算法的优势开展基于深度神经网络的图像分类实验。

借助MobileNetv3模型进行迁移学习,经过足够多次的迭代,分类准确率可以达到90%。这里使用的MMAFEDB数据集包含128000MMA面部表情图像数据集 MMAFEDB数据集包含用于、验证和测试的目录。 每个目录包含对应7个面部表情类别的7个子目录。

MMAFEDB数据集数据说明如下:

  1. Angry:愤怒。
  2. Disgust:厌恶。
  3. Fear:恐惧。
  4. Happy:快乐。
  5. Neutral:中性。
  6. Sad:悲伤。
  7. Surprise:惊讶。

MMAFEDB数据集数据来源如下:

https://www.kaggle.com/mahmoudima/mma-facial-expression?select=MMAFEDB

相对重量级网络而言,轻量级网络的特点是参数少、计算量小、推理时间短,更适用于存储空间和功耗受限的场景,例如移动端嵌入式设备等边缘计算设备。因此,轻量级网络受到了广泛的关注,其中MobileNet可谓是其中的佼佼者。MobileNetV3经过了V1和V2前两代的积累,性能和速度都表现优异,受到学术界和工业界的追捧,无疑是轻量级网络的“抗把子”。

本项目这里加载预训练的MobileNetv3模型,由于预训练的模型与我们的任务需要不一样,因此需要修改最后的全连接层,将输出维度修改为我们的任务要求中的7个分类(7种面部表情)。 但是需要注意冻结其他层的参数,防止训练过程中将其改动,然后训练微调最后一层即可。

由于我们的任务为多分类问题,因此损失函数需要使用交叉熵损失函数(Cross Entropy),但是这里没有采用框架自带的损失函数,而是自己实现了一个损失函数。虽说大多数情况下,框架自带的损失函数就能够满足我们的需求,但是对于一些特定任务是无法满足的,需要我们进行自定义。自定义函数需要继承 nn.Module 子类,然后定义好参数和所需的变量,在forward方法中编写计算损失函数的过程,然后PyTorch会自动计算反向传播需要的梯度,不需要我们自己进行计算。

###########expression_on_face.py##################### import torchvision from torch import nn import numpy as np import os import pickle import torch  from torchvision import transforms, datasets import torchvision.models as models from tqdm import tqdm from PIL import Image import matplotlib.pyplot as plt  epochs = 10 lr = 0.03 batch_size = 32 image_path = './The_expression_on_his_face/train' save_path = './chk/expression_model.pkl'  device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')  # 1.数据转换 data_transform = {     # 训练中的数据增强和归一化     'train': transforms.Compose([         transforms.RandomResizedCrop(224),  # 随机裁剪         transforms.RandomHorizontalFlip(),  # 左右翻转         transforms.ToTensor(),         transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])  # 均值方差归一化     ]) }  # 2.形成训练集 train_dataset = datasets.ImageFolder(root=os.path.join(image_path),                                      transform=data_transform['train'])  # 3.形成迭代器 train_loader = torch.utils.data.DataLoader(train_dataset,                                            batch_size,                                            True)  print('using {} images for training.'.format(len(train_dataset)))  # 4.建立分类标签与索引的关系 cloth_list = train_dataset.class_to_idx class_dict = {} for key, val in cloth_list.items():     class_dict[val] = key with open('class_dict.pk', 'wb') as f:     pickle.dump(class_dict, f)  print(class_dict.values())  # 自定义损失函数,需要在forward中定义过程 class MyLoss(nn.Module):     def __init__(self):         super(MyLoss, self).__init__()      # 参数为传入的预测值和真实值,返回所有样本的损失值     # 自己只需定义计算过程,反向传播PyTroch会自动记录     def forward(self, pred, label):         # pred:[32, 4] label:[32, 1] 第一维度是样本数          exp = torch.exp(pred)         tmp1 = exp.gather(1, label.unsqueeze(-1)).squeeze()         tmp2 = exp.sum(1)         softmax = tmp1 / tmp2         log = -torch.log(softmax)         return log.mean()  # 5.加载MobileNetv3模型 #加载预训练好的MobileNetv3模型 model = torchvision.models.mobilenet_v3_small(     weights=models.MobileNet_V3_Small_Weights.DEFAULT) # 冻结模型参数 for param in model.parameters():     param.requires_grad = False  # 修改最后一层的全连接层 model.classifier[3] = nn.Linear(model.classifier[3].in_features, 7)  # 将模型加载到cpu中 model = model.to('cpu')  # criterion = nn.CrossEntropyLoss() # 损失函数 criterion = MyLoss() optimizer = torch.optim.Adam(model.parameters(), lr=0.01)  # 优化器  # 6.模型训练 best_acc = 0  			# 最优精确率 best_model = None  		# 最优模型参数  for epoch in range(epochs):     model.train()     running_loss = 0  	# 损失     epoch_acc = 0  		# 每个epoch的准确率     epoch_acc_count = 0 	# 每个epoch训练的样本数     train_count = 0  	# 用于计算总的样本数,方便求准确率     train_bar = tqdm(train_loader)     for data in train_bar:         images, labels = data         optimizer.zero_grad()         output = model(images.to(device))         loss = criterion(output, labels.to(device))         loss.backward()         optimizer.step()          running_loss += loss.item()         train_bar.desc = "train epoch[{}/{}] loss:{:.3f}".format(epoch + 1,                                                                  epochs,                                                                  loss)         # 计算每个epoch正确的个数         epoch_acc_count += (output.argmax(axis=1) == labels.view(-1)).sum()         train_count += len(images)      # 每个epoch对应的准确率     epoch_acc = epoch_acc_count / train_count      # 打印信息     print("【EPOCH: 】%s" % str(epoch + 1))     print("训练损失为%s" % str(running_loss))     print("训练精度为%s" % (str(epoch_acc.item() * 100)[:5]) + '%')      if epoch_acc > best_acc:         best_acc = epoch_acc         best_model = model.state_dict()      # 在训练结束保存最优的模型参数     if epoch == epochs - 1:         # 保存模型         torch.save(best_model, save_path)  print('Finished Training')  # 加载索引与标签映射字典 with open('class_dict.pk', 'rb') as f:     class_dict = pickle.load(f)  # 数据变换 data_transform = transforms.Compose(     [transforms.Resize(256),      transforms.CenterCrop(224),      transforms.ToTensor()])  # 图片路径 img_path = r'./The_expression_on_his_face/test.jpg'  # 打开图像 #为了避免通道数不匹配,使用灰度图像(1通道),使用RGB图像(3通道) #解决方式:加载图像时,做一下转换 img = Image.open(img_path).convert('RGB')  # 对图像进行变换 img = data_transform(img)  plt.imshow(img.permute(1, 2, 0)) plt.show()  # 将图像升维,增加batch_size维度 img = torch.unsqueeze(img, dim=0)  # 获取预测结果 pred = class_dict[model(img).argmax(axis=1).item()] print('【预测结果分类】:%s' % pred) 

代码运行结果如下:

using 851 images for training. dict_values(['angry', 'disgust', 'fear', 'happy', 'neutral', 'sad', 'surprise']) train epoch[1/10] loss:1.943: 100%|██████████| 27/27 [00:10<00:00,  2.65it/s]   0%|          | 0/27 [00:00

注意,这里只是列出计算10个周期,如果需要提高训练精度,需要增加训练周期100个以及扩大训练样本量。读者可以自行尝试。

《PyTorch深度学习与企业级项目实战(人工智能技术丛书)》(宋立桓,宋立林)【摘要 书评 试读】- 京东图书 (jd.com)

相关内容

热门资讯

玩家必用!乐乐围棋入门插件,微... 玩家必用!乐乐围棋入门插件,微乐陕西小程序破解器(有挂细节辅助下载)1、下载安装好微乐陕西小程序破解...
透视教学!微信微乐自建房脚本下... 透视教学!微信微乐自建房脚本下载,财神13章辅助,安装教程(发现有挂)这是一款可以让一直输的玩家,快...
第5分钟辅助挂!新海贝之城游戏... 第5分钟辅助挂!新海贝之城游戏攻略,一起宁德钓蟹脚本(了解开挂辅助安装);亲,新海贝之城游戏攻略这款...
透视好牌!wepoker辅助器... 透视好牌!wepoker辅助器最新版本更新内容,微乐广西自建房免费黑科技下载,2026新版总结(有挂...
重大通报!链接大厅辅助插件有哪... 重大通报!链接大厅辅助插件有哪些,战神辅助直装破解版(有挂细节辅助下载)您好:链接大厅辅助插件有哪些...
两分钟辅助挂!闲逸游戏修改器,... 两分钟辅助挂!闲逸游戏修改器,鄱阳翻精辅助软件(掌握开挂辅助透视神器);无需打开直接搜索薇:1367...
透视透视!微乐江苏小程序游戏破... 微乐江苏小程序游戏破解下载是一款专注玩家量身打造的游戏记牌类型软件,在微乐江苏小程序游戏破解下载这款...
科技揭秘!广西老友玩手游辅助,... 大家好,今天小编来为大家解答广西老友玩手游辅助这个问题咨询软件客服可以免费测试直接加微信(13670...
第9分钟辅助挂!微乐小程序辅助... 第9分钟辅助挂!微乐小程序辅助收费,约战平台辅助(熟悉开挂辅助透视挂)这是一款可以让一直输的玩家,快...
透视代打!随意玩辅助器视频有挂... 随意玩辅助器视频有挂是一款专注玩家量身打造的游戏记牌类型软件,在随意玩辅助器视频有挂这款游戏中我们可...