【问题标题】:Problems with SVM to gender recognition支持向量机对性别识别的问题
【发布时间】:2015-07-12 08:04:26
【问题描述】:

这几天我一直在使用 SVM 进行性别识别项目(在 python 中),但我迷失了我获得的结果:

为什么男性的召回率为 0.09,女性的召回率为 1?还是女性的准确率只有 50%?

SVM Accuracy: 0.540041067762
Classification report:
           precision   recall  f1-score   support
Females       0.52      1.00      0.68       242
Males         1.00      0.09      0.16       245

avg / total       0.76      0.54      0.42       487

我已对所有图像进行了裁剪、对齐和灰度处理 如何提高精度?

我需要更改以下参数:clf = svm.SVC()?

我的代码:

import os, sys
import numpy as np
import PIL.Image as Image
import cv2
from sklearn import svm
from sklearn.externals import joblib
from sklearn.cross_validation import train_test_split
from sklearn.metrics import classification_report
from sklearn.metrics import accuracy_score


def read_images(path, id, sz=None):
    c = id
    X,y = [], []
    for dirname, dirnames, filenames in os.walk(path):
        for subdirname in dirnames:
            subject_path = os.path.join(dirname, subdirname)
            for filename in os.listdir(subject_path):
                try:
                    im = Image.open(os.path.join(subject_path, filename))
                    im = im.convert("L")
                    # resize to given size (if given)
                    if (sz is not None):
                        im = im.resize(sz, Image.ANTIALIAS)
                    X.append(np.asarray(im, dtype=np.uint8).ravel())
                    y.append(c)
                except IOError as e:
                    print "I/O error({0}): {1}".format(e.errno, e.strerror)
                except:
                    print "Unexpected error:", sys.exc_info()[0]
                    raise
                        #c = c+1

    return [X,y]


def main():

    contador = 0;

    # check arguments
    if len(sys.argv) != 3:
        print "USAGE: example.py </path/to/images/males> </path/to/images/females>"
        sys.exit()

    # read images and put them into Vectors and id's
    [X,x] = read_images(sys.argv[1], 1)
    [Y, y] = read_images(sys.argv[2], -1)

    # R all images and r all id's
    [R, r] = [X+Y, x+y]
    R_train, R_test, r_train, r_test = train_test_split(R, r)

    # Default svm
    clf = svm.SVC()   

    clf.fit(R_train, r_train)

    r_pred = clf.predict(R_test)

    target_names = ['Female', 'Male']
    print "SVM Accuracy:", accuracy_score(r_test, r_pred)
    print "Classification report:\n", classification_report(r_test, r_pred, target_names=target_names) 




if __name__ == '__main__':
    main()

对于如何使用 SVM 进行良好的性别识别,我将不胜感激。感谢阅读

好的,现在使用标准化数据(介于 0 和 1 之间)我尝试使用 GridSearchCV 来调整 C 和 Gamma 使用:

    param_grid = [
  {'C': [1, 10, 100, 1000], 'kernel': ['linear']},
  {'C': [1, 10, 100, 1000], 'gamma': [0.001, 0.0001], 'kernel': ['rbf']},
 ]
svr = svm.SVC()
clf = grid_search.GridSearchCV(svr, param_grid)

过了一会儿我得到了这个结果:

{'n_jobs': 1, 'verbose': 0, 'estimator__gamma': 0.0, 'estimator__probability': False, 'param_grid': [{'kernel': ['linear'], 'C': [1, 10, 100, 1000]}, {'kernel': ['rbf'], 'C': [1, 10, 100, 1000], 'gamma': [0.001, 0.0001]}], 'cv': None, 'scoring': None, 'estimator__cache_size': 200, 'estimator__verbose': False, 'pre_dispatch': '2*n_jobs', 'estimator__kernel': 'rbf', 'fit_params': {}, 'estimator__max_iter': -1, 'refit': True, 'iid': True, 'estimator__shrinking': True, 'score_func': None, 'estimator__degree': 3, 'estimator__class_weight': None, 'loss_func': None, 'estimator__random_state': None, 'estimator': SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0, degree=3, gamma=0.0,
  kernel='rbf', max_iter=-1, probability=False, random_state=None,
  shrinking=True, tol=0.001, verbose=False), 'estimator__coef0': 0.0, 'error_score': 'raise', 'estimator__tol': 0.001, 'estimator__C': 1.0}

SVM Accuracy: 0.767326732673
Classification report:
             precision    recall  f1-score   support

    Females       0.76      0.77      0.76       294
    Males         0.78      0.77      0.77       312

