面部情绪识别(FER)指的是识别和分类基于人类情感面部表情通过分析面部特征和模式,机器可以对一个人的情绪状态做出有根据的猜测。面部识别的这一子领域是高度跨学科的,借鉴了计算机视觉、机器学习和心理学的见解。
在这篇研究文章中,我们将尝试从哲学和技术的角度理解面部情感识别的概念。我们还将探索一种习惯VGG13型模型体系结构与革命性人脸表情识别增强版(FER)数据集来构建一个整合的实时面部情感识别系统。最后,我们还将分析从实验中获得的结果。
- 人类情感的重要性
- 人工智能加速系统能检测人类情绪吗?
- 面部情绪识别的应用
- 构建面部情绪识别系统
- 结论
人类情感的重要性 哲学家们一直在争论情绪几个世纪以来。有些人将情绪视为纯粹的生理反应,而另一些人则将其视为复杂的心理状态,包括判断、欲望和信念。然而,其他人将情绪理解为社会建构的现象。从历史上看,情绪经常与理性形成对比,理性被视为优越的,情绪则是不稳定和破坏性的。然而,现代心理学和神经科学的观点认识到,情绪往往在决策、道德判断和其他认知过程中起着关键作用。
人工智能加速系统能检测人类情绪吗?
对人类来说,观察和解读我们周围世界的过程是直观的,似乎毫不费力。我们的眼睛捕捉光线,我们的视神经将这些数据传输到我们的大脑,在几毫秒内,我们的大脑处理这些信息,形成我们周围环境的连贯画面。这种感知、识别和解释的能力是数百万年进化完善的结晶。
另一方面,计算机对世界没有天生的理解。它们不像人类那样“看”。相反,它们通过数据来解释世界,在视觉的情况下,这些数据通常由相机提供。摄像机将视觉信息转换为数字数据,然后动物分类模型可以处理这些数据。
面部情绪识别的应用
事实证明,情感识别可以应用于多个领域。以下是一些可能有所帮助的关键领域:
社交和内容创作平台:
- 基于情感反馈的个性化用户体验。
- 自适应学习系统根据学习者的情绪状态调整内容,以提供更具针对性的推荐。
- 医学研究:
- 监测患者是否有抑郁、焦虑或其他情绪障碍的迹象。
- 协助治疗师跟踪患者在治疗过程中的进展或反应。
- 实时监控压力水平。
- 驾驶员安全机制:
- 监测驾驶员是否有疲劳、分心、压力或嗜睡的迹象。
- 市场营销和市场研究:
- 实时分析观众对广告的反应。
- 根据观众的情绪状态定制广告内容。
- 产品测试和反馈。
- 安全和监控:
- 在拥挤区域发现可疑或异常行为。
- 分析期间的人群反应
-
构建面部情绪识别系统
本节将深入探讨构建面部情绪识别系统的复杂性。我们首先探索一个为人脸情绪识别量身定制的数据集,确保为我们的模型奠定坚实的基础。接下来,我们将介绍一种定制的VGG13模型架构,该架构以其在分类任务中的效率和准确性而闻名,并阐明其与我们的情绪识别目标的相关性。最后,我们在实验结果部分花了一些时间来提供全面的评估,揭示了系统的性能指标及其潜在应用。面部表情识别数据集(FER+)FER+数据集是原始面部表情识别(FER)数据集的显著扩展。FER+是为了改进原始数据集的局限性而开发的,它为面部表情提供了更精细、更细致的标记。虽然最初的FER数据集将面部表情分为六种基本情绪——快乐、悲伤、愤怒、惊讶、恐惧。
FER+数据集中情感类别的扩展反映了对人类情感和表达复杂性的认识。事实证明,一个人大部分时间看起来都没有表情,因此“中性”是比较的基线,有助于解释个人的表情没有强烈传达任何主要情绪的情况。通过添加“中性”作为一个不同的类别,该数据集承认,并非所有面部表情都可以容易地归类为主要情绪标签。
用于人脸检测的RFB-320单点多盒检测器(SSD)模型
在识别情绪之前,需要在输入框中检测人脸。为此,使用了超轻量级人脸检测RFB-320。这是一个创新的人脸检测模型,针对边缘计算设备进行了优化。它结合了一个修改的接收字段块(RFB)模块,在不增加计算开销的情况下有效地捕获了多尺度上下文信息。培训时间:
自定义VGG13模型体系结构
情绪识别分类模型采用了为64×64灰度图像设计的定制VGG13架构。它使用具有最大池化和丢弃的卷积层将图像分类为八个情感类,以防止过拟合。该架构从64个内核的两个卷积层开始,然后是最大池化和25%的丢弃。额外的卷积层捕捉复杂的特征——两个密集层,每个层有1024个节点,聚合信息,然后是50%的丢弃。softmax输出层预测情绪类别。
图5所示的模型架构中,我们可以观察到黄色、绿色、橙色、蓝色和灰色分别是卷积层、最大池化层、丢弃层、完全连接层和软最大层。尽管数据集很小,但丢弃层是战略性地放置的,以遏制过度拟合。这增强了模型概括和准确识别各种图像中情绪的能力。在该实现中,该模型已经在上述FER+数据集上进行了预训练。
人脸表情识别的代码实现
好吧,让我们写一些代码来实际构建这个系统。最初,需要初始化一些重要的参数。
image_mean =np.array([127, 127, 127])
image_std =128.0
iou_threshold =0.3
center_variance =0.1
size_variance =0.2
min_boxes =[
[10.0,16.0,24.0],
[32.0,48.0],
[64.0,96.0],
[128.0,192.0,256.0]
- image_mean:RGB通道中图像归一化的平均值。
- image_std:图像标准化的标准偏差。
- iou_threshold:用于确定边界框匹配的交集(iou)度量的阈值。
- center_variance:预测边界框中心坐标的比例因子。
- size_variance:预测边界框尺寸的缩放因子。
- min_boxes:不同大小对象的最小边界框尺寸。
- 步幅:根据图像大小控制特征图的比例。
- threshold:对象检测的置信度阈值。
defdefine_img_size(image_size):
shrinkage_list=[]
feature_map_w_h_list=[]
forsize inimage_size:
feature_map=[int(ceil(size/stride))forstrideinstrides]
feature_map_w_h_list.append(feature_map)
fori inrange(0,len(image_size)):
shrinkage_list.append(strides)
priors=generate_priors(
feature_map_w_h_list, shrinkage_list, image_size, min_boxes
)
returnpriors
上述函数“define_img_size”旨在为对象检测任务生成先验边界框(先验)。此函数接受一个“image_size”参数作为输入。它根据提供的图像大小和一组预定义的步长值计算特征图尺寸。这些特征图维度反映了进化神经网络(CNN)层对于输入图像的不同尺度的预期输出维度。本质上,SSD中的先验提供了一种有效的方法,可以在网络的单个前向通道中同时预测多个边界框及其相关的类分数,从而实现实时对象检测。
代码通过复制“image_size”列表中每个元素的“steps”列表来准备“shrinkage_list”。随后,该代码调用名为“generate_priors”的函数,传递计算出的特征图尺寸、收缩信息、“image_size”和预定义的最小边界框尺寸集。generate_p的目的。
defgenerate_priors(feature_map_list, shrinkage_list, image_size, min_boxes):
priors=[]
forindex inrange(0,len(feature_map_list[0])):
scale_w=image_size[0]/shrinkage_list[0][index]
scale_h=image_size[1]/shrinkage_list[1][index]
forj inrange(0, feature_map_list[1][index]):
fori inrange(0, feature_map_list[0][index]):
x_center=(i+0.5) /scale_w
y_center=(j+0.5) /scale_h
formin_box inmin_boxes[index]:
w=min_box/image_size[0]
h=min_box/image_size[1]
priors.append([
x_center,
y_center,
w,
h
该代码定义`generate_priors`,一个为对象检测生成预先边界框的函数。使用要素图、图像尺寸和最小框尺寸等输入数据,它计算并规范化边界框坐标。该函数积累并返回这些框,从而形成精确对象定位的重要参考。
defhard_nms(箱内核,iou_threshold,top_k= -1,候选大小= two hundred):
得分=box_scores[:,-1]
盒=box_scores[:,:-1]
挑选=[]
索引= np.参数排序(分数)
索引=索引[-候选大小:]
虽然len(索引)>0 :
现在的=索引[-1]
picked.append(当前)
如果0< top_k==len(选中)orlen(indexes) ==1:
打破
当前框=框[当前,:]
索引=索引[:-1]
rest_box(_B)=框[索引,:]
欠条=iu_of(
rest_ boxes,
np.expand_dims(当前框,轴= zero),
硬件(_N)`该函数实现目标检测的硬非最大抑制(NMS)。它处理`框_核心`参数如下`iou阈值 `, `顶部(_k)`、和`候选_大小`. 它通过循环和IoU计算选择得分高、不重叠的方框。该函数返回一个细化的方框子集,提高了对象检测的准确性。
右_下=np.最小值(方框0[。。。,2:],方框1[。。。,2 :])
重叠_区域=区域(重叠左上,重叠右下)
区域0=区域(方框0[…,:2],方框0[。。。,2 :])
区域1=区域(方框1[…,:2],方框1[。。。,2 :])
returnoverlap_area /(area0 +area1 -overlap_area +eps)
区域(_O)`函数使用左上角和右下角坐标计算矩形区域。它通过以下方式避免了负值`np.卡瓦`. 另一方面`iou_of`该函数通过评估两组框之间的重叠区域来计算IoU。它利用了`区域(_O)`功能和帮助通过量化边界框重叠来评估检测精度。
defpredict(
width,
height,
confidences,
boxes,
prob_threshold,
iou阈值=0.3,
顶部(_k)= -1
):
盒=boxes[0]
confidences=confidences[0]
picked_box_probs=[]
picked_labels=[]
forclass_index inrange(1, confidences.shape[1]):
probs=confidences[:, class_index]
mask=probs > prob_threshold
probs=probs[mask]
如果probs.shape[ zero] == zero:
continue
subset_boxes=boxes[mask, :]
box_probs=np.concatenate(
[subset_boxes, probs.reshape(-1, 1)], axis=1
)
box_probs=hard_nms(box_probs,
iou阈值=iou_threshold,
顶部(_k)=top_k,
`predict’函数细化对象检测模型结果,生成准确的边界框预测、标签和置信度。它根据提供的阈值过滤预测,并采用非最大抑制(NMS)来消除冗余。该函数接受诸如“width”、“height”、“confidences”、和`盒`, 并输出精确的边界框坐标、标签和置信度。
defconvert_locations_to_boxes(locations, priors, center_variance,
size_variance):
如果len(priors.shape)+1==len(locations.shape):
priors=np.expand_dims(priors,0)
returnnp.concatenate([
locations[..., :2]*center_variance*priors[...,2:]+priors[..., :2],
np.exp(locations[...,2:]*size_variance)*priors[...,2:]
], axis=len(locations.shape) -1)
defcenter_form_to_corner_form(locations):
returnnp.concatenate(
[locations[..., :2]-locations[...,2:]/2,
locations[..., :2]+locations[...,2:]/2],
len(locations.shape)
函数convert_locations_to_boxes在将预测的偏移和比例转换为实际边界框坐标方面发挥着关键作用。通过使用给定的信息和调整“center_variance”和“size_variance”等因素,它可以校正预测的边界框,以准确地显示对象的位置和大小。
而“center_form_to_corner_form”函数的作用是将边界框坐标从基于中心的表示转换为基于角的格式。这种转换对于与不同检测算法的兼容性和有效地可视化边界框至关重要。该函数重新校准边界框的中心坐标和尺寸,以表示左上角和右下角。
defFER_live_cam():
emotion_dict={
zero: 'neutral',
1: 'happiness',
2: 'surprise',
3: 'sadness',
4: 'anger',
5: 'disgust',
6: 'fear'
}
# cap = cv2.VideoCapture('video1.mp4')
cap=cv2.VideoCapture(0)
frame_width=int(cap.get(3))
frame_height=int(cap.get(4))
size=(frame_width, frame_height)
result=cv2.VideoWriter('result.avi',
cv2.VideoWriter_fourcc(*'MJPG'),
10, size)
# Read ONNX model
model='onnx_model.onnx'
model=cv2.dnn.readNetFromONNX('emotion-ferplus-8.onnx')
# Read the Caffe face detector.
model_path='RFB-320/RFB-320.caffemodel'
proto_path='RFB-320/RFB-320.prototxt'
net=dnn.readNetFromCaffe(proto_path, model_path)
input_size=[320,240]
width=input_size[0]
height=input_size[1]
priors=define_img_size(input_size)
虽然cap.isOpened():
ret, frame=cap.read()
如果ret:
img_ori=frame
#print("frame size: ", frame.shape)
rect=cv2.resize(img_ori, (width, height))
rect=cv2.cvtColor(rect, cv2.COLOR_BGR2RGB)
net.setInput(dnn.blobFromImage(
rect,1/image_std, (width, height), 127)
)
start_time=time.time()
boxes, scores=net.forward(["boxes","scores"])
盒=np.expand_dims(np.reshape(boxes, (-1, 4)), axis=0)
得分=np.expand_dims(np.reshape(scores, (-1, 2)), axis=0)
盒=convert_locations_to_boxes(
boxes, priors, center_variance, size_variance
)
盒=center_form_to_corner_form(boxes)
boxes, labels, probs=predict(
img_ori.shape[1],
img_ori.shape[0],
scores,
boxes,
threshold
)
gray=cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
for(x1, y1, x2, y2) inboxes:
w=x2-x1
h=y2-y1
cv2.rectangle(frame, (x1,y1), (x2, y2), (255,0,0),2)
resize_frame=cv2.resize(
gray[y1:y1+h, x1:x1+w], (64,64)
)
resize_frame=resize_frame.reshape(1,1,64,64)
model.setInput(resize_frame)
output=model.forward()
end_time=time.time()
fps=1/(end_time-start_time)
print(f"FPS: {fps:.1f}")
pred=emotion_dict[list(output[0]).index(max(output[0]))]
cv2.rectangle(
img_ori,
(x1, y1),
(x2, y2),
(0,255,0),
2,
lineType=cv2.LINE_AA
)
cv2.putText(
frame,
pred,
(x1, y1),
cv2.FONT_HERSHEY_SIMPLEX,
0.8,
(0,255,0),
2,
lineType=cv2.LINE_AA
)
result.write(frame)
函数“FER_live_cam()”对视频帧进行实时面部情绪识别。它首先建立了一个词典“emotion_dict”,将数字情感类索引映射到人类可读的情感标签。视频源已初始化,尽管有使用网络摄像头馈送的规定。该函数还初始化输出视频编写器,以保存带有情感注释的处理帧。以ONNX格式保存的主要情绪预测模型使用OpenCV DNN“readNetFromONNX”方法读取,并与Caffe格式的RFB-30 SSD人脸检测模型一起加载。随着视频被逐帧处理,人脸检测模型识别由边界框表示的人脸。
这些检测到的人脸在被输入情绪识别模型之前,要经过预处理——调整大小并转换为灰度。通过模型的最大输出分数确定的识别情感被映射到使用“emotion_dict”的标签。
实验结果
让我们看看使用这个模型和人类表现出不同面部情绪的库存镜头的一些推断结果。
这篇研究文章揭示了人类情感与尖端深度学习技术进步之间错综复杂的相互作用。从人类感知体验到数字领域的旅程是一次引人入胜的探索,不仅揭示了深度学习的巨大潜力,还提出了关于情感本质及其解释的深刻哲学问题。
从纯粹的技术角度来看,面部情绪识别领域取得的进步是显著的。卷积神经网络等深度学习模型的使用,使人们能够开发出能够从面部表情中准确识别情绪的系统。这些进步为从医疗保健和教育到人机交互和营销的广泛应用带来了希望。
然而,当我们惊叹于这些技术的能力时,我们也必须面对哲学上的考虑。