来源:投稿 作者:LSC
编辑:学姐

本篇文章的内容是从表情分类,到完成人脸表情识别,理论穿插实战代码。分为两部分,第一部分为表情分类实战;第二部分为人脸表情识别案例实战。

第一部分

1.表情分类实战简介

  • 数据集: 表情数据集,可分为无表情、撅嘴、微笑、张嘴四类。

  • 样本个数: 训练样本13598,验证样本1509

  • 使用网络: resnet,multiscale-resnet

分类表情数据

  • 无表情0none:4763 训练集4287 测试集476

  • 嘟嘴1pouting:3154 训练集2839 测试集315

  • 微笑2smile:4841 训练集4357 测试集484

  • 大笑3openmouth:2348 训练集2114 测试集234

训练数据:13597

测试数据:1509

格式:统一为128*128,jpg图像

训练模型要求

(1) 输入大小统一为:96*96

(2) 最后一层特征输出大小为3*3,分类类别为4,使用迁移学习

2.表情分类实战数据集读取

使用torch.utils.data里的data函数实现编写过程;

分为_init_、_len_、_getitem_三个模块;

_init_完成某些参数的初始定义;

len 获取数据集的总数;

getitem 读取每幅图像和标签。

3.数据增强

可以自行编写,也可以使用torchvision.transform

4.网络搭建

可以自行编写,也可以使用torchvision.models中的模型

5.正确率计算

评价指标记录函数的编写,主要为分类准确率.

6.训练和验证函数

第二部分

人脸表情识别案例

1.1任务——表情识别

从零开始整理数据,使用pytorch从零开始搭建表情识别模型

1.2 一个完整的工业级项目流程

从数据整理到模型验证

1.3.1数据获取的常见方法

数据集(ImageNet等 数据质量高 成本低) 外包(阿里众包等 大规模 成本高) 自采集(自己采集或者爬虫 成本低 速度快)

1.3.2开源数据集

表情数据集: KDEF, RaFD, RAF, EMotioNet等

人脸数据集: Celaba等

1.3.3爬虫获取

用于准备小型的数据集(10000以内),图片来源主要是搜索引擎,快速获取第一批数据用于验证方案。

1.4.1数据预处理——归一化

  • 去除损坏图片,防止读取失败

  • 类型归一化(方便遍历,*.jpg | .*png,统一压缩方式)

  • 去除尺寸异常图片(如长宽比大于10)

  • 命名归一化(方便归类)

# 数据读取
def listfiles(rootDir):list_dirs = os.walk(rootDir)for root, dirs, files in list_dirs:for d i dirs:print(os.path.join(root, d))for f in files:fileid = f.split('.')[0]filepath = os.path.join(root, f)try:src = cv2.imread(filepath, 1)print("src = ", filepath, src.shape)os.remove(filepath)cv2.imwrite(os.path.join(root, fileid + '.jpg'), src)except:os.remove(filepath)continue

1.4.2数据预处理——人脸检测

OpenCv人脸检测,Dlib关键点检测,将嘴唇区域裁剪并适当扩大区域。

# 人脸检测
cascade_path = 'haarcascade_frontalface_default.xml'
cascade = cv2.CascadeClassifier(cascade_path)#关键点检测
PREDICTOR_PATH = "shape_predictor_68_face_landmarks.dat"
predictor = dlib.shape_predictor(PREDICTOR_PATH)def get_landmarks(im):rects = cascade.detectMultiScale(im, 1.3, 5)x, y, w, h = rects[0]rect = dlib.rectangle(int(x), int(y), int(x + w), int(y + h))return np.matrix([[p.x, p.y] for p in predictor(im, rect).parts()])#提取出嘴唇区域,并适当扩大区域
for i in range(48, 67):x = landmarks[i, 0]y = landmarks[i, 1]

1.5数据集大小

15000多张图,包含微笑,嘟嘴,大笑,无表情4类

按9:1均匀划分为训练集和测试集,格式统一为128*128,jpg图像。

2.1图像分类任务,通过torchvision包来读取数据

import torchvision.dataset as dataset
data_dir = './data' # 数据目录
data = dataset.ImageFolder(data_dir, data_transform) # ImageFolder接口
dataloader = data.DataLoader(data) # 数据指针
Train和val文件夹都包含4个类的子文件夹,自动被torchvision转成标签。

2.2 数据增强方法

添加随机缩放裁剪,随机翻转,去均值方差归一化操作。

transforms.RandomSizedCrop(48),将输入图进行随机裁剪,尺度由面积比参数scale控制,长宽比由ratio控制,然后缩放为48*48。

transforms.RandomHorizontalFlip()以0.5的概率进行随机翻转。

2.3数据指针

使用data.DataLoader获得数据指针

data_dir = './data/'
# 分别读取'../data/train'.和'./data/val'文件夹
image_datasets = {x:dataset.ImageFolder(os.path.join(data_dir, x), data_transforms[x]) for x in ['train', 'val']}
# 设置batchsize大小为4,数据读取线程为1,使用随机打乱操作
dataloaders = {x: torch.util.data.DataLoader(image_datasets[x], batch_size = 16, shuffle = True, num_workers = 4) for x in ['train', 'val']}

