顔の画像に基づいて性別を分類する小さなプログラムを作成しました。私はYale の顔データベース(男性用の 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
これは私にとってさらに奇妙に思えます。
だから私の質問は:
- 私のアプローチやコードに間違いはありますか?
- そうでない場合、線形カーネルの結果が非常に良く、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