数据科学竞赛-人脸表情识别
人脸表情识别
简介
这是科赛网曾今的一次计算机视觉类的分类赛,属于一个视觉基础任务。关于人脸表情识别,Kaggle等平台也举办过相关的比赛,难度并不算大,但是对技巧的要求比较高。本文详述该比赛的主要步骤,并构建多个模型对比效果。
数据探索
这部分主要是对数据集的简单探索,由于计算机视觉类比赛数据多为图片或者视频格式,无需像挖掘赛那样进行比较复杂的EDA。这部分的代码可以在文末给出的Github仓库的EDA.ipynb
文件中找到。
数据集的目录形式如下(数据集分享于百度云,提取码为zczc),由于本比赛只需要将五种区分度比较明显的表情识别出来,所以共五个文件夹,每个文件夹内的图片为一类。
首先,生成了如下的csv格式的数据集说明文件如下,包含两列,分别为文件的相对路径和标签。对该说明文件进行分析更加的方便,因为这个文件包含大多数数据集的信息,且Pandas提供了很多分析的API,很容易对表格数据处理。
首先观察类别的分布,很遗憾,数据的类别分布如下。这是因为有的表情数据确实很少,尽管我们确实希望数据的分布是均衡的,但是这里的影响也不是很大,后面通过数据增强,会对这个情况有所改善。
随后,随机采样10张图片展示并显示标签,结果如下。通过这一步的观察,不难发现,其实图片中不仅仅是目标-人脸表情,有很多背景干扰因素,这就要求需要进行人脸检测及图片裁减了,也就是输入深度模型中的不应该是原图而应该是裁减后的人脸图片。
数据预处理
这部分主要对图片进行人脸截取,实现的原理是基于目标检测的思路,分为传统方法和深度方法,为了更快得到结果,这里使用软件包face_recognition
进行人脸检测(注意处理单图片多人脸情况),这是一个非常简单的封装好的人脸识别库,可以通过pip安装(若安装出错一般是dlib问题,安装dlib的我回来文件即可)。
其人脸检测的结果保存到本地后结果如下。注意,这个数据生成的过程时间较长。
核心代码如下,具体代码见文末Github。
def preprocess():categories = os.listdir(data_folder)for category in categories:in_path = os.path.join(data_folder, category)out_path = os.path.join(generate_folder, category + '_face')if not os.path.exists(out_path):os.mkdir(out_path)for file in glob(in_path + '/*.jpg'):file_name = file.split('\\')[-1]print(file_name)img = face_recognition.load_image_file(file)if max(img.shape) > 2000:if img.shape[0] > img.shape[1]:img = cv2.resize(img, (2000, int(2000 * img.shape[1] / img.shape[0])))else:img = cv2.resize(img, (int(2000 * img.shape[0] / img.shape[1]), 2000))locations = face_recognition.face_locations(img) # 人脸检测,大部分为单个,但也有多个检测结果if len(locations) <= 0:print("no face")else:for i, (a, b, c, d) in enumerate(locations):image_split = img[a:c, d:b, :]image_split = scale_img(image_split)Image.fromarray(image_split).save(os.path.join(out_path, file_name + '_{}.png'.format(i)))
数据加载
由于数据集已经被处理为很规范的数据集格式,这里直接调用TF2中Keras接口解析数据集(自己写迭代器也是合适的,这里为了开发的速度采用封装好的API),返回一个迭代器,同时在该接口中设置一些数据增强手段,这里主要使用水平翻转。
具体代码如下,关于如何使用Keras的数据加载接口可以见我之前的博客。
代码如下,具体整个项目的代码见文末Github。
class DataSet(object):def __init__(self, root_folder):self.folder = root_folderself.df_desc = pd.read_csv(self.folder + 'description.csv', encoding="utf8")def get_generator(self, batch_size=32, da=True):if da:# 数据增强train_gen = ImageDataGenerator(rescale=1 / 255., validation_split=0.2, horizontal_flip=True, shear_range=0.2,width_shift_range=0.1)else:train_gen = ImageDataGenerator(rescale=1 / 255., validation_split=0.2, horizontal_flip=False)img_size = (64, 64)train_generator = train_gen.flow_from_dataframe(dataframe=self.df_desc,directory='.',x_col='file_id',y_col='label',batch_size=batch_size,class_mode='categorical',target_size=img_size,subset='training')valid_generator = train_gen.flow_from_dataframe(dataframe=self.df_desc,directory=".",x_col="file_id",y_col="label",batch_size=batch_size,class_mode="categorical",target_size=img_size,subset='validation')return train_generator, valid_generator
模型构建
主要尝试了构建一个简单的CNN模型进行训练和预测,这是模型较浅,这是考虑到可能的部署后的速度而采取的设计方法;此外,使用ResNet50模型结构尝试训练和预测。本文采用TensorFlow2.0构建模型进行训练,这是TF2是一个很不错的深度学习框架,相比于TF1很容易学习和使用,具体的可以查看我TensorFlow2系列的教程博客。
def CNN(input_shape=(224, 224, 3), n_classes=5):# inputinput_layer = Input(shape=input_shape)x = Conv2D(32, (1, 1), strides=1, padding='same', activation='relu')(input_layer)# block1x = Conv2D(64, (3, 3), strides=1, padding='same')(x)x = PReLU()(x)x = Conv2D(64, (5, 5), strides=1, padding='same')(x)x = PReLU()(x)x = MaxPooling2D(pool_size=(2, 2), strides=2)(x)# fcx = Flatten()(x)x = Dense(2048, activation='relu')(x)x = Dropout(0.5)(x)x = Dense(1024, activation='relu')(x)x = Dropout(0.5)(x)x = Dense(n_classes, activation='softmax')(x)model = Model(inputs=input_layer, outputs=x)return modeldef ResNet_pretrained(input_shape=(224, 224, 3), n_classes=5):input_layer = Input(shape=input_shape)densenet121 = ResNet50(include_top=False, weights=None, input_tensor=input_layer)x = GlobalAveragePooling2D()(densenet121.output)x = Dropout(0.5)(x)x = Dense(n_classes, activation='softmax')(x)model = Model(input_layer, x)return model
对比两个模型的效果如下图,训练集很快达到接近100%的准确率,验证集却几乎不怎么变化,说明模型的效果还是比较一般的,这主要是因为不同类的数据量差距太大(有的类别几百个样本有的类别几万个样本),模型很难训练,或者说很快达到极限。
这里注意,表情识别比赛只是一个简单的分类赛,采用合适的深度特征提取网络即可取得不错的效果,对于这种分类问题一般采用端到端的模型设计即可,即使用分类损失交叉熵进行预测结果衡量,优化器选择的是Adam,当然,为了更加适应任务可以自己设计合适的损失函数如focal损失,当然,这也只是锦上添花而已,真正需要优化的还是模型的结构。此外,也可以考虑RGB转为Gray图从而减少冗余信息等手段,或者引入更多的数据集进行训练。
补充说明
真正构建实际系统是可以在模型应用的预测端进行一个增广预测,将得到的结果进行加权从而得到真正的预测结果,具体可以参考我之前的项目。所有代码开源于我的Github,欢迎Star或者Fork。
数据科学竞赛-人脸表情识别相关推荐
- 人脸表情识别 (1) 下载fer2013数据集和数据的处理
最近做了有关人脸表情识别的实验,还是挺有意思的,所以想在博客上记录这个过程,既是给自己做个记录,也想把这个过程分享给大家,如果能对你有一些帮助我会感到挺开心的,模型,数据集之类的我都会陆续上传,有需要 ...
- 人脸表情识别系统(VGG_16和Xception模型)配置GPU加速,Fer2013数据集和CK+数据集,tensorboard
编译器 python3.8 开发平台 Pycharm PyQT5 系统界面 (可视化开发工具designer ) 模型训练基于深度学习tensorflow框架 opencv haar cascade ...
- 【完结】如何掌握基于图像和视频的人脸表情识别,这9篇文章可以作为一个参考...
文/编辑 | 言有三 人脸表情识别(Facial Expression Recognition,FER)作为人脸识别技术中的一个重要组成部分,近年来在人机交互.安全.机器人制造.自动化.医疗.通信和驾 ...
- 【人脸表情识别】情绪识别相关会议、比赛汇总(2018-2020)
前面专栏中,我们介绍了有关基于图片/视频的人脸表情识别的相关内容,也了解了通过回归的方式来理解表情的方式--基于连续模型的人脸表情识别.在专栏的最后一篇文章中,我们将分享计算机视觉领域中围绕情绪识别主 ...
- 人脸表情识别和情绪分类 | Python+TensorFlow(框架)+Keras+PyQt5
人脸表情识别 | Python+Keras+PyQt5 参考学习文章: Keras|基于深度学习的人脸表情识别系统 PyQt5+QtDesigner编写摄像头界面程序(一)--pyqt5.qtdesi ...
- 【人脸表情识别】基于回归模型的人脸表情识别方法
前面几篇专栏中,我们介绍了有关基于图片/视频的人脸表情识别的相关内容,这两个领域采用解决分类问题的方法来对表情进行识别.这篇文章,我们将介绍通过回归的方式来理解表情的方式--基于连续模型的人脸表情识别 ...
- Keras|基于深度学习的人脸表情识别系统
更新内容(2019-4-12) 已将Keras版本模型权重压缩之后上传至GItHub,可以自取 更新内容(2018-12-9) 正好在学习tensorflow,使用tensorflow重构了一下这个系 ...
- CVPR 2020几篇论文内容点评:目标检测跟踪,人脸表情识别,姿态估计,实例分割等
CVPR 2020几篇论文内容点评:目标检测跟踪,人脸表情识别,姿态估计,实例分割等 CVPR 2020中选论文放榜后,最新开源项目合集也来了. 本届CPVR共接收6656篇论文,中选1470篇,&q ...
- 从0到1构建数据科学竞赛知识体系,有夕,鱼佬,茂霖等竞赛大咖将特邀分享...
从0到1构建数据科学竞赛知识体系 这是怎样的数据竞赛知识体系 为了帮助更多竞赛选手入门进阶比赛,通过数据竞赛提升理论实践能力和团队协作能力.DataFountain 和 Datawhale 联合邀请了 ...
最新文章
- Windows XP with SP3 All Edtion Download
- python设计_设计和历史常见问题
- Ubuntu14.04-LAMP环境搭建
- [工具库]JFileDownloader工具类——多线程下载网络文件,并保存在本地
- Java反射 Class类
- axios vue 回调函数_VUE使用axios调用后台API接口的方法
- iptables 开放端口
- LINGO语法及软件操作
- 【算法】并查集(Java)
- kubectl 命令详解(三十四):rollout status
- 活久见:都 2203 年了,你还在使用 word 调试 API
- android 执行bin文件是什么意思,将可执行文件复制到android中的system / bin
- iphone应用隐私政策_如何在iPhone上“隐藏”联系人以获得更大的隐私
- wince6下载地址
- Ubuntu安装软件包网络不可达问题
- HTML网页制作基础教程
- 对面试常见问题的一些总结
- Java基础 - 坦克大战(第四章,线程基础)
- 螺钉分类及表面处理种类
- 如何开始阅读ASP.NET Core源代码