2.4 定义一个简单的网络,由3个卷积层,3个BN层,3个全连接层构成

# 网络搭建
calss Net(nn.Module, nclass):def __init__(self):super(Net, self).__init__()self.conv1 = nn.Conv2d(3, 12, 3, 2)self.bn1 = nn.BatchNorm2d(12)self.conv2 = nn.Conv2d(12, 24, 3, 2)self.bn2 = nn.BatchNorm2d(24)self.conv3 = nn.Conv2d(24, 48, 3, 2)self.bn2 = nn.BatchNorm2d(48)self.fc1 = nn.Linear(48 * 5 * 5, 1200) # conv3的输出为48 * 5 * 5self.fc2 = nn.Linear(1200, 128)self.fc3 = nn.Linear(128, nclass) # 输出Tensor尺寸[batch, 1, 1, nclass]def forward(self, x):x = F.relu(self.bn1(self.conv1(x)))x = F.relu(self.bn2(self.conv2(x)))x = F.relu(self.bn3(self.conv3(x)))x = x.view(-1, 48 * 5 * 5)x = F.relu(self.fc1(x))x = F.relu(self.fc2(x))x = self.fc3(x)return x

2.5 优化目标与方法

优化目标: 交叉熵损失

优化方法: 带动量的SGD算法(Momentum算法)

criterion = nn.CrossEntropyLoss()optimizer_ft = optim.SGD(modelclc.parameters(), lr = 0.1, momentum = 0.9)
exp_lr_scheduler = lr_scheduler.StepLR(optimizer_ft, step_size = 100, gamma = 0.1) # 学习率迭代策略

模型定义与训练

model = Net(4)
model = train_model(model = model, criterion = criterion, optimizer = optimizer_ft,scheduler = exp_lr_scheduler, num_epochs = 500)

2.6训练迭代

每一次epoch,包含数据batch数据迭代

def train_model(model, criterion, optimizer, scheduler, num_epochs = 25):for epoch in range(num_epochs):for phase in ['train', 'val']:if phase == 'train':scheduler.step()model.train(True)else:model.train(False)running_loss = 0.0running_corrects = 0.0for data in dataLoader[phase]:inputs, labels = dataif use_gpu = True:inputs = inputs.cuda()labels = labels.cuda()optimizer.zero_grad() # 梯度清零outputs = model(inputs)_, preds = torch.max(outputs.data, 1)loss = criterion(outputs, labels)if phase = "train":loss.backward() # 误差反向传播optimizer.step() # 参数更像

2.7 可视化

使用tensorboardX库进行可视化

# 记录需要可视化的变量
for tersorboardX import SummaryWriter
writer = SummaryWriter()# 每一个batch
if phase == 'train':writer.add_scaler('data/trainloss', epoch_loss, epoch)writer.add_scaler('data/trainacc', epoch_acc, epoch)
else:writer.add_scaler('data/trainloss', epoch_loss, epoch)writer.add_scaler('data/trainacc', epoch_acc, epoch)# 每一个epochwriter.export_scalars_to_json('./all_scalars.json')
writer.close()

第一步,用tensorboardX打开日志文件(默认为runs) tensorboard --logdir=runs/

第二步,在浏览器根据提示打开地址: http://longpengdeMBP:6007/

2.8测试

# 测试
# 载入预训练模型,前向推理获得预测结果
form net import Net
Net.load_state_dict(torch.load(modelpath, map_location = lambda storage, loc:storage))
Net.eval() # 设置为推理模式,不会更新模型的k, b参数
torch.no_grad() # 停止autograd模块的工作,加速和节省显存# 定义数据预处理
testsize = 48 # 测试图大小
data_transforms = transforms.Compose([transforms.ToTensor(),transforms.Normalize([0.5, 0.5, 0.5], [0.5, 0.5, 0.5])
])# 前向推理获得结果,读取数据,填充数据维度
image = Image.open(imagepath)
imgblob = data_transfroms(img).unsqueeze(0)
predict = F.softmax(Net(imgblob))
imdex = np.argmax(predict.detach().numpy())# 使用OpenCv的rectangle函数和putText函数将结果绘制到图像
# 绘制框与文本
pos_x = int(offsetx + roisize)
pos_y = int(offsety + roisize)
font = cv2.FONT_HERSHEY_SIMPLEX
cv2.rectangle(im, (offsetx), offsety), (pos_x, pos_y), (0, 255, 0), 2)if index == 0:cv2.putText(im, 'none', (pos_x, pos_y), font, 1,2, (0, 255, 255), 1)
elif index == 1:cv2.putText(im, 'pouting', (pos_x, pos_y), font, 1,2, (0, 255, 255), 1)
elif index == 2:cv2.putText(im, 'smile', (pos_x, pos_y), font, 1,2, (0, 255, 255), 1)
else:cv2.putText(im, 'open', (pos_x, pos_y), font, 1,2, (0, 255, 255), 1)

