14、机器学习中的分类器性能评估与表情识别应用

机器学习中的分类器性能评估与表情识别应用

1. 分类器性能指标

一个优秀的分类器目标是使混淆矩阵成为对角矩阵,这意味着每个样本的真实类别(c_true)和预测类别(c_pred)相同。下面介绍几个重要的分类器性能指标:
- 准确率(Accuracy) :计算最简单的指标,通过统计正确预测的测试样本数量,并将其表示为总测试样本数的比例。代码实现如下:

def __accuracy(self, y_test, y_vote):
    """ Calculates the accuracy based on a vector of ground-truth  
        labels (y_test) and a 2D voting matrix (y_vote) of size  
        (len(y_test),numClasses). """
    y_hat = np.argmax(y_vote, axis=1)
    mask = (y_hat == y_test)
    return np.count_nonzero(mask)*1./len(y_test)
  • 精确率(Precision) :在二分类中,精确率衡量检索到的相关实例的比例。在多分类中,其计算会根据分类策略有所不同。
    • 一对一(one-vs-one)策略 :需要使用混淆矩阵计算。
    • 一对多(one-vs-all)策略 :计算相对简单。
      代码实现如下:
def __precision(self, y_test, Y_vote):
    """ precision extended to multi-class classification """
    y_hat = np.argmax(Y_vote, axis=1)
    if True or self.mode == "one-vs-one":
        conf = self.__confusion(y_test, y_vote)
        prec = np.zeros(self.numClasses)
        for c in xrange(self.numClasses):
            tp = conf[c,c]
            fp = np.sum(conf[:,c]) - conf[c,c]
            if tp + fp != 0:
                prec[c] = tp*1./(tp+fp)
    elif self.mode == "one-vs-all":
        prec = np.zeros(self.numClasses)
        for c in xrange(self.numClasses):
            tp = np.count_nonzero((y_test==c) * (y_hat==c))
            fp = np.count_nonzero((y_test==c) * (y_hat!=c))
            if tp + fp != 0:
                prec[c] = tp*1./(tp+fp)
    return prec
  • 召回率(Recall) :召回率衡量检索到的相关实例的比例,与精确率类似,但计算时考虑的是假阴性。计算过程也会根据分类策略有所不同。
    代码实现如下:
def __recall(self, y_test, Y_vote):
    """ recall extended to multi-class classification """
    y_hat = np.argmax(Y_vote, axis=1)
    if True or self.mode == "one-vs-one":
        conf = self.__confusion(y_test, y_vote)
        recall = np.zeros(self.numClasses)
        for c in xrange(self.numClasses):
            tp = conf[c,c]
            fn = np.sum(conf[c,:]) - conf[c,c]
            if tp + fn != 0:
                recall[c] = tp*1./(tp+fn)
    elif self.mode == "one-vs-all":
        recall = np.zeros(self.numClasses)
        for c in xrange(self.numClasses):
            tp = np.count_nonzero((y_test==c) * (y_hat==c))
            fn = np.count_nonzero((y_test!=c) * (y_hat==c))
            if tp + fn != 0:
                recall[c] = tp*1./(tp+fn)
    return recall
2. 综合性能评估流程

为了比较不同设置和特征提取方法下的分类性能,我们需要执行以下步骤:
1. 导入相关模块并设置主函数:

