【实战】深度学习构建人脸面部表情识别系统

实战:深度学习构建人脸面部表情识别系统

一、表情数据集

数据集采用了kaggle面部表情识竞赛的人脸表情识别数据集。

https://www.kaggle.com/c/challenges-in-representation-learning-facial-expression-recognition-challenge/data
如果数据下载不下来的话,可以从网盘下载
链接:https://pan.baidu.com/s/1pB55JalBCzDtv9jvppp9Xg
提取码:y1t0

数据主要是由48*48像素的灰度图像组成。面部表情有7种类别(0 =愤怒,1 =厌恶,2 =恐惧,3 =快乐,4 =悲伤,5 =惊喜,6 =中立)

对于kaggle数据集来说,第一列是表情的类别,第二列是图像的像素点,第三列表示是Training,PublicTest,PrivateTest

import pandas as pddf = pd.read_csv("./fer2013.csv")
df.head()
emotionpixelsUsage
0070 80 82 72 58 58 60 63 54 58 60 48 89 115 121...Training
10151 150 147 155 148 133 111 140 170 174 182 15...Training
22231 212 156 164 174 138 161 173 182 200 106 38...Training
3424 32 36 30 32 23 19 20 30 41 21 22 32 34 21 1...Training
464 0 0 0 0 0 0 0 0 0 0 0 3 15 23 28 48 50 58 84...Training

将数据集转换成图片格式

#encoding:utf-8
import pandas as pd
import numpy as np
import os
import cv2emotions = {"0":"anger","1":"disgust","2":"fear","3":"happy","4":"sad","5":"surprised","6":"normal"
}def createDir(dir):if os.path.exists(dir) is False:os.makedirs(dir)def saveImageFromFer2013(file):# 读取csv文件faces_data = pd.read_csv(file)imageCount = 0# 遍历csv文件内容,并将图片数据按分类保存for index in range(len(faces_data)):# 解析每一行csv文件内容emotion_data = faces_data.loc[index][0]image_data = faces_data.loc[index][1]usage_data = faces_data.loc[index][2]# 将图片数据转换为48*48data_array = list(map(float,image_data.split()))data_array = np.asarray(data_array)image = data_array.reshape(48,48)# 选择分类,并创建文件名dirName = usage_dataemotionName = emotions[str(emotion_data)]# 图片要保存的文件夹imagePath = os.path.join(dirName,emotionName)# 创建分类文件夹以及表情文件夹createDir(dirName)createDir(imagePath)# 图片文件名imageName = os.path.join(imagePath,str(index)+".jpg")# 保存图片cv2.imwrite(imageName,image)imageCount = indexprint("总共有"+str(imageCount)+"张图片")if __name__ == "__main__":saveImageFromFer2013("fer2013.csv")
总共有35886张图片
# 可视化图像 anger disgust fear happy normal sad surprised
from tensorflow.keras.preprocessing.image import load_img,img_to_array
import matplotlib.pyplot as plt
import os
%matplotlib inline# 图像像素大小为48*48
pic_size = 48
plt.figure(0,figsize=(12,20))
cpt = 0
for expression in os.listdir("./Training/"):for i in range(1,6):cpt = cpt +1plt.subplot(7,5,cpt)img = load_img("./Training/"+expression+"/"+os.listdir("./Training/"+expression)[i],target_size=(pic_size,pic_size))plt.imshow(img,cmap="gray")
plt.tight_layout()
plt.show()        

在这里插入图片描述

# 统计训练图像中每个类别的数量
for expression in os.listdir("./Training/"):print(str(len(os.listdir("./Training/"+expression)))+" " + expression +" images")
3995 anger images
436 disgust images
4097 fear images
7215 happy images
4965 normal images
4830 sad images
3171 surprised images

使用ImageDataGenerator来提供批量数据来训练深度学习模型

