第一个深度学习模型 Bitmoji Faces Gender Recognition

2024-03-11 08:50

本文主要是介绍第一个深度学习模型 Bitmoji Faces Gender Recognition,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

  简介:

          本文根据利用深度学习模型,根据人脸的表情信息对人的性别进行分类,数据集来自kaggle。是一个二分类问题,比较简单,可以当做自己的第一个深度学习模型。动手深刻感受深度学习。

数据集:

       原始数据集如下所示:

        其中所给的训练集图像有3000张,测试集图像有1084张,同时还提供了训练集的CSV文件如下所示:

image_idis_maleleft_eye_xleft_eye_yright_eye_xright_eye_ynose_xnose_ymouth_left_xmouth_left_ymouth_right_xmouth_right_y
0000.jpg1152186236183196234158262231260
0001.jpg-1146191232192190229155263228264
0002.jpg1157188229188194235164258224257
0003.jpg-1152210232210191248159280222281
0004.jpg-1151189237189192227

155

254232254

        其中表格中中1代表男性,-1代表女性,同时还提供了左眼,右眼,鼻子,左嘴巴端点,右嘴巴端点的坐标。以像素值表示。这些数据本文并没有用到。只用了图片作为卷积输入。

1.相关工作

1.1. 预处理:

        所谓的预处理,是将计算特征之前,排除掉跟脸无关的一切干扰,因此,就有了数据增强,图片大小的重置、图片的剪裁、向量化和归一化等。

        数据增强,包含在线和离线两种[1]:主流的离线数据增强,包含随机扰动,变换(旋转,平移,翻转,缩放,对齐),噪声添加如椒盐噪声,斑点噪声,以及亮度,饱和度变化,以及在眼睛之间添加2维高斯随机分布的噪声。同时,还有其他的如GAN生成脸[2],3DCNN辅助AUs生成表情。

        除此之外为了方便数据输入模型,我们需要将图片存储的位置和图片的标签放到一个文本文件中,如下所示:

         其中1代表男性,0代表女性。这个处理需要使用make_data_txt.py  这个文件,主要是制作训练集,测试集。里面文件路径需要替换成自己的。

1.2. 深度特征学习

        主要是基于CNN的网络模型,具有非常高性能的特征表达能力[3]。特别适合基于图像的分类问题,另外一个基于DBN网络的特征提取,以及DAE转门用作特征提取。最后,还有一部分是基于序列建模的RNNs,如LSTM等。因为我们的这个作业复杂度不高,所以主要采用CNN的网络模型。

1.3.面部表示分类

        主要是说,可以基于深度学习,直接学习特征,预测概率(softmax),也可以把学习的深度特征,用SVM等浅层分类器进行分类[3]。

2 本文工作

       本文的核心框架为pytorch,接下来将从图片的处理方法,模型的结构和模型的结果展示三个部分进行模型说明。

2.1模型的图片处理

       这里我使用pytorch的transform进行数据的预处理,主要用到了图片大小的重置、图片的剪裁、向量化和归一化。

        图片大小的重置:考虑到使用两层卷积层和池化层,这里决定设置一个普通的数据256像素。原图片大小为384*384。然后进行中心剪裁,这里剪裁后的大小为224*224.

        图片归一化:使得预处理的数据被限定在一定的范围内,从而消除奇异样本数据导致的不良影响。

2.2 网络结构

        本模型使用的网络结构较为简单,首先是一层卷积层,然后跟着一个池化层,然后又是一层卷积跟着一个池化。接下来就是全连接层。一共有三层全连接层。经过全连接层之后将结果进行输出。这里不同的是没有使用激活函数,也是只用了两层的卷积。

对于网络参数的设置如下:

       这里所有的填充都是0,所以没有添加到上述表格中。最终的输出是是一个1*2的张量,里面是预测的概率。

2.3 结果展示和分析

        本模型训练的参数是总共训练10 epochs,训练的batch_size是4。使用的是CPU进行训练的。

10个epochs的准确度如下所示:

       模型大概训练了40分钟,最终训练集的正确率达到99.875,测试集的正确率达到99.333。然后将此模型的识别结果提交到kaggle上时,得到的评分是99.472.

3 代码

训练模型的代码如下所示:

