首先说明,Caffe表情识别的模型训练和测试全部在Windows上完成,全部在CPU上完成。训练过程参考了这篇博客
https://blog.csdn.net/pangyunsheng/article/details/79434263
当然这篇博主使用的是Ubuntu操作的,而我全部是在CPU-Windows完成,所以还是有很多不一样的地方,经过实际测试发现,这篇博客虽然讲解详细但是有以下几个明显缺点:
(1)细节仍然不够详细,我测试过按照他的步骤训练模型,精度一直在19%左右,显然里面存在错误,这边我已经解决这个问题
(2)模型训练实在Intel云上训练,看起来高上大,但是其实没有必要,而且我注册过Intel,好像已经不能训练了。
(3)测试采用Caffe模块测试,需要配置Caffe环境,Caffe我在有的Ubuntu配置很好,但是很多时候能把人搞崩溃,尤其我是安装了Anacoda环境,简直配置的令人抓狂?
(4)他图片弄成42x42的是不是有点小,数据集本身是48x48,为什么不用48x48呢?(注:我的模型是48x48)
而我这边刚好解决了上述所有毛病,此外如何查看loss和Accuray趋势?在windows上似乎,不太方便,不要紧,我已经开发一款软件可在windows查看loss和Accuray趋势,具体可以参考我的博客https://blog.csdn.net/FL1623863129/article/details/95727103,注意这个软件已经最近更新了,界面大体一样,但是横坐标已经被我优化成训练步骤了。下面发的训练精度图片可以看到。我的训练过程具有以下优点:
(1)人人熟悉windows,所以在windows操作都是习以为常
(2)查看loss和Accuray趋势在windows有点困难,需要配置,我试过没成功,原因是windows现在我不用python2.7老版本,官方提供的代码已经不能在新版python3上需要大量修改。我做的软件不需要搞这个崩溃人心的配置
(3)虽然训练在CPU有点慢,但是CPU我们人人有,GPU我们很少有,有也得配置,还想再来一次抓狂的配置?只是时间问题,10个小时我们等得起!
注意本文使用的fer2013数据集,经过网上查询,fer2013数据集训练模型不可能很高,大部分都集中在60%多左右,也有70多但是不知道别人是不是吹牛逼呢?为什么会这么低的精度呢?你可以打开图片看看就知道了,有的表情人都分不清,何况机器呢?而且七种表情界限有时候很难说的清楚。最重要的是有的天生长的是苦瓜脸,他认为是中性表情,其实就是Sad。有的人天生长的是个笑脸,即使他不笑,模型认为他也在happy。我这边训练精度大概在60%左右。具体看图
从上可以看出训练迭代在9万次其实已经收敛了,我已共训练了20万步,最终精度在60左右。
下面是我全过程大致操作流程:
(1)安装caffe-windows和Visual Studio2013,编译Caffe源码
(2)找到fer2013数据集,为jpg格式,大概有2-3万张
(3)将数据集转换为lmdb格式,我用的bat命令格式
(4)配置好网络文件,超参数文件,以及生成标签文件,标签文件我是C#生成的,也可以用Python、C++、dos等。反正简单,哪个上手用哪个
(5)运行训练脚本,开始模型训练,大概需要10多个小时,看你的电脑配置
(6)查看日志中Accuracy和loss趋势,以便调整训练策略
(7)得到Caffe模型,用于测试
我开始使用的是Atlst 200DK测试,已经开源在https://github.com/futureflsl/sample-faceemotion
这个东西高上大,不适合咱们劳苦大众,于是我又使用了opencv版本做了测试,人脸框使用的是haarcascade_frontalface_default.xml,Opencv自带的。代码开源如下:
import numpy as np
import cv2
from cv2 import dnn
'''
通过一个简单的脸图预测表情,这个代码利用opencv自动截取人脸识别,并显示
'''
emotion = {0: "anger", 1: "disgust", 2: "fear", 3: "happay", 4: "sad", 5: "surprised", 6: "normal"}
# 加载模型
net = dnn.readNetFromCaffe('deploy.prototxt', 'model__iter_200000.caffemodel')
# 读入图像
# 读入原始图像
img = cv2.imread('tt.jpg')
# 将图img转为灰度图,因opencv中的人脸检测是基于灰度的色彩空间
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 实例化级联分类器
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
# 调用图像中的对象,并返回矢量矩形
faceRects = face_cascade.detectMultiScale(gray, scaleFactor=1.2, minNeighbors=3, minSize=(50, 50))
if len(faceRects) == 0:
exit()
color = (0, 255, 0) # 定义绘制颜色
for faceRect in faceRects: # 单独框出每一张人脸
x, y, w, h = faceRect
# 灰度化处理
blob = dnn.blobFromImage(gray[x:x + w, y:y + h], 1, (48, 48), False, False)
# 传入模型
net.setInput(blob)
# 输出
prob = net.forward()
# print("Output:", prob.shape, prob.dtype)
# print(type(prob))
# print(prob)
# print(emotion[np.argmax(prob)])
cv2.rectangle(img, (x, y), (x + w, y + h), color, 3)
cv2.putText(img, emotion[np.argmax(prob)], (x, y), cv2.FONT_HERSHEY_COMPLEX, 1.0, (255, 0, 0), 3)
cv2.imshow("result", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
结果:
结果预测错误,人家明显在笑啊。可能是我的代码有问题,也可能是BlobFromImage的缩放因子,还有均值问题,当然也可能是模型精度不够的原因。我也封装了摄像头版本捕捉的版本,大家可以参考上述的代码自己封装一下摄像头实时人脸表情识别,经过测试预测Happy还是很准的,但是其他的有点不行,具体原因还在查,既然上面日志打印出来,应该模型不存在问题。好了,过程记录结束,模型和源码可以有偿提供,关注微信公众号:未来自主研究中心,可以@我,源码截图展示
这是脚本文件,运行starttrain.bat就可以开始训练了,这里注意下log是训练的日志文件,这个caffe-windows默认是没日志文件生成的,这个坑百度就知道了
这是数据集的操作,标签生成以及均值文件
这是模型文件和测试模型的代码,test是最简单的版本需要自己框人脸然后保存图片检测,test1.py是利用opencv人脸检测自动框人脸检测表情识别。test2.py是封装的类,这样简单易懂,test_camera是摄像头实时人脸表情检测。
这是网络配置文件和超参数文件。