# 通过提供批量数据来训练深度学习模型。Keras 有一个非常有用的类来自动从目录中提供数据:ImageDataGenerator。
from tensorflow.keras.preprocessing.image import ImageDataGeneratorbatch_size = 128
datagen_train = ImageDataGenerator()
datagen_validation = ImageDataGenerator()
train_generator = datagen_train.flow_from_directory("./Training",target_size=(pic_size,pic_size),color_mode="grayscale",batch_size=batch_size,class_mode="categorical",shuffle=True)
validation_generator = datagen_validation.flow_from_directory("./PublicTest",target_size=(pic_size,pic_size),color_mode="grayscale",batch_size=batch_size,class_mode="categorical",shuffle=False)
Found 28709 images belonging to 7 classes.
Found 3589 images belonging to 7 classes.

二、卷积神经网络模型搭建

定义模型

# 定义cnn结构# 导入需要的模块
from tensorflow.keras.layers import Dense,Input,Dropout,GlobalAveragePooling2D,Flatten,Conv2D,BatchNormalization,Activation,MaxPooling2D
from tensorflow.keras.models import Model,Sequential
from tensorflow.keras.optimizers import Adam# 类别数量
n_classes = 7# 初始化CNN
model = Sequential()# 第1层卷积层
model.add(Conv2D(64,(3,3),padding="same",input_shape=(48,48,1)))
model.add(BatchNormalization())
model.add(Activation("relu"))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Dropout(0.25))# 第2层卷积层
model.add(Conv2D(128,(5,5),padding="same"))
model.add(BatchNormalization())
model.add(Activation("relu"))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Dropout(0.25))# 第3层卷积层
model.add(Conv2D(512,(3,3),padding="same"))
model.add(BatchNormalization())
model.add(Activation("relu"))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Dropout(0.25))# 第4层卷积层
model.add(Conv2D(512,(3,3),padding="same"))
model.add(BatchNormalization())
model.add(Activation("relu"))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Dropout(0.25))# 1层展平层
model.add(Flatten())# 第1层全连接层
model.add(Dense(256))
model.add(BatchNormalization())
model.add(Activation("relu"))
model.add(Dropout(0.25))# 第2层全连接层
model.add(Dense(512))
model.add(BatchNormalization())
model.add(Activation("relu"))
model.add(Dropout(0.25))model.add(Dense(n_classes,activation="softmax"))opt = Adam(lr=0.0001)
model.compile(optimizer=opt,loss="categorical_crossentropy",metrics=["accuracy"])
WARNING:tensorflow:From D:\software\Anaconda\anaconda\lib\site-packages\tensorflow\python\ops\resource_variable_ops.py:435: colocate_with (from tensorflow.python.framework.ops) is deprecated and will be removed in a future version.
Instructions for updating:
Colocations handled automatically by placer.
WARNING:tensorflow:From D:\software\Anaconda\anaconda\lib\site-packages\tensorflow\python\keras\layers\core.py:143: calling dropout (from tensorflow.python.ops.nn_ops) with keep_prob is deprecated and will be removed in a future version.
Instructions for updating:
Please use `rate` instead of `keep_prob`. Rate should be set to `rate = 1 - keep_prob`.

模型架构

