Create MLで自動車部品の不良品検知

#Create MLで100%検知
目視できるレベルの金属部品の表面異常検知であれば、 **Create MLで十分な高精度を達成できます。**

Pythonに潜って専用モデルを探したり、カスタムモデルをつくる必要はありません。

**我々が自動車部品メーカーとの技術研究で100%の検知結果を出した**Create MLでの画像分類タスクの取り組みについて紹介します。

###Create MLは表面異常検知の現場で使えるのか

自動車に用いられている4cm程度の細長い部品の表面異常検知をおこないました。
**傷の大きさは1〜4mm程度。**
![良品.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/07d51e2b-1188-a655-031b-f52433af1686.png)　![不良品.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/bc475fd4-0ec6-397f-19da-c8bcfeae64d5.png)
*（左）良品　／　（右）不良品（中央に斜めに走っている四角い影が「圧痕」という傷）*

実際に出荷されている部品であるため、部品サンプルはたくさんは望めず。
良品30本、不良品30本のデータでの実験となります。

この分野では90%の分類精度であっても不十分です。
大量の再検査コストがかかり、自動化の意味がなくなってしまうのです。
**現場では99%の検知能力が求められます。**


Create MLの画像認識モデルは、（模様のようなものではなく）物体の種類分類データセットによって事前学習されているため、細かい模様のような傷には適用できないのではないかと当初は考えました。

そのため当初は、Pythonの画像分類ネットワークを初期値からトレーニングするか、抽象度の高い事前学習層だけを用いて転移学習させる必要があると覚悟しました。
それでもダメなら、金属表面専用の最新研究を用いる。

ただ、とりあえず試す意味でCreate MLにかけてみると、わりあい**あっけなく精度100%を達成しました。**
<img width="512" alt="スクリーンショット 2020-08-06 1.32.21.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/029598c0-9343-df66-4dbf-950a5a8b261e.png">

###金属表面を分類する際のコツ
重要なのは、データセットを可能な限り（傷以外の）**ばらつきのない画像にすること**です。
モデルに傷の有無だけに集中してもらうイメージで取り組みました。

#####1、フォーカスする領域にクロップする
部品全体の画像を一気にモデルにかけてしまうと、ランダムに近い結果しか得られませんでした。
幸い、今回の部品は傷のつく場所が部品の一部分に集中していたので、その部分だけをクロップして使用しました。
複数箇所に傷がある場合は、一定の形状や角度ごとに部品の部分を区別して、各々でモデルを作成した方が高精度が望めます。

#####2、撮像環境を一定にする
金属表面が光の反射があるので、どうしても部分による明暗が出てしまいます。
撮像環境をできる限り一定にすることで、反射のばらつきは無視して傷のみを学習できます。
**その程度の能力はCreate MLにはあります。**
一般住宅内のLED照明の下で、**カメラと部品を一定の位置に固定して撮影すること**で、上記の精度を達成できました。
もちろん、傷が濃く映るような明るさが理想です。ただそのために特別な証明は必要ないということです。

#####３、データ拡張を慎重に行う。
データ拡張なしでCreate MLでトレーニングしたところ、Training正解率は100%、Validation（検証）正解率は70％程度でした。
**トレーニング正解率と検証正解率が乖離するのは過学習のサインです。**
一般に、**過学習はデータセットが十分ではない時に起こります。**
十分なデータを得ることが難しい場合は、データ拡張を用いてデータセットを水増しします。
ただし、**やみくもにデータ拡張をすればいいというものでもありません。**
Create MLには
Add Noise、Blur、Crop、Flip、Rotate
というデータ拡張オプションがありますが、今回は、たとえばrotateを適用して画像をランダムな角度で回転させてデータを水増ししたところ、**むしろ正解率が下がりました。**
**Flipだけを用いたところ、正解率100%を達成できました。**

画像の性質上、画像のz軸で回転させると、本来は一方向であった光の反射や影や金属の表面の筋がバラバラの向きになってしまい、ノイズとして無視したいものを画像の特徴として捉えてしまうのだと思います。

####現場への導入に必要なこと
#####１、部品表面全体を画像認識する必要があります
部品を回転させながら撮像します。
２つ方法があります。
・時系列で回転させた表面を一枚の画像としてまとめる方法。
・回転させながら動画を撮って毎フレーム解析する方法です。
Create MLの軽量モデルならエッジデバイスでも毎フレーム解析が可能なので、後者がとっつきやすいように思います。
#####２、不良品を排除する機器に信号を送る必要があります
BlueToothなどの形で通信する必要があります。
#####３、過検出を防ぐ
現場で発生する埃や繊維、白粉といった「不良品ではないが表面異常としてうつるノイズ」を無視する必要があります。
これらのノイズが原因で「不良品」として認識してしまうと、良品が大量に弾かれてしまい、結局再検査の人員コストがかかります。
**過検出を防ぐには、CIFilter等を用いて情報をエッジのみにするなどして、ノイズを目立たないように、傷が目立つように画像を前処理することが有効です。**
WWDC 2020のセッション Explore Computer Vision APIs　が参考になります。
<img width="128" alt="スクリーンショット 2020-08-06 1.59.18.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/99e40b31-08b0-9b44-e859-721cfbb49059.png">
*（写真）フィルターで情報量を削った金属表面*

#結論
**目視できるレベルの不良品検出であれば、Create MLで十分に対応できます。**
少なくとも、Pythonモデルで試行錯誤する前に、手軽に試してみてる価値はあります。。

<img width="128" alt="スクリーンショット 2020-08-06 8.25.52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/cca5915d-8d2a-2f95-07fd-24a33638f161.png">
機械学習関連の情報を発信しています。
MLBoysだいすけ　https://twitter.com/JackdeS11
MLBoysゆうじ https://twitter.com/oka_yuuji

Core MLやCreate ML、Visionを使ったアプリを作っています。
mlboys.d.yu@gmail.com