关注

【实战案例】表情分类人脸表情识别相关推荐

  1. 【计算机视觉40例】案例37:人脸表情识别

    [导读]本文是专栏<计算机视觉40例简介>的第37个案例<人脸表情识别>.该专栏简要介绍李立宗主编<计算机视觉40例--从入门到深度学习(OpenCV-Python)&g ...

  2. 人脸表情系列——人脸表情识别(Facial Expression Recognization/FER)

    最近看了几篇关于表情识别的论文,稍微记录一下. 综述推荐一篇CVPR2019的:Deep Facial Expression Recognition: A Survey 基于深度学习的表情识别流程为: ...

  3. python视频人脸检测_Python学习案例之视频人脸检测识别

    前言 上一篇博文与大家分享了简单的图片人脸识别技术,其实在实际应用中,很多是通过视频流的方式进行识别,比如人脸识别通道门禁考勤系统.人脸动态跟踪识别系统等等. 案例 这里我们还是使用 opencv 中 ...

  4. Python案例之视频人脸检测识别

    今天给大家分享简单的图片人脸识别技术,其实在实际应用中,很多是通过视频流的方式进行识别,比如人脸识别通道 门禁考勤系统.人脸动态跟踪识别系统等等. 案例展示 这里我们还是使用 opencv 中自带了 ...

  5. 机器学习实战案例—验证码(CAPTCHA)识别基于Logistic

    基于Logistic验证码识别 基于逻辑回归(Logistic)图像处理实现数字验证码的识别 一.准备数据(制作验证码) 二.对图形进行处理 三.将数据带入逻辑回归进行建模 四.得到模形,进行图像验证 ...

  6. 高精度人脸表情识别(附GitHub地址)

    编者按:本文原作者吴捷,目前于中山大学就读研究生.研究领域为计算机视觉与自然语言处理.本文原载于知乎,经作者授权发布.欢迎去GitHub给大佬加星. 先放出GitHub地址: https://gith ...

  7. 【技术综述】人脸表情识别研究

    李振东 北京邮电大学硕士在读,计算机视觉方向 言有三 毕业于中国科学院,计算机视觉方向从业者,有三工作室等创始人 作者 | 李振东/言有三 编辑 | 言有三 随着机器学习和深度神经网络两个领域的迅速发 ...

  8. 《基于剪切波变换的人脸表情识别》笔记

    [时间]2018.10.16 [题目]<基于剪切波变换的人脸表情识别>笔记 [论文链接]http://www.wanfangdata.com.cn/details/detail.do?_t ...

  9. 腾讯大佬总结的人脸表情识别技术

    李振东 北京邮电大学硕士在读,计算机视觉方向 言有三 毕业于中国科学院,计算机视觉方向从业者,有三工作室等创始人 作者 | 李振东/言有三 编辑 | 言有三 随着机器学习和深度神经网络两个领域的迅速发 ...

最新文章

  1. apache ant
  2. 交流线圈磁芯上的短路铜片
  3. 【TUP第11期】腾讯黄朝兴:浅谈客户端架构
  4. 深入解读MySQL8.0 新特性 :Crash Safe DDL 1
  5. deep linux 看视频卡,在Deepin 20等Linux系统下用Chrome看虎牙直播经常卡的处理
  6. 论文笔记《Neural Machine Translation by Jointly Learning to Align and Translate》
  7. 如何解二阶齐线性微分方程
  8. 面试智力题:赛马问题求前几名
  9. Win10桌面美化(桌面数字时钟,悬浮侧边栏、透明任务栏、底部居中软件图标)
  10. java读取word2010_Java 添加、读取、删除Word脚注/尾注
  11. JavaScript(JS)的基本语法
  12. 计算机网络小黑指北-单选题自测
  13. 云服务到底是什么东西?
  14. Adroid11,拍照,裁剪以及保存图片
  15. 关于.length和.length()
  16. VS(SQL Server一样)设置护眼背景色
  17. matlab实现线性函数逼近,1基于MATLAB的科学计算—函数逼近1.doc
  18. java中的开方Math.sqrt(n)函数和平方{a的b次方Math.pow(a, b)}
  19. Excel 表格删除重复数据
  20. MediaPlayer代码分析(1)-初始化和设置数据的过程

热门文章

  1. 物联网区块链技术的行业发展优势
  2. Stanford CS230深度学习(一)
  3. bzoj4455 [Zjoi2016]小星星
  4. 微信公众账号服务号自定义菜单配置与实现
  5. HTML+CSS学习(五)
  6. #问题求解与编程# 实验二 D 比赛排名预测
  7. 每天一练——爱因斯坦出了一道这样的数学题
  8. ps磨皮插件Portraiture分享
  9. 破解入门(四)-----实战单步跟踪法脱壳
  10. 电子学:第009课——实验 7:研究继电器