HOG+SVMはCNNに勝てる?FashionMNIST 60,000枚で精度・速度・誤りを比較

実験日: 2026-08-24
CPU: Core i7-14700F / GPU: RTX 5070 Ti / WSL2

画像分類と聞くと、最初からCNNやVision Transformerを選びたくなるかもしれません。しかし小さな画像と限られた学習予算では、人が設計した特徴量と古典機械学習が強い場合があります。

HOGは地味な手法に見えますが、今回の条件ではCNNより高い精度になりました。

FashionMNISTの学習60,000枚・テスト10,000枚を使い、HOG特徴量+Linear SVMと、105,866パラメータのCNNを比較しました。

HOG+SVMは88.85%、3 epoch CNNは87.00%でした。古典手法が1.85ポイント上です。一方、HOG抽出とSVM fitには合計約66.2秒かかり、CNNのGPU学習は約3.59秒でした。「どちらが勝ちか」は精度だけでは決まりません。

古典手法が1.85ポイント勝った

HOG + Linear SVM

  • test accuracy:88.85%
  • HOG:1画像1,296次元
  • 学習画像HOG抽出:13.73秒
  • LinearSVC fit:50.45秒
  • test HOG抽出:2.22秒
  • SVM predictのみ:0.028秒
  • end-to-end test処理:約2.25秒

CNN(3 epoch)

  • test accuracy:87.00%
  • 105,866パラメータ
  • GPU学習:3.59秒
  • test inference:0.142秒

10,000テスト画像の関係

  • 両方正解:8,293枚
  • SVMだけ正解:592枚
  • CNNだけ正解:407枚
  • 両方誤り:708枚
  • 予測label一致率:88.29%
FashionMNISTの元画像とHOG可視化、HOG+Linear SVMとCNNの全体・クラス別精度比較
FashionMNISTの元画像とHOG可視化、HOG+Linear SVMとCNNの全体・クラス別精度比較

HOGは画像の何を特徴量にするのか

HOGはHistogram of Oriented Gradients、つまり「勾配方向のhistogram」です。画素の明るさそのものより、局所的なedgeがどの方向を向いているかを表します。

まず横・縦方向の差分からgradientを求めます。

gx = 横方向の明るさ変化
gy = 縦方向の明るさ変化

magnitude = sqrt(gx² + gy²)
angle     = atan2(gy, gx)

gradientが大きい場所はedgeです。衣服の袖、胴体、靴底、bagの輪郭などが反応します。

次に画像を小さなcellへ分け、cell内のgradient方向をhistogramへ投票します。今回の設定です。

features = hog(
    image,
    orientations=9,
    pixels_per_cell=(4, 4),
    cells_per_block=(2, 2),
    block_norm="L2-Hys",
)

scikit-image公式のHistogram of Oriented Gradientsでは、gradient計算、cell内の方向histogram、block正規化、feature vector化という流れが解説されています。

なぜ1,296次元になるのか

28×28画像を4×4 pixelのcellへ分けると、縦横7 cellです。

2×2 cellを1 blockにし、1 cellずつずらすので、block位置は縦横6個あります。

1 blockには次の値があります。

2 × 2 cells × 9 orientations = 36 values

全体では次の通りです。

6 × 6 blocks × 36 values = 1,296 dimensions

元画像は28×28=784画素なので、HOGは次元削減ではなく1,296次元へ増やしています。同じcellが複数blockで正規化されるため重複がありますが、局所的なcontrast変化へ強くなる利点があります。

学習60,000枚をfloat32で保持すると、HOG行列だけで約296.6 MiBです。特徴抽出は計算時間だけでなくRAMも使います。

Linear SVMは1,296次元空間に境界を引く

HOGを抽出した後、LinearSVCへ入力しました。

svm = LinearSVC(
    C=1.0,
    dual="auto",
    max_iter=5000,
    random_state=42,
)

svm.fit(hog_train, y_train)
prediction = svm.predict(hog_test)

classごとに概念的には次のscoreを計算します。

score_k(x) = w_k · x + b_k

HOG vector xとweight w_kの内積が大きいclassを選びます。境界はfeature空間でlinearです。

今回使ったのはRBF kernelのSVCではなくLinearSVCです。60,000 sampleに対して計算量を現実的にし、HOG表現がlinear boundaryでどこまで分類できるかを見ています。

CNNは特徴量そのものを学習する

CNNへは0~1へ変換した画素をそのまま入力しました。

1×28×28
  → Conv 1→16 → ReLU → MaxPool
  → Conv 16→32 → ReLU → MaxPool
  → Linear 1568→64 → ReLU
  → Linear 64→10

HOGのcell sizeや方向binは人が決めます。CNNではconvolution kernelのweightを誤差逆伝播で更新し、分類に役立つedgeやtexture、部品の組み合わせをdataから学びます。

ただし今回のCNNは小さく、3 epoch、data augmentationなしです。HOG+SVMより精度が低かったことは「CNNの上限が87%」という意味ではありません。比較しているのは、この具体的な学習budgetのbaselineです。

実験条件を揃えた部分と揃わない部分

共通条件です。

  • FashionMNIST公式train 60,000 / test 10,000
  • 同じlabelと画像
  • test setでmodel選択をしない
  • 全体精度、class別精度、confusion matrixを保存

HOG+SVM条件です。

  • CPUでHOG抽出
  • 1,296次元float32
  • LinearSVC C=1
  • feature extraction、fit、predictを別計時

CNN条件です。

  • RTX 5070 Tiで学習
  • batch 256、Adam、learning rate 0.001
  • 3 epoch
  • DataLoader workers=4、pin memory
  • GPU/library warm-upを時間外に実施
  • warm-upでweightを変えた後、初期modelを再生成してから本学習

