【三菱電機】の特許技術を「推理」する

先日、驚くべきニュースが飛び込んできました。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">教師データ不要でAIが工場での作業者の手順の違いや無駄な動作を検出 <a href="https://t.co/rKYmyzqNxn">https://t.co/rKYmyzqNxn</a> <a href="https://t.co/8DlgZRro05">pic.twitter.com/8DlgZRro05</a></p>&mdash; MarvinNewsJP (@MarvinNewsJP) <a href="https://twitter.com/MarvinNewsJP/status/1097360275236257792?ref_src=twsrc%5Etfw">2019年2月18日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


これは正に自分がやろうとしていたことで、「先を越された！」という
のが正直なところです。自分でも、実験的に[こんなこと](https://qiita.com/shinmura0/items/1fbfe4dc5f719d54ebbe)をしていました。

三菱電機では、**特許出願中**とのことで、特許公開がいつになるのか
分かりませんが、ここでは、その技術を「推理」してみようと思います。

![ダウンロード (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264781/884a5e33-b952-2b06-cc6c-51b6e28d37c1.png)


# 特許技術の凄いところ
＜この技術の概要＞

+ 作業者の手に色付きのバンドを付けて、ステレオカメラでその座標を取得する。
+ その座標から、組立作業などの異常検知が可能となる。
+ さらに、異常検知だけではなく、作業効率向上のアドバイスもくれる。

＜この技術の凄いところ＞

+ 「教師なし学習」であるため、面倒なラベル付けの作業が不要。
+ 作業と作業の継ぎ目を指定する必要はない。

**凄すぎて言葉が出ません。**

というのも、自分がやろうとしていたことは「教師あり学習」で
かつ、作業の継ぎ目が存在しない「単一の作業」を題材にする予定でした。

ちなみに、畳み込みニューラルネットワークを使った作業工程の分類を
やっている論文もあるので、興味ある方はご覧ください。
https://www.mdpi.com/2227-9709/5/2/26

#結論から

結論からいうと、ベイズ最適化を使えば、**教師なし学習で異常検知**はできそうです。
しかも、作業の継ぎ目を指定する必要はありません。

ただ、アドバイスの提示はどういうアルゴリズムなのか、実際に見てみないと
推理することは難しいです。

#問題設定
三菱電機の資料によると、手の座標を監視することで異常検知しています。

今回は、簡易的に右手のx座標（1次元の波形）があったとして、それを
監視することで異常検知します。

以下に「学習データ」、1工程だけの時間が長い「正常データ」、
工程が一つ多い「異常データ」を示します。

![ダウンロード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264781/eb4f1376-90f9-6663-f32f-2a9bb042853e.png)

これだけだと、何が異常が分からないので、意味ある形で4分割してみます。

![ダウンロード (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264781/6ba7107e-a301-080f-ea60-2359cdc80bda.png)

色別で比較すると、分かりやすくなります。
明らかに、青で囲った部分が異常です。

#異常検知手法
時系列データの異常検知は、[K近傍法を使う手法や特異スペクトル変換法](https://blog.brains-tech.co.jp/entry/2017/10/17/170140)等、
色々ありますが、今回の異常検知は波形に切れ目を入れ、分割する手法を使います。

分割する理由として、各工程では作業者によって作業時間にばらつきが生じるため、
各工程で波形が伸縮します。従って、切れ目を入れ各工程に分割し、そこで伸縮を
考慮した異常検知が必要になってきます。

具体的に、さきほどの図で説明します。

![ダウンロード (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264781/6ba7107e-a301-080f-ea60-2359cdc80bda.png)

正常データの赤の部分は、学習データの赤と比べて長くなっていますが、
問題なく作業が行われているように思えます。

一方、異常データの青の部分は、明らかに余計な工程が入っており、
異常と認識してほしいところです。

上図のようにうまく分割できれば、波形を伸縮させ同じ長さにした上で
異常度を計算すれば異常検知できそうです。

![ダウンロード (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264781/5d646345-8bd9-baf9-f657-330a11745908.png)


波形の類似度を見る場合、[DTW](http://ksknw.hatenablog.com/entry/2017/03/26/234048)が良く用いられますが、今回は
コサイン類似度を使います。

そして、OpenCVの機能で波形を同じ長さにして、異常度を計算します。

```py
import cv2
import numpy as np

def cos_sim(train, test):
    test = cv2.resize(test, (1,len(train)))
    return np.dot(train, test) / (np.linalg.norm(train) * np.linalg.norm(test))
```

#ベイズ最適化
ここまでは、三菱電機の資料を見れば何となく推理できます。
問題は、「どうやって切れ目を入れるのか？」ということです。

畳み込みニューラルネットワークを使えれば良いなぁと思ったのですが、
私の脳みそでは力不足でした。代わりにベイズ最適化を使います

ベイズ最適化は[こちら](https://qiita.com/shinmura0/items/2b54ab0117727ce007fd)を見ていただければ、イメージは分かるかと思います。

ベイズ最適化とは、ある関数でパラメータがあったとして、パラメータをいじると
出力が変化するとします。そして、出力が最小（もしくは最大）になるように
パラメータを良い感じに探してくれるものです。

![movie (2).gif](https://qiita-image-store.s3.amazonaws.com/0/264781/2631fa00-8ae9-51e0-52ed-124bb9a59438.gif)

上の動画はパラメータ（x）に対し、yの出力値が最小(y=0)となる点を探す様子です。
青い点は事前に与えられた情報、赤い点は実際に探索した点を示しています。
わずか5回探索するだけで、最小値を見つけることができました。

今回の問題では、切れ目を入れる場所をベイズ最適化で見つけます。
そして、コサイン類似度で分割した波形同士を比較し、その類似度の
平均値が高くなるように分割する位置を探索します。

#実験

コード全体は[github](https://github.com/shinmura0/BayesAssemble/blob/master/bayes_assemble.ipynb)に置きました。
Colaboratoryで実行可能です。

さきほどのデータを使ってベイズ最適化で切れ目を探索させました。
そして、コサイン類似度で計算した結果を以下に示します。

![ダウンロード (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264781/884a5e33-b952-2b06-cc6c-51b6e28d37c1.png)

正常データでは、コサイン類似度が0.98以上となり正常と認識することができました。
一方、異常データでは異常部分のコサイン類似度が0.35と低くなっており、異常を
検出することができそうです。

#最後に
今回の推理は当たっていれば、そして、三菱電機の特許が認可されれば
特許でカバーされてしまうため、無断で使うことはできません。

しかし、外れていれば、本稿で紹介した内容は特許を気にすることなく
使える可能性があります。今後も特許に注目していきたいと思います。

次回は[handtracking](https://qiita.com/shinmura0/items/07d976fc13ce774036b8)を使って、実際に本技術を使ってみます。