# coding=utf-8
import os
import numpy as np
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torch.autograd import Variable
from torch.utils.data import Dataset
from torchvision import transforms, datasets, models
from PIL import Imageepochs = 10 # 训练次数
batch_size = 4  # 批处理大小
num_workers = 0  # 多线程的数目
use_gpu = torch.cuda.is_available()
PATH='./mymodel.pt'
# 对加载的图像作归一化处理, 并裁剪为[224x224x3]大小的图像
data_transform = transforms.Compose([transforms.Resize(256),transforms.CenterCrop(224),transforms.ToTensor(),transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
])class MyDataset(Dataset):def __init__(self, txt_path, transform = None):fh = open(txt_path, 'r')imgs = []for line in fh:line = line.rstrip()words = line.split()imgs.append((words[0], int(words[1])))self.imgs = imgsself.transform = transformdef __getitem__(self, index):fn, label = self.imgs[index]img = Image.open(fn).convert('RGB')if self.transform is not None:img = self.transform(img)return img, labeldef __len__(self):return len(self.imgs)# 配置参数
random_state = 1
torch.manual_seed(random_state)  # 设置随机数种子,确保结果可重复
torch.cuda.manual_seed(random_state)
torch.cuda.manual_seed_all(random_state)
np.random.seed(random_state)
# random.seed(random_state)train_dataset = MyDataset(txt_path='train_data.txt', transform=data_transform)
train_loader = torch.utils.data.DataLoader(train_dataset,batch_size=batch_size,shuffle=True,num_workers=num_workers)test_dataset = MyDataset(txt_path='test.txt', transform=data_transform)
test_loader = torch.utils.data.DataLoader(test_dataset, batch_size=batch_size, shuffle=True, num_workers=num_workers)# 创建模型
class Net(nn.Module):def __init__(self):super(Net, self).__init__()self.conv1 = nn.Conv2d(3, 6, 5)self.maxpool = nn.MaxPool2d(2, 2)self.conv2 = nn.Conv2d(6, 16, 5)self.fc1 = nn.Linear(16 * 53 * 53, 1024)self.fc2 = nn.Linear(1024, 512)self.fc3 = nn.Linear(512, 2)def forward(self, x):x = self.maxpool(F.relu(self.conv1(x)))x = self.maxpool(F.relu(self.conv2(x)))x = x.view(-1, 16 * 53 * 53)x = F.relu(self.fc1(x))x = F.relu(self.fc2(x))x = self.fc3(x)return xnet = Net()
if(os.path.exists('mymodel.pt')):net=torch.load('mymodel.pt')if use_gpu:net = net.cuda()
print(net)# 定义loss和optimizer
cirterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(), lr=0.0001, momentum=0.9)def train():for epoch in range(epochs):running_loss = 0.0train_correct = 0train_total = 0for i, data in enumerate(train_loader, 0):inputs, train_labels = dataif use_gpu:inputs, labels = Variable(inputs.cuda()), Variable(train_labels.cuda())else:inputs, labels = Variable(inputs), Variable(train_labels)optimizer.zero_grad()outputs = net(inputs)_, train_predicted = torch.max(outputs.data, 1)train_correct += (train_predicted == labels.data).sum()loss = cirterion(outputs, labels)loss.backward()optimizer.step()running_loss += loss.item()train_total += train_labels.size(0)print('train %d/%d epoch loss: %.3f  acc: %.3f ' % (epoch + 1, epochs,running_loss / train_total, 100 * train_correct / train_total))# 模型测试correct = 0test_loss = 0.0test_total = 0test_total = 0net.eval()for data in test_loader:images, labels = dataif use_gpu:images, labels = Variable(images.cuda()), Variable(labels.cuda())else:images, labels = Variable(images), Variable(labels)outputs = net(images)_, predicted = torch.max(outputs.data, 1)loss = cirterion(outputs, labels)test_loss += loss.item()test_total += labels.size(0)correct += (predicted == labels.data).sum()print('test  %d/%d epoch loss: %.3f  acc: %.3f ' % (epoch + 1,epochs, test_loss / test_total, 100 * correct / test_total))torch.save(net, 'mymodel.pt')print('mymodels save!')train()

4 总结

       这个模型是个比较简单的二分类问题,因此模型也比较简单,可以帮助我们更好地理解深度学习的数据处理和输入,数据的处理流程,作为我们的第一个深度学习模型是比较好的。顺便提一下,模型没有用到特征增强,我同学有用到这一方面,准确率可以达到100%。感兴趣的小伙伴可以尝试改进模型。

       完整项目以及介绍见 GitHub

引用

[1]  宋雨,王帮海,曹钢钢.结合数据增强与特征融合的跨模态行人重识别[J/OL].计算机工程与应用:1-10[2022-12-26].http://kns.cnki.net/kcms/detail/11.2127.TP.20221213.1638.017.html