import numpy as np
import matplotlib.pyplot as plt
from datasets import gtsrb
from classifiers import MultiClassSVM
def main():
  1. 定义分类策略和特征提取方法:
    strategies = ['one-vs-one', 'one-vs-all']
    features = [None, 'gray', 'rgb', 'hsv', 'surf', 'hog']
  1. 初始化性能指标矩阵:
    accuracy = np.zeros((2,len(features)))
    precision = np.zeros((2,len(features)))
    recall = np.zeros((2,len(features)))
  1. 使用嵌套循环遍历所有设置:
    for f in xrange(len(features)):
        (X_train,y_train), (X_test,y_test) = gtsrb.load_data(  
            "datasets/gtsrb_training",  
            feature=features[f], test_split=0.2)
        X_train = np.squeeze(np.array(X_train)).astype(np.float32)
        y_train = np.array(y_train)
        X_test = np.squeeze(np.array(X_test)).astype(np.float32)
        y_test = np.array(y_test)
        labels = np.unique(np.hstack((y_train,y_test)))
        for s in xrange(len(strategies)):
            MCS = MultiClassSVM(len(labels),strategies[s])
            MCS.fit(X_train, y_train)
            (accuracy[s,f],precision[s,f],recall[s,f]) =  
                MCS.evaluate(X_test, y_test)
  1. 可视化结果:
    f,ax = plt.subplots(2)
    for s in xrange(len(strategies)):
        x = np.arange(len(features))
        ax[s].bar(x-0.2, accuracy[s,:], width=0.2, color='b',  
            hatch='/', align='center')
        ax[s].bar(x, precision[s,:], width=0.2, color='r',  
            hatch='\\', align='center')
        ax[s].bar(x+0.2, recall[s,:], width=0.2, color='g',  
            hatch='x', align='center')
        ax[s].axis([-0.5, len(features) + 0.5, 0, 1.5])
        ax[s].legend(('Accuracy','Precision','Recall'), loc=2,  
            ncol=3, mode="expand")
        ax[s].set_xticks(np.arange(len(features)))
        ax[s].set_xticklabels(features)
        ax[s].set_title(strategies[s])
    plt.show()
3. 结果分析
  • HOG 特征表现出色 :无论采用何种分类策略,HOG 特征的性能都优于其他特征,这凸显了特征提取的重要性。
  • 一对一策略优势 :使用一对一策略时,所有方法的准确率都超过 0.95,可能是因为二分类任务有时比 10 分类任务更容易学习。
  • 归一化效果 :比较“None”和“rgb”设置的结果,可以看到归一化对性能有明显影响,尤其是在一对多策略下。
  • 颜色变换效果不佳 :RGB 和 HSV 等颜色变换的性能并不比简单的灰度变换好,SURF 特征也没有起到明显作用。
4. 人脸表情识别应用

目标是开发一个结合人脸检测和人脸识别的应用,重点是识别检测到的人脸的情感表达。为了实现这一目标,需要解决以下两个挑战:
- 人脸检测 :使用 Viola 和 Jones 提出的 Haar 级联分类器,OpenCV 提供了一系列预训练的模型。利用人脸级联和眼睛级联来可靠地检测和对齐面部区域。
- 面部表情识别 :训练一个多层感知器(MLP)来识别六种不同的情感表达。为了提高自记录训练集的质量,需要使用仿射变换对齐所有数据样本,并通过主成分分析(PCA)降低特征空间的维度。

5. 应用组件

最终的应用需要以下几个组件:
| 组件 | 功能 |
| ---- | ---- |
| chapter7 | 主脚本和入口点 |
| chapter7.FaceLayout | 自定义布局,有训练和测试两种模式 |
| chapter3.main | 启动 GUI 应用的主函数 |
| detectors.FaceDetector | 人脸检测类,包含检测和对齐方法 |
| classifiers.Classifier | 所有分类器的抽象基类 |
| classifiers.MultiLayerPerceptron | 实现 MLP 的类,包含训练、评估、预测、保存和加载方法 |
| train_test_mlp | 训练和测试 MLP 的脚本 |
| datasets.homebrew | 解析自记录训练集的类,包含加载数据、从文件加载和特征提取方法 |
| gui | 提供 wxPython GUI 应用的模块 |

mermaid 流程图如下:

graph LR
    A[开始] --> B[导入模块和设置主函数]
    B --> C[定义策略和特征]
    C --> D[初始化性能矩阵]
    D --> E[嵌套循环遍历设置]
    E --> F[训练分类器并评估性能]
    F --> G[可视化结果]
    G --> H[人脸表情识别应用]
    H --> I[人脸检测]
    H --> J[面部表情识别]
    I --> K[使用Haar级联分类器]
    J --> L[训练MLP并预处理数据]
    K --> M[应用组件构建]
    L --> M
    M --> N[结束]

