基于sklearn SVM的人脸识别项目两类核心问题求助
人脸识别项目问题解答
问题1:多样本类别导致识别偏差
原因
你的SVM分类器默认基于平衡数据集训练,当某一类别(如A)的样本数量多于其他类别时,模型会倾向于预测样本数更多的类别——训练时模型会优先减少整体错误,样本多的类别隐性权重更高,最终导致其他类别甚至无关人脸都被误判为该类别。
解决方案
使用SVM的class_weight参数自动平衡类别权重,给样本数量少的类别分配更高权重,抵消样本不平衡的影响。
修改代码中SVM初始化的行:
# 原代码 clf = svm.SVC(gamma="scale") # 修改后 clf = svm.SVC(gamma="scale", class_weight='balanced')
class_weight='balanced'会根据每个类别的样本数自动计算权重,公式为n_samples / (n_classes * np.bincount(y)),样本越少的类别权重越高,让模型对每个类别的错误惩罚更公平。
问题2:无法识别未知人脸
原因
默认的SVM是硬分类器,无论输入是否属于训练过的类别,都会强制输出一个已知类别,不会返回"未知"结果。
解决方案
让SVM支持概率输出,通过预测概率的阈值判断是否为未知人脸:
- 初始化SVM时开启
probability=True,让模型能输出每个类别的预测概率; - 预测时获取最大概率值,若低于设定阈值(如0.7),则判定为"未知"。
修改代码中的两处:
1. SVM初始化
clf = svm.SVC(gamma="scale", class_weight='balanced', probability=True)
2. 人脸预测逻辑
# 原预测代码 name = clf.predict([encoding]) print(name) face_names.extend(name) # 修改后 pred_probs = clf.predict_proba([encoding]) max_prob = pred_probs.max() # 阈值可根据实际识别效果调整 if max_prob >= 0.7: name = clf.predict([encoding]) else: name = ["Unknown"] face_names.extend(name)
predict_proba会返回每个类别的预测概率,最大值代表模型对当前预测的置信度,低于阈值说明模型对该人脸的匹配度不足,直接标记为"Unknown"。
内容的提问来源于stack exchange,提问作者Arafat Khan
相关产品推荐
相关产品推荐

