1

我制作了一个基于人脸图像进行性别分类的小程序。我使用耶鲁人脸数据库(男性 175 张图像,女性相同数量),将它们转换为灰度和均衡直方图,因此预处理后的图像如下所示:

在此处输入图像描述

我运行以下代码来测试结果(它使用 SVM 和线性内核):

def run_gender_classifier():
    Xm, Ym = mkdataset('gender/male', 1)     # mkdataset just preprocesses images, 
    Xf, Yf = mkdataset('gender/female', 0)   #  flattens them and stacks into a matrix
    X = np.vstack([Xm, Xf])
    Y = np.hstack([Ym, Yf])
    X_train, X_test, Y_train, Y_test = train_test_split(X, Y,
                                                    test_size=0.1,
                                                    random_state=100)
    model = svm.SVC(kernel='linear')
    model.fit(X_train, Y_train)
    print("Results:\n%s\n" % (
        metrics.classification_report(
            Y_test, model.predict(X_test))))

并获得100%的精度

In [22]: run_gender_classifier()
Results:
             precision    recall  f1-score   support

          0       1.00      1.00      1.00        16
          1       1.00      1.00      1.00        19

avg / total       1.00      1.00      1.00        35

我可以期待不同的结果,但 100% 正确的图像分类对我来说真的很可疑。

此外,当我将内核更改为RBF时,结果变得非常糟糕:

In [24]: run_gender_classifier()
Results:
             precision    recall  f1-score   support

          0       0.46      1.00      0.63        16
          1       0.00      0.00      0.00        19

avg / total       0.21      0.46      0.29        35

这对我来说似乎更奇怪。

所以我的问题是:

  1. 我的方法或代码有什么错误吗?
  2. 如果不是,线性核的结果怎么会这么好,而 RBF 的结果怎么会这么差呢?

请注意,逻辑回归我也得到了 100% 正确的结果,而深度信念网络的结果非常差,所以它不是特定于 SVM,而是针对线性和非线性模型。


为了完整起见,这是我用于预处理和制作数据集的代码:

import cv2
from sklearn import linear_model, svm, metrics
from sklearn.cross_validation import train_test_split


def preprocess(im):
    im = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
    im = cv2.resize(im, (100, 100))
    return cv2.equalizeHist(im)


def mkdataset(path, label):
    images = (cv2.resize(cv2.imread(fname), (100, 100))
              for fname in list_images(path))
    images = (preprocess(im) for im in images)
    X = np.vstack([im.flatten() for im in images])
    Y = np.repeat(label, X.shape[0])
    return X, Y
4

2 回答 2

5

所有描述的模型都需要调整参数:

  • 线性支持向量机:C
  • RBF SVM:C,伽马
  • DBN:层数、神经元数、输出分类器、训练率……

而你只是省略了这个元素。所以很自然,具有最少数量的可调参数的模型表现得更好 - 因为默认参数实际工作的可能性更大。

100% 的分数总是看起来很可疑,您应该“手动”仔细检查 - 将数据物理拆分为训练和测试(放入不同的目录),训练一部分,将模型保存到文件中。然后在单独的代码中 - 加载模型,并在测试文件上测试它,并显示模型中的图像+标签。这样,您将确保没有实施错误(因为您真的不在乎是否存在任何处理错误,如果您有物理证据证明您的模型可以识别这些面孔,对吗?)。这纯粹是“心理方法”,很明显数据拆分/共享和进一步评估没有错误。

更新

正如评论中所建议的,我还检查了您的数据集,正如官方网站上所述:

扩展的耶鲁人脸数据库 B 包含 28 个人体受试者在 9 个姿势和 64 个光照条件下的 16128 张图像。

所以这肯定是一个问题——这不是性别识别的数据集。您的分类器只记住这 28 个主题,这些主题很容易分为男性/女性。它根本不适用于其他主题的任何图像。该数据集唯一“有价值”的部分是一组 28 张不同个体的面孔,您可以手动提取这些面孔,但 28 张图像似乎至少行数量级太小而无法使用。

于 2013-10-26T05:30:35.800 回答
-2

朋友,我理解你对你的问题的描述,我认为解释很简单,因为线性内核的问题比 RBF 更好,相信你的逻辑是正确的,但是你应该使用 RBF 有点错误,我认为它会起作用对于您的问题,继续尝试开发一种仅使用线性内核的方法

于 2013-10-25T22:48:59.723 回答