ユニクロコン 手法編

オプトのユニクロコンペ(https://deepanalytics.jp/compe/36?tab=comperank)に出ていました。
public 4th -> private 4thという結果で、運次第では賞金圏内もあったと思うので切ないですね。

0. 概要

基本データ

  • ユニクロの商品の色(24クラス)を判別する課題
  • Train:12399, Test:9801
  • 背景はちゃんと切り抜いてくれているので、わざわざwatershedなどで背景抽出をする必要が無い

課題

  • 色の判別はやや単純すぎる課題で、本来はCNNを使うのはオーバーキルな感じもある。 ただ、後述のラベリングの微妙さも相まってコンペとしてはある意味おもしろい。
  • ラベリングが微妙。もはやどっちが正しいのかわからないの多数。特に3連靴下はなんだこれ。
  • 分析すると、女性物は同じような色でもオフホワイトになりやすかったり、ラベリングは服の種類に影響を受けていることがわかる
  • このコンペは色を判別するコンペではなく、人間がどのように色コードを設定するかを判別するコンペといえる。
  • train/testはrandom splitではなく、商品ラインごとのsplitをしている様子。 なので、やりすぎるとtrainデータへのoverfitの危険もある

評価指標

  • balanced accuracyであることがポイント。比率の少ないものを間違えるとペナルティが大きい。 完全に正しい確率を予測できているとするならば、確率÷正解ラベルの比率が最大となるものを予測するのが適切。
  • trainingデータのweightを変える方法も試したが、通常のweightで分類し上記の調整を行う方が精度が高かった。
  • balanced accuracyは安定しない、accuracyが良くても2番手以降の評価がいまいちだとスコアが出ないので、loglossを下げることに注力。

1. 特徴量抽出、分析

クラスタリングを少し試したが、結局モデリングには適用していない。

  • シルエットによるクラスタリング
    背景領域を0, それ以外を1としてベクトル化し、kmeansクラスタリング。 画像が整えられているので、単純だが結構きれいに商品カテゴリごとに分けられる。

  • 分析、ヴィジュアライゼーション
    カテゴリ間の距離が最小になるように並べる(巡回サラリーマン問題を解く)と、近いカテゴリが近くなるので見やすい。 カテゴリごとに画像を並べたPDFを作ったり、カテゴリごとの色の分布・正答率を見たりした。

  • 接続領域での分離
    繋がっている領域が何個あるかを求める(DFS)。3連靴下とかを綺麗にわけることができる。

  • その他
    SIFT、カラーヒストグラム、pretrained modelで予測したimagenetのカテゴリとか考えたが、結局使っていない。

2-1. モデリング

  • ニューラルネットのライブラリはkeras
  • ファインチューニングとスクラッチからのCNNの両方を行った。
  • テストデータには、5cvの平均を適用するようにした。 ニューラルネットだと、trainの全データを使うとvalidation scoreが見れないので怖い。
  • パラメータ調整はhyperopt。ネットワーク構成、learning rate、optimizerの選択に大変役に立った。
  • 単発だとかなりぶれるので、10-20回回した平均をとった。
  • オプティマイザは、ファインチューニングはmomentum sgdで良さそうですが、スクラッチではadamが有効だった。
  • クラッチから作る場合は、序盤に1*1フィルタを適用するモデルの精度が良かった。
  • 1epochで10000枚回すとearly stoppingの際に行き過ぎてしまうので、generatorを使うことで1 epochの枚数を制御した。
  • data augmentation, test-time augmentationを行った。 左右反転・少し回転・少し拡大縮小させた。 kerasのImageGeneratorは専用実装になっており、取り入れにくかったので、適宜コードをつぎはぎした。

2-2. 作成したモデル

ファインチューニング

  • vgg16
  • vgg16, augmentationあり
  • resnet
  • resnet, augmentationあり

クラッチからのCNN

  • cnn1-5 : 序盤に1*1フィルタを適用したCNN(5種類)、augmentationあり
  • cnn0 : 1*1フィルタのみでピクセルの場所の情報を全く使用しないCNN

ネットワーク構造は以下のような感じ。怪しい。
Conv2d(filter=1 * 1) -> Conv2d(filter=1 * 1,stride=2) -> BN -> Maxpooling(2 * 2) ->
Conv2d(filter=2 * 2) -> Conv2d(filter=2 * 2,stride=2) -> BN -> MaxPooling(2 * 2) ->
Dense -> BN -> Prediction

各モデルのローカルのスコア(10-20個混ぜている)は以下のとおり。

model logloss balanced acc accuracy
vgg16 0.6876 0.7004 0.7695
vgg16_aug 0.6969 0.6910 0.7685
resnet 0.6687 0.6975 0.7747
resnet_aug 0.6462 0.7005 0.7809
cnn1-5 0.6548-0.6743 0.6993-0.7116 0.7672-0.7732
cnn0 0.7396 0.6624 0.7443

3. Ensemble、調整

  • 各モデルの加重平均をとる。 加重平均を取る際には、loglossが最小になるような係数を探し、適用する。
  • スタッキングを行う。クラスが多いためか、スタッキングをしたモデル自体の精度はあまり良くない。 スタッキングをしたモデルとの加重平均をとることで少し精度が上がる。
  • 最後の仕上げでloglossが最小になるように確率をn乗したり、色の比率のn乗を乗じた。 この辺はいろいろやり方がありそう。

各モデルのローカルのスコアは以下のとおり。

model logloss balanced acc accuracy
加重平均 0.6154 0.7199 0.7880
スタッキング 0.6311 0.7154 0.7815
上2つの加重平均 0.6120 0.7213 0.7882
調整後 0.6069 0.7217 0.7874