以上就是关于分类器性能评估和人脸表情识别应用的详细介绍,通过这些方法和组件,我们可以开发出高效准确的分类和识别系统。

6. 各组件详细功能及操作步骤
6.1 chapter7.FaceLayout
  • 训练模式
    1. 收集图像帧。
    2. 在图像帧中检测人脸。
    3. 根据面部表情为检测到的人脸分配标签。
    4. 退出时,将所有收集的数据样本保存到文件,以便 datasets.homebrew 解析。
  • 测试模式 :在每个视频帧中检测人脸,并使用预训练的 MLP 预测相应的类别标签。
6.2 detectors.FaceDetector
  • detect 方法
    1. 输入一张灰度图像,可选择对图像进行下采样以提高检测可靠性。
    2. 在图像中检测人脸。
    3. 若检测成功,返回提取的头部区域。
  • align_head 方法 :对提取的头部区域进行仿射变换预处理,使最终的人脸居中且直立。
6.3 classifiers.MultiLayerPerceptron
  • fit 方法
    1. 输入训练数据矩阵,每行是一个训练样本,列包含特征值。
    2. 输入标签向量。
    3. 将 MLP 拟合到训练数据。
  • evaluate 方法
    1. 输入测试数据矩阵,每行是一个测试样本,列包含特征值。
    2. 输入标签向量。
    3. 训练后将 MLP 应用于测试数据,返回准确率、精确率和召回率三个性能指标。
  • predict 方法 :输入测试数据,预测其类别标签,可应用于任意数量的数据样本,在测试模式中很有用。
  • save 方法 :将训练好的 MLP 保存到文件。
  • load 方法 :从文件中加载预训练的 MLP。
6.4 datasets.homebrew
  • load_data 方法
    1. 加载训练集。
    2. 通过 extract_features 函数对数据进行 PCA 处理。
    3. 将数据拆分为训练集和测试集。
    4. 可选择将预处理后的数据存储在文件中,以便后续直接加载。
  • load_from_file 方法 :从文件中加载先前存储的预处理数据集。
  • extract_features 方法 :提取所选特征(在本章中为对数据进行 PCA 处理),可应用于任意数量的数据样本,在测试模式中很有用。
7. 训练和测试 MLP 脚本流程

train_test_mlp 脚本用于训练和测试 MLP,具体流程如下:
1. 探索不同的网络架构。
2. 在自记录的数据集上应用不同架构的 MLP 进行训练和测试。
3. 选择具有最佳泛化性能的架构。
4. 将该架构的 MLP 保存到文件,以便后续加载使用。

8. 总结与要点回顾
要点 详情
分类器性能指标 包括准确率、精确率和召回率,计算方法因分类策略(一对一、一对多)而异
综合评估流程 导入模块、定义策略和特征、初始化矩阵、嵌套循环遍历设置、训练评估、可视化结果
结果分析 HOG 特征出色,一对一策略有优势,归一化影响性能,颜色变换效果不佳
人脸表情识别挑战 人脸检测用 Haar 级联分类器,面部表情识别训练 MLP 并预处理数据
应用组件 包含主脚本、布局、检测类、分类器类、训练脚本、数据集解析类和 GUI 模块等

mermaid 流程图展示 MLP 训练和测试流程:

graph LR
    A[开始] --> B[探索网络架构]
    B --> C[加载自记录数据集]
    C --> D[不同架构MLP训练]
    D --> E[不同架构MLP测试]
    E --> F[选择最佳泛化性能架构]
    F --> G[保存最佳架构MLP到文件]
    G --> H[结束]

通过上述对分类器性能评估和人脸表情识别应用的全面介绍,我们了解了从理论到实践的完整过程。从分类器性能指标的计算,到不同特征和策略下的综合评估,再到人脸表情识别的具体实现和相关组件的功能,我们可以构建出一个完整的机器学习应用系统。掌握这些知识和技术,有助于我们在实际项目中开发出高效、准确的分类和识别系统。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值