[2]范丽丽. 基于深度学习的视觉特征学习关键技术研究[D].吉林大学,2022.DOI:10.27162/d.cnki.gjlin.2022.002224.

[3]杨兆龙. 面部表情识别方法研究实现[D].福州大学,2017.

这篇关于第一个深度学习模型 Bitmoji Faces Gender Recognition的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/797319

相关文章

Java的IO模型、Netty原理解析

《Java的IO模型、Netty原理解析》Java的I/O是以流的方式进行数据输入输出的,Java的类库涉及很多领域的IO内容:标准的输入输出,文件的操作、网络上的数据传输流、字符串流、对象流等,这篇... 目录1.什么是IO2.同步与异步、阻塞与非阻塞3.三种IO模型BIO(blocking I/O)NI

Python 中的异步与同步深度解析(实践记录)

《Python中的异步与同步深度解析(实践记录)》在Python编程世界里,异步和同步的概念是理解程序执行流程和性能优化的关键,这篇文章将带你深入了解它们的差异,以及阻塞和非阻塞的特性,同时通过实际... 目录python中的异步与同步:深度解析与实践异步与同步的定义异步同步阻塞与非阻塞的概念阻塞非阻塞同步

基于Flask框架添加多个AI模型的API并进行交互

《基于Flask框架添加多个AI模型的API并进行交互》:本文主要介绍如何基于Flask框架开发AI模型API管理系统,允许用户添加、删除不同AI模型的API密钥,感兴趣的可以了解下... 目录1. 概述2. 后端代码说明2.1 依赖库导入2.2 应用初始化2.3 API 存储字典2.4 路由函数2.5 应

Redis中高并发读写性能的深度解析与优化

《Redis中高并发读写性能的深度解析与优化》Redis作为一款高性能的内存数据库,广泛应用于缓存、消息队列、实时统计等场景,本文将深入探讨Redis的读写并发能力,感兴趣的小伙伴可以了解下... 目录引言一、Redis 并发能力概述1.1 Redis 的读写性能1.2 影响 Redis 并发能力的因素二、

最新Spring Security实战教程之表单登录定制到处理逻辑的深度改造(最新推荐)

《最新SpringSecurity实战教程之表单登录定制到处理逻辑的深度改造(最新推荐)》本章节介绍了如何通过SpringSecurity实现从配置自定义登录页面、表单登录处理逻辑的配置,并简单模拟... 目录前言改造准备开始登录页改造自定义用户名密码登陆成功失败跳转问题自定义登出前后端分离适配方案结语前言

Java进阶学习之如何开启远程调式

《Java进阶学习之如何开启远程调式》Java开发中的远程调试是一项至关重要的技能,特别是在处理生产环境的问题或者协作开发时,:本文主要介绍Java进阶学习之如何开启远程调式的相关资料,需要的朋友... 目录概述Java远程调试的开启与底层原理开启Java远程调试底层原理JVM参数总结&nbsMbKKXJx

Redis 内存淘汰策略深度解析(最新推荐)

《Redis内存淘汰策略深度解析(最新推荐)》本文详细探讨了Redis的内存淘汰策略、实现原理、适用场景及最佳实践,介绍了八种内存淘汰策略,包括noeviction、LRU、LFU、TTL、Rand... 目录一、 内存淘汰策略概述二、内存淘汰策略详解2.1 ​noeviction(不淘汰)​2.2 ​LR

C#集成DeepSeek模型实现AI私有化的流程步骤(本地部署与API调用教程)

《C#集成DeepSeek模型实现AI私有化的流程步骤(本地部署与API调用教程)》本文主要介绍了C#集成DeepSeek模型实现AI私有化的方法,包括搭建基础环境,如安装Ollama和下载DeepS... 目录前言搭建基础环境1、安装 Ollama2、下载 DeepSeek R1 模型客户端 ChatBo

SpringBoot快速接入OpenAI大模型的方法(JDK8)

《SpringBoot快速接入OpenAI大模型的方法(JDK8)》本文介绍了如何使用AI4J快速接入OpenAI大模型,并展示了如何实现流式与非流式的输出,以及对函数调用的使用,AI4J支持JDK8... 目录使用AI4J快速接入OpenAI大模型介绍AI4J-github快速使用创建SpringBoot

Python与DeepSeek的深度融合实战

《Python与DeepSeek的深度融合实战》Python作为最受欢迎的编程语言之一,以其简洁易读的语法、丰富的库和广泛的应用场景,成为了无数开发者的首选,而DeepSeek,作为人工智能领域的新星... 目录一、python与DeepSeek的结合优势二、模型训练1. 数据准备2. 模型架构与参数设置3