model.summary()
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d (Conv2D)              (None, 48, 48, 64)        640       
_________________________________________________________________
batch_normalization_v1 (Batc (None, 48, 48, 64)        256       
_________________________________________________________________
activation (Activation)      (None, 48, 48, 64)        0         
_________________________________________________________________
max_pooling2d (MaxPooling2D) (None, 24, 24, 64)        0         
_________________________________________________________________
dropout (Dropout)            (None, 24, 24, 64)        0         
_________________________________________________________________
conv2d_1 (Conv2D)            (None, 24, 24, 128)       204928    
_________________________________________________________________
batch_normalization_v1_1 (Ba (None, 24, 24, 128)       512       
_________________________________________________________________
activation_1 (Activation)    (None, 24, 24, 128)       0         
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 12, 12, 128)       0         
_________________________________________________________________
dropout_1 (Dropout)          (None, 12, 12, 128)       0         
_________________________________________________________________
conv2d_2 (Conv2D)            (None, 12, 12, 512)       590336    
_________________________________________________________________
batch_normalization_v1_2 (Ba (None, 12, 12, 512)       2048      
_________________________________________________________________
activation_2 (Activation)    (None, 12, 12, 512)       0         
_________________________________________________________________
max_pooling2d_2 (MaxPooling2 (None, 6, 6, 512)         0         
_________________________________________________________________
dropout_2 (Dropout)          (None, 6, 6, 512)         0         
_________________________________________________________________
conv2d_3 (Conv2D)            (None, 6, 6, 512)         2359808   
_________________________________________________________________
batch_normalization_v1_3 (Ba (None, 6, 6, 512)         2048      
_________________________________________________________________
activation_3 (Activation)    (None, 6, 6, 512)         0         
_________________________________________________________________
max_pooling2d_3 (MaxPooling2 (None, 3, 3, 512)         0         
_________________________________________________________________
dropout_3 (Dropout)          (None, 3, 3, 512)         0         
_________________________________________________________________
flatten (Flatten)            (None, 4608)              0         
_________________________________________________________________
dense (Dense)                (None, 256)               1179904   
_________________________________________________________________
batch_normalization_v1_4 (Ba (None, 256)               1024      
_________________________________________________________________
activation_4 (Activation)    (None, 256)               0         
_________________________________________________________________
dropout_4 (Dropout)          (None, 256)               0         
_________________________________________________________________
dense_1 (Dense)              (None, 512)               131584    
_________________________________________________________________
batch_normalization_v1_5 (Ba (None, 512)               2048      
_________________________________________________________________
activation_5 (Activation)    (None, 512)               0         
_________________________________________________________________
dropout_5 (Dropout)          (None, 512)               0         
_________________________________________________________________
dense_2 (Dense)              (None, 7)                 3591      
=================================================================
Total params: 4,478,727
Trainable params: 4,474,759
Non-trainable params: 3,968
_________________________________________________________________

模型训练

from tensorflow.keras.callbacks import ModelCheckpoint
epochs = 5
checkpoint = ModelCheckpoint("face_model.h5",monitor="val_acc",verbose=1,save_best_only=True,mode="max")
callbacks_list = [checkpoint]
history = model.fit_generator(generator=train_generator,steps_per_epoch=train_generator.n,epochs=epochs,validation_data=validation_generator,validation_steps=validation_generator.n,callbacks=callbacks_list)
WARNING:tensorflow:From D:\software\Anaconda\anaconda\lib\site-packages\tensorflow\python\ops\math_ops.py:3066: to_int32 (from tensorflow.python.ops.math_ops) is deprecated and will be removed in a future version.
Instructions for updating:
Use tf.cast instead.
Epoch 1/5
28708/28709 [============================>.] - ETA: 0s - loss: 0.6304 - acc: 0.7638
Epoch 00001: val_acc improved from -inf to 0.64360, saving model to model_weights.h5
# 将模型结构序列化为JSON
model_json = model.to_json()
with open("face_model.json","w") as json_file:json_file.write(model_json)

分析结果

# 绘制训练和验证集上损失和准确率的演变
import matplotlib.pyplot as plt
%matplotlib inlineplt.figure(figsize=(14,3))
plt.subplot(1, 2, 1)
plt.suptitle('Optimizer : Adam', fontsize=10)
plt.ylabel('Loss', fontsize=16)
plt.plot(history.history['loss'], color='b', label='Training Loss')
plt.plot(history.history['val_loss'], color='r', label='Validation Loss')
plt.legend(loc='upper right')plt.subplot(1, 2, 2)
plt.ylabel('Accuracy', fontsize=16)
plt.plot(history.history['acc'], color='b', label='Training Accuracy')
plt.plot(history.history['val_acc'], color='r', label='Validation Accuracy')
plt.legend(loc='lower right')
plt.show()

绘制confusion matrix(混淆矩阵),了解模型如何对图像进行分类

# 显示预测的混淆矩阵
# 计算预测
predictions = model.predict_generator(generator=validation_generator)
y_pred = [np.argmax(probas) for probas in predictions]
y_test = validation_generator.classes
class_names = validation_generator.class_indices.keys()from sklearn.metrics import confusion_matrix
import itertools
def plot_confusion_matrix(cm,classes,title="Confusion matrix",cmap=plt.cm.Blues):cm = cm.astype("float") / cm.sum(axis=1)[:,np.newaxis]plt.figure(figsize=(10,10))plt.imshow(cm,interpolation="nearest",cmap=cmap)plt.title(title)plt.colorbar()tick_marks = np.arange(len(classes))plt.xticks(tick_marks,classes,rotation=45)plt.yticks(tick_marks,classes)fmt = ".2f"thresh = cm.max() / 2.for i,j in itertools.product(range(cm.shape[0]),range(cm.shape[1])):plt.text(j,i,format(cm[i,j],fmt),horizontalalignment="center",color="white" if cm[i,j] > thresh else "black")plt.ylabel("True label")plt.xlabel("Predicted label")plt.tight_layout()
# 计算混淆矩阵
cnf_matrix = confusion_matrix(y_test,y_pred)
np.set_printoptions(precision=2)
plt.figure()
plot_confusion_matrix(cnf_matrix,classes=class_names,title="Normalized confusion matrix")
plt.show()
<Figure size 432x288 with 0 Axes>

在这里插入图片描述

三、实时预测

创建一个model.py文件,将为我们提供先前训练模型的预测:

from keras.models import model_from_json
import numpy as np# 创建FacialExpressionModel类
# 功能:提供先前训练模型的预测
class FacialExpressionModel(object):EMOTIONS_LIST = ["Angry", "Disgust","Fear", "Happy","Sad", "Surprise","Neutral"]def __init__(self, model_json_file, model_weights_file):# 从JSON文件中加载模型with open(model_json_file, "r") as json_file:loaded_model_json = json_file.read()self.loaded_model = model_from_json(loaded_model_json)# 将权重加载到新模型中self.loaded_model.load_weights(model_weights_file)self.loaded_model._make_predict_function()#print("Model loaded from disk")#self.loaded_model.summary()def predict_emotion(self, img):self.preds = self.loaded_model.predict(img)return FacialExpressionModel.EMOTIONS_LIST[np.argmax(self.preds)]

接下来,创建一个camera.py文件

  • 从我们的网络摄像头获取图像流

  • 使用 OpenCV 检测面并添加边界框

  • 将面转换为灰度,重新缩放它们并将它们发送到我们预先训练的神经网络

  • 从我们的神经网络获取预测并将标签添加到网络摄像头图像

  • 返回最终的图像流

import cv2
from model import FacialExpressionModel
import numpy as npfacec = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
model = FacialExpressionModel("face_model.json", "face_model.h5")
font = cv2.FONT_HERSHEY_SIMPLEXclass VideoCamera(object):def __init__(self):self.video = cv2.VideoCapture(0)def __del__(self):self.video.release()# 返回相机帧以及边界框和预测def get_frame(self):_, fr = self.video.read()gray_fr = cv2.cvtColor(fr, cv2.COLOR_BGR2GRAY)faces = facec.detectMultiScale(gray_fr, 1.3, 5)for (x, y, w, h) in faces:fc = gray_fr[y:y+h, x:x+w]roi = cv2.resize(fc, (48, 48))pred = model.predict_emotion(roi[np.newaxis, :, :, np.newaxis])cv2.putText(fr, pred, (x, y), font, 1, (255, 255, 0), 2)cv2.rectangle(fr,(x,y),(x+w,y+h),(255,0,0),2)_, jpeg = cv2.imencode('.jpg', fr)return jpeg.tobytes()

最后,我们的主要脚本将创建一个 Flask 应用程序,将我们的图像预测呈现到网页中。

from flask import Flask, render_template, Response
from camera import VideoCameraapp = Flask(__name__)@app.route('/')
def index():return render_template('index.html')def gen(camera):while True:frame = camera.get_frame()yield (b'--frame\r\n'b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n\r\n')@app.route('/video_feed')
def video_feed():return Response(gen(VideoCamera()),mimetype='multipart/x-mixed-replace; boundary=frame')if __name__ == '__main__':app.run(host='0.0.0.0', debug=True)

结果展示

在这里插入图片描述

附上源码地址github

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/28125.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

icon图标在线制作生成的方法

我们在实际的建站过程中&#xff0c;经常需要制作自己的icon图标文件&#xff1b;又或者我们需要把windows系统里的应用图标改成自定义的图标样式&#xff0c;那么有什么办法能够快速的将一张普通图片经过裁剪等操作后&#xff0c;制作生成一张icon图标文件呢&#xff0c;参考这…

如何给生成的exe加图标

一、简述 今天就简单介绍一下如何给exe加图标&#xff0c;其实很简单&#xff0c;但是主要是为了讲述另一个问题&#xff0c;这也是之前遇到的一个容易忽略的问题。 首先我们了解一下一共有多少个图标可以设置。 看到下面这张图&#xff0c;我们首先会了解到生成的一个exe程…

一键生成iosandroid应用图标

用的在线工具: https://toool.top/app-icon-generate 只需要准备一张 1024 x 1024 的图片 即可生成各个分辨率的应用图标 ,十分方便

奇舞周刊第 488 期:一个服务端同学的 Vue 框架入门及实践

记得点击文章末尾的“ 阅读原文 ”查看哟~ 下面先一起看下本期周刊 摘要 吧~ 奇舞推荐 ■ ■ ■ 一个服务端同学的 Vue 框架入门及实践 做为服务端同学&#xff0c;接触前端代码较少&#xff0c;刚毕业的时候用过 jQuery Bootstrap2/3&#xff0c;当时的感觉就是&#xff0c;容…

国内站的ai聊天网站

国内站的ai聊天网站 网站如下: https://chat-gpt.org/chat其他网站如下: 在线体验ChatGPT网站集合 UI与官方相似https://chat.theb.ai/https://chatgpt-35-turbo.com/https:

Threads实测:和推特很像,马斯克大呼不讲武德

自从马斯克买下了推特&#xff0c;这个全球最大的在线社区就永远不缺少乐子&#xff0c;马斯克的整活能力在全球网红中都算是顶尖的。只不过&#xff0c;以前他只能在自己的推特账号那一亩三分地上整活&#xff0c;把推特买回家后&#xff0c;整个推特都变成了他的“乐园”。前…

AIGC明星独角兽爆雷!7亿融资烧大半,拖欠员工工资,创始人被扒得千疮百孔...

丰色 萧箫 发自 凹非寺 Stable Diffusion背后团队创始人&#xff0c;被曝巨大丑闻&#xff01; 这两天&#xff0c;福布斯发布的一则长新闻在网上病毒式传播&#xff1a; 30多位前员工投资人现身说法&#xff0c;细数Stability AI老板Emad Mostaque&#xff08;伊玛德莫斯塔克&…

马化腾聊天截图,被疯狂转发。

推荐阅读&#xff1a; 《在一个公司死磕了 5~10 年的人最后都怎么样了&#xff1f;》 《西安&#xff0c;被误解为贼城似乎是一件很正常的往事......》 1 裁员 前一段时间&#xff0c;一个有大佬九边&#xff0c;写了一篇关于裁员的文章&#xff0c;被马化腾给转发了&#xff0…

在「机器人领域」使用ChatGPT提高生产力

最近几个月&#xff0c;ChatGPT 大火&#xff0c;它是OpenAI于去年11月底推出的人工智能聊天机器人程序&#xff0c;已经成为了历史上增长最快的消费者应用程序 [1]。毫无疑问&#xff0c;ChatGPT受到了各个行业的广泛关注。 其中在机器人领域&#xff0c;微软于今年2月20日发布…

2020年一线城市程序员工资大调查

趋势 从趋势上看&#xff0c;基本上一线城市的工资都是上升的趋势。 人才需求 一线城市共发布岗位38115个&#xff0c;招聘120827人。 其中 beijing 22805 guangzhou 25081 shanghai 39614 shenzhen 33327 工资分布 2020年中国一线城市程序员的平均工资为16285元&#xff…

人工智能,落地为王!深圳人工智能企业百强榜超七成为应用层

中国工程院院士、香港中文大学(深圳)校长徐扬生认为&#xff0c;深圳具有完备的制造产业链&#xff0c;包括制造机器人的产业链&#xff0c;为设计、开发、制造人工智能系统提供了得天独厚的条件&#xff0c;这也不难理解为何深圳AI企业百强榜中超七成为应用层了。 人工智能作为…

致敬我在深圳大学的C++启蒙老师,跟着他学计算机编程就对了 (文末赠书5本)

致敬我的C启蒙老师&#xff0c;跟着他学计算机编程就对了 摘要 讲述了一个故事&#xff0c;介绍了一位良师&#xff0c;一段因C而续写的回忆&#xff0c;希望对各位看官有所帮助和启发。 文章目录 1 写在前面2 我的C启蒙老师3 谈谈老师给我的启发4 友情推荐5 文末福利 1 写在前…

本周杭州程序员工资大调查,高于深圳和广州

今天晚上11点&#xff0c;爬了某招聘网站&#xff0c;获取近7日内杭州的程序员工资2344条。其中&#xff0c;有工资的2275条。本文分别统计了工资的分布&#xff0c;工资和学历&#xff0c;工作经验和公司的性质&#xff0c;规模&#xff0c;产业的关系。 这里的程序员包括普通…

不得不说的Telegram : 币圈与链圈的微信

如果让你在「大而全的应用」和「小而美的应用」之间选一个&#xff0c;你会选择哪一个&#xff1f;你可以带着这个问题来阅读这篇软件体验报告&#xff0c;今天的主角是一款 IM 软件&#xff1a;Telegram Telegram Messenger 是一个跨平台的实时通讯软件&#xff0c;它的客户端…

再次来到爱丁堡

工作了几年后&#xff0c;作为访问学者再次来到爱丁堡。 出国访学有下面几个原因&#xff1a; 不太喜欢国内的科研环境。太浮躁&#xff0c;杂事也多。没有几个真正想搞学术的&#xff0c;大部分学术圈的人要么躺平&#xff0c;要么天天想着快速捞名利&#xff0c;我那个差单位…

【2020年领域新星】 赵彦鹏 爱丁堡大学

【2020年领域新星】赵彦鹏&#xff0c;爱丁堡大学语言、认知和计算研究所博士生&#xff0c;导师是Ivan Titov和Mirella Lapata教授。研究兴趣是结构预测和隐变量模型&#xff0c;现在主要关注语言结构和图像结构的学习&#xff0c;以及二者之间的联系。论文“Visually Grounde…

InstructGPT高效实践——【DeepSpeed-Chat】源码详解(2/3):Supervised Finetuning、Reward Model Finetuning

目录 前言1 phase-1: Supervised Finetuning1.1 训练数据样例1.2 训练过程1.3 关键代码详解1.3.1 基座模型结构1.3.2 LoRA结构及其正向传播1.3.3 phase1的指标评估 1.4 实例测试1.5 相关拓展1.5.1 多轮对话性能1.5.2 本阶段训练更倾向过拟合 1.6 版块相关问题 2 phase-2: Rewar…

NEWS|药物发现公司正在定制ChatGPT:方法如下

大型语言模型正在帮助科学家与人工智能交谈&#xff0c;甚至产生潜在的药物靶点。 近几个月来&#xff0c;世界大部分地区都被OpenAI的ChatGPT等文本生成引擎的出现所震惊&#xff0c;人工智能&#xff08;AI&#xff09;算法能够生成看起来像是由人类编写的文本。虽然像微软和…

ChatGPT强势加入芯片设计!不用学专业硬件描述语言了,说人话就行

西风 发自 凹非寺量子位 | 公众号 QbitAI 和ChatGPT聊聊天&#xff0c;就可解决CPU开发过程中的一大难题&#xff1f; 纽约大学&#xff08;NYU&#xff09;研究人员完成了一件看似不可能的事情&#xff1a; 无需专业的硬件描述语言&#xff08;HDL&#xff09;&#xff0c;仅靠…

激素、酶、细胞因子区别;肿瘤细胞信号通路

参考&#xff1a; https://www.xuetangx.com/course/THU08261001403/12423502?channeli.area.learn_title 本文章主要有chatgpt生成&#xff1a; 1、激素、酶、细胞因子区别 概念、功能 激素、酶和细胞因子都是生物活性物质&#xff0c;激素、酶和细胞因子都是蛋白质&#…