avg / total       0.77      0.77      0.77       606

我不知道这是否是正确的使用方法,以及给出这个结果的参数 C 和 gamma 是什么,但是分类器已经改进了,有人可以告诉我我是否做得很好以及结果意味着什么或我怎样才能做到这一点?谢谢

【问题讨论】:

  • 既然您要求更适合此任务的库:任何支持卷积网络和 GPU 支持的可靠深度神经网络库(假设您有一个不错的 GPU)都应该可以正常工作。看看 Caffe、Torch7、keras ......(如果你愿意,最后一个是 Python 的)。所有这些都有训练用于图像分类的深度网络(通常是 ImageNet 或 CIFAR-10)的示例。
  • 谢谢,那么我将使用 keras,所以继续使用 python ,我目前正在使用带有 Iris 1536 MB Intel GPU 的 MacbookPro,够了吗?本周我将使用 SVM 更改一些参数,然后尝试“keras”。非常感谢@cfh
  • 也可以看看千层面。
  • 顺便说一句,您应该对 gamma 和 C 进行网格搜索并重新调整您的功能。如果它们是 0 到 255 之间的灰度,我建议除以 255.0(确保获得实际的浮点数)。
  • 注意到@AndreasMueller :)

标签: python


【解决方案1】:

您似乎正在将每个图像的像素转换为数字数组,并且只是希望 SVM 能够以某种方式区分女性像素序列和男性像素序列。

这种分类的“黑魔法”方法不太可能成功。对图像进行某种实际分析似乎是一种更有前途的方法——也许尝试量化面部特征,甚至只是颜色或边缘的数量。但这不是一个简单的爱好项目,您可以在一个周末使用简单的现成工具成功地大致了解最新技术

【讨论】:

  • 深度卷积网络实际上以这种“黑匣子”方式(或你所说的黑魔法)工作,因此可以原谅 OP 尝试这样做。
  • 此外,借助免费提供的库,这是一个简单的爱好项目,如果您拥有强大的 GPU,则可以在周末轻松完成。
  • @cfh 对,但是这里没有神经网络,只是将特定坐标处的像素灰度作为“特征”。如果 (177, 413) 特别暗,你会期待“男性”吗?当然你不知道,添加更多像素并不能真正改变这一点。
  • @cfh:对于设计它们的科学家来说,深层网络并不是黑匣子。一个实际的实现是黑盒子,因为神经网络不能证明他们的选择是正确的,但是当你研究它时,理论机制得到了很好的解释并且完全合理。在这种情况下,我不认为神经网络会增强结果,因为当你不知道它是如何工作的时它们很难正常工作(即使你知道,它仍然很难)。 OP 应该尝试将数据投影到另一个表示上,例如使用 PCA 或随机森林,以便分类器在非线性空间上工作。
  • 77% 使用最少的工作似乎与“黑匣子不起作用”相矛盾,尽管我同意仅使用 sklearn-theano 可以通过类似的多行代码和预训练的神经网络。
【解决方案2】:

桌子

SVM Accuracy: 0.540041067762
Classification report:
           precision   recall  f1-score   support
Females       0.52      1.00      0.68       242
Males         1.00      0.09      0.16       245

清楚地表明您的分类器将几乎所有示例都识别为女性。这是为什么? 100% 召回意味着所有女性样本都被正确识别为女性,而男性样本的 100% 准确率意味着您的分类器认为男性的每个样本确实是男性。另一方面,女性人群的 50% 准确率意味着平均而言,您归类为女性的样本中只有一半是真正的女性,而另一半是男性。

如果您仔细考虑一下,只能得出一个结论:您的分类器为(几乎)显示的任何内容预测一个“女性”标签。现在你必须找出发生这种情况的原因。

【讨论】:

  • 好的,谢谢@cfh,我会尝试不同的裁剪、不同的尺寸,也许还可以使用 EqualizeHist 图片,'clf = svm.SVC()' 的参数可以改变什么吗?
  • 一个问题@cfh ,表示“支持”列,因为训练数据的数量也是487(242 + 245),以及我如何知道支持向量的数量在我创建的 SVM 模型?谢谢
猜你喜欢
  • 2012-07-26
  • 1970-01-01
  • 2013-06-21
  • 2015-12-12
  • 2010-09-06
  • 2010-12-04
  • 2019-07-29
  • 2020-04-16
  • 2012-07-26
相关资源
最近更新 更多