ゼロから始める機械学習

機械学習についての個人メモ

画像データの切り抜きをCNNとopenCVで自動化する

概要

画像分類では認識したい対象だけのクリーンな画像が欲しいですが、提供データには不要なオブジェクトが多く写ります。また、分類対象が小さくしか写っていないこともあります。
大量の画像データを手動で切り抜くには時間がかかるので、必要部分のみ切り抜く処理をCNNとopenCVで教師データありで自動化します。

目的

Kaggleのintel子宮頚部癌スクリーニングコンペに参加し、22位でした。
Intel & MobileODT Cervical Cancer Screening | Kaggle

f:id:fujisanx:20170703205728p:plain

このコンペでは4000pxを超える高解像度のデータが8000枚ほど提供されました。
画像は専用の医療機器で撮ったものからデジカメで撮ったようなものまで、対象の形状や色も違い、医療器具の映り込みもありました。
CNNでの画像分類はメモリの制約上、224pxや299pxなど縮小したものを利用します。
認識したい箇所が小さい画像はそのまま縮小すると特徴が失われてしまうので、高解像度の画像から認識したい箇所を切り抜き特徴を残したいところです。
※最初にそのまま縮小した画像で、転移学習のResNet50で分類した時は良いスコアは得れませんでした。

検討した他の手法

Kaggleカーネルでは、教師なしでセグメンテーションをする方法が紹介されていましたが、実際に適応するとあまり満足する結果ではありませんでした。
以下のカーネルで確認できますが、必要でない医療器具が残ったり、必要な皮膚部分が除去される場合があります。

http://ggle.com/chattob/cervix-segmentation-gmm

その他scikit-imageにある教師なしセグメンテーションで閾値分割や前景の検出など

http://scikit-image.org/docs/dev/auto_examples/

満足な結果が出なかったので教師なしでのセグメンテーションを諦め、教師ありで切り抜くことにしました。

CNNによるセグメンテーション既存手法

既にRCNNやSSDなどの複数オブジェクト検出、FCNによるピクセル単位でセグメンテーションするネットワークが考案されています。
今回は医療画像の為、流用できる教師データはなさそうでした。
手動で教師データを作成する場合、時間のかかるピクセル単位の教師データ作成は時間がかかるので、切り抜きたい座標を得れる単純なもので対応したいところです。

また、kaggle公式ブログの過去コンペでも既に使われている手法だったので、教師データ作成に時間をかける価値はありそうでした。 blog.kaggle.com

ResNetを利用した単一オブジェクトの切り抜き領域の推測

切り抜きたい対象は画像につき1つで、領域はCNNに必要な正方形で十分です。
今回はシンプルにResNetで特徴を抽出して始点のx,yとlengthを推測することにしました。

一度縮小した画像でx,y,lengthを求め、元画像と縮小画像の比率に応じてopenCVで切り抜けば完了です。

結果

まず200件の教師データを手動で作成し、残りのデータに推論をかけてチェックしながらズレを手修正、チェック済みのデータで再学習の繰り返しで対応しました。
初期の200件の学習でもそれなりの結果が得れ、1割程度の手修正。1000枚の学習以降は2000枚チェックしても殆ど修正はしませんでした。

このことから以下の条件を満たす場合にはある程度有効となりそうです。

  • 教師なしの手法で切り抜きができない
  • 流用できるセグメンテーションデータがない
  • 切り抜き対象が画像内に必ず一つ
  • ピクセル単位のセグメンテーションデータの作成は面倒で、座標指定の作業ならまだ許せる場合

最終的に3000枚の教師データの切り抜き精度で十分だったので画像を処理し、複数のCNNのアンサンブルで22位を取得できました。