我根据 image of a face 为 gender classification 制作了一个小程序 . 我使用Yale face databse(男性为175张图像,女性为相同数字),将它们转换为灰度和均衡直方图,因此在预处理后图像如下所示:
我运行以下代码来测试结果(它使用SVM和 linear 内核):
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% precision !
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
这对我来说似乎更奇怪 .
So my questions are:
-
我的方法或代码有什么错误吗?
-
如果没有,线性内核的结果怎么这么好,而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
2 回答
朋友从我的理解你对你的问题的描述,我认为解释很简单,由于线性内核的问题比RBF更好,相信你的逻辑是正确的但是你应该使用RBF有些错误我认为它会服务对你的问题,继续尝试开发一种只使用线性内核的方法
所有描述的模型都需要调整参数:
线性SVM:C
RBF SVM:C,gamma
DBN:图层计数,神经元计数,输出分类器,训练率...
而你只是 omitted 这个元素 . 所以很自然,具有最少可调参数的模型表现得更好 - 因为简单地说默认参数实际工作的概率更大 .
100%得分总是看起来很可疑,你应该“手动”仔细检查 - 将数据分成火车和测试(放入不同的目录),一部分训练,将模型保存到文件中 . 然后在单独的代码中 - 加载模型,并在测试文件上测试它,并在模型中显示图像标签 . 这样你就可以确保没有implmenentation错误(因为你真的不在乎是否有任何处理错误,如果你有一个物理证明你的模型识别那些面,对吧?) . 这纯粹是“心理学方法”,这使得数据分割/共享和进一步评估中没有错误显而易见 .
UPDATE
正如评论中所建议的那样,我还检查了您的数据集,并且正如官方网站上所述:
所以这肯定是一个问题 - 这是 not the dataset for the gender recognition . 您的分类器只记忆这28个科目,这些科目很容易分为男/女 . 它根本不适用于其他主题的任何图像 . 这个数据集中唯一的"valuable"部分是28个独特个体的面部集合,您可以手动提取,但28个图像似乎至少有一个数量级太小而无法使用 .