CPU SVMとGPU CNNの時間は、algorithmだけでなくhardwareも違います。精度と、このPCで実際に待つ時間の両方を示す比較です。

古典手法が1.85ポイント上だった

HOG+Linear SVMは8,885/10,000正解、CNNは8,700/10,000正解でした。

FashionMNISTは背景がほぼ黒く、衣服が中央へ揃った28×28画像です。輪郭方向を固定gridで集計するHOGの仮定と相性がよいdataです。

一方、CNNは3 epochしか学習していません。小型modelでもepochを増やす、正規化する、augmentationを使う、architectureを調整する余地があります。

ここから言えるのは、「簡単な画像taskで古典baselineを省略してはいけない」ということです。HOG+SVMはdeep learning実験の妥当性を測る強いbaselineになります。

class別に見ると違いが大きい

class HOG+SVM CNN 差(SVM-CNN)
T-shirt/top 85.3% 89.4% -4.1 pt
Trouser 96.9% 97.3% -0.4 pt
Pullover 83.1% 84.5% -1.4 pt
Dress 87.7% 84.9% +2.8 pt
Coat 84.1% 73.5% +10.6 pt
Sandal 96.7% 95.5% +1.2 pt
Shirt 65.8% 58.8% +7.0 pt
Sneaker 95.5% 97.3% -1.8 pt
Bag 98.0% 95.5% +2.5 pt
Ankle boot 95.4% 93.3% +2.1 pt

最大差はCoatの10.6ポイントです。CNNはCoat 1,000枚のうちPulloverへ122、Shirtへ110誤分類しました。HOG+SVMではPulloverへ64、Shirtへ54です。

一方、T-shirt/topではCNNが4.1ポイント上です。HOGが常に優れた特徴ではなく、classごとに得意・苦手が違います。

Shirtは両方に難しい

両modelで最低精度はShirtでした。

  • HOG+SVM:65.8%
  • CNN:58.8%

HOG+SVMはShirtをT-shirtへ130、Pulloverへ82、Coatへ82誤分類しました。CNNはT-shirtへ211、Pulloverへ106、Coatへ70です。

28×28のgrayscaleでは、上半身衣類の局所edgeが似ています。全体accuracyだけではこの弱点を見落とします。実用systemなら「衣類10分類で89%」ではなく、重要classごとのrecallを確認すべきです。

速度はCNNが圧倒的だった

HOG+SVMの学習側costです。

train HOG extraction  13.73 s
LinearSVC fit          50.45 s
合計                   64.18 s

test側です。

test HOG extraction     2.22 s
SVM predict             0.028 s
合計                    約2.25 s

SVMの内積計算だけなら速いのですが、毎回HOGを作る必要があります。特徴抽出がinferenceの約99%を占めました。

CNNは3 epoch学習3.59秒、10,000枚推論0.142秒です。このPCではCNN推論がHOG+SVM end-to-endより約15.8倍速くなりました。

ただしCNNはGPUを使用し、SVM/HOGはCPUです。GPUなしの環境、少量data、モデル説明、実装依存を含めれば選択は変わります。

誤りの集合が同じではない

両modelが同じ予測labelを出した割合は88.29%でした。

SVMだけが正解した592枚と、CNNだけが正解した407枚があります。仮に「正解する方を必ず選ぶoracle」があれば、8,293+592+407=9,292枚、92.92%まで正解できます。

もちろん実際には正解labelを知らないのでoracleは作れません。しかし2 modelが異なる情報を使っている証拠であり、次の研究テーマになります。

  • decision scoreをcalibrationしてensembleする
  • CNN特徴をSVMへ入力する
  • HOGをCNN入力channelへ追加する
  • disagreement sampleを人が調べる
  • 両方が誤る708枚のannotationや画質を確認する

単純な多数決は2 modelではtieになるため、validation setで重みやmeta-classifierを学ぶ必要があります。test setで重みを調整してはいけません。

再現方法

cd /mnt/c/Users/user/Documents/Codex/2026-08-24/ko/work/ai_lab

/opt/ai-lab/venv/bin/python experiment_hog_svm_vs_cnn.py \
  --data-dir /opt/ai-lab/data \
  --output results/hog_svm_vs_cnn.json \
  --figure ../../outputs/hog-svm-vs-cnn.png

JSONにはHOG設定、1,296次元、各処理時間、class別精度、2つのconfusion matrix、正誤集合、予測一致率を保存しています。

比較実験で確認すること

  1. 同じtrain/test splitを使う
  2. feature extraction時間をfit時間から隠さない
  3. inferenceも前処理込みで測る
  4. GPU/CPUなどhardware差を明記する
  5. 全体accuracyだけでなくclass別metricを見る
  6. deep learningのepochとtuning budgetを明記する
  7. baselineが勝っても失敗扱いにしない
  8. test setをhyperparameter調整に使わない
  9. disagreement sampleを次の仮説へつなげる

まとめ

FashionMNISTでは、HOG+Linear SVMが88.85%で3 epoch CNNの87.00%を上回りました。背景が単純で中央揃えの小画像では、局所edge方向という手設計biasが強いbaselineになりました。

一方、HOG抽出+SVM fitは約64.2秒、CNN GPU学習は3.59秒でした。test前処理込みでもCNNが約15.8倍高速です。また両modelの正解集合は異なり、SVMだけ正解592枚、CNNだけ407枚でした。

古典MLとdeep learningは、単純な新旧の関係ではありません。精度、前処理、計算資源、class別誤り、運用速度を同じ表へ置いて比較することが重要です。次からはこのPCの16GB VRAMでローカルLLMを4B・8B・12Bと段階的に動かし、model sizeと生成速度・memoryを測ります。

関連記事