Coursera Machine Learning Week11 「Application Example: Photo OCR」

# はじめに
本記事は、[Coursera Machine Learning](https://www.coursera.org/learn/machine-learning)コースのWeek11「Application Example: Photo OCR」の内容のまとめです。

取り扱った内容は、以下でした。

- Photo OCRについて
- 学習データの人工的な作成方法について
- Ceiling Analysis（天井分析）について



# Photo OCRについて
## Photo OCRとは
Photo OCRとは、画像の中にあるテキストをコンピュータに認識させる技術です。
例えば、以下のような画像があった場合に、「おうちにかえりたい」という文字が含まれているということを認識させるような技術です。
![図7.png](https://qiita-image-store.s3.amazonaws.com/0/142563/76453909-8201-d01b-5b3c-2bd3b04f9fda.png)

Photo OCRによる文字列の認識は、3つのステップで行われます。
まず、画像の中のどこにテキストがあるかの検出、次に検出されたテキストを個々の文字に分割、そして個々の文字に対する文字認識というステップで処理を進めていきます。

![図2.png](https://qiita-image-store.s3.amazonaws.com/0/142563/9e16c4c4-aed7-69d3-59e3-8c7a3d79ef3b.png)

このように、複数の機械学習のコンポーネントを連結することで1つの大きな機能を実現するシステムのことを、パイプラインと呼んでいます。
Photo OCRパイプラインのそれぞれについて、簡単に見ていきます。

### テキスト検出
テキストの検出では、画像の中のどこに文字列があるかを検出し、文字列が含まれる領域を抽出します。
ここでは、スライディングウィンドという技術が用いられます。予め学習しておいた分類器を画像全体に走らせ、パッチ内の領域に文字列が含まれるかどうかを分類していくというものです。
これにより、画像内のどこの領域に文字列があるかを検出します。
![slide_wind.png](https://qiita-image-store.s3.amazonaws.com/0/142563/ba5b726d-d123-09bf-473f-3d597be4316e.png)

### テキストの分割
テキスト分割では、テキスト検出によって得られた領域に含まれる文字列を、個々の文字に分割します。
ちょうど2つの文字の切れ目が真ん中にあるような陽性データと、文字の切れ目ではないような陰性データにより、2つの文字の切れ目分割器を作っておきます。
この分割器を、上で得られた領域に走査させることで、文字の切れ目を判定し、個々の文字を抽出します。
![moji_bunkatu.png](https://qiita-image-store.s3.amazonaws.com/0/142563/c7f2b882-917f-0361-21b6-09e40d8917f7.png)

### 文字の認識
文字の認識では、テキスト分割によって得られた個々の文字が、どの文字（図の場合だとひらがな）に対応しているかを予測します。
![moji_ninshiki.png](https://qiita-image-store.s3.amazonaws.com/0/142563/5932a83f-e66c-92d0-5b19-4d0cf3abd24a.png)





# 学習データの人工的な作成方法について
Photo OCRの例では、多くの（というかパイプラインの全てで）教師あり学習を用いていました。
教師あり学習では、低バイアスな学習アルゴリズムに大量の学習データを食わせて訓練することで、より高いパフォーマンスを叩きます。
学習データが大量に用意できる場合には問題ありませんが、少量しか用意できない場合にはどうすればよいでしょうか？
ここでは、学習データが少ない場合に、人工的に学習データを生成することで、学習データを水増しする2つの方法について説明します。

## 0から作り出す
これは学習用データを、変換や組み合わせなどにより、自作するというもの。
特に「文字」を学習データとして取り扱う場合、ワープロソフトやwebなどのフォントライブラリを活用し、様々な種類の文字をランダムな背景にペーストしていくということを行います。
そして、この合成した人工文字画像に歪みなどを加えることで、本物のデータっぽくします。
こうすることで、無制限に学習データを量産することができます。

## 既にある学習データを複製する
これは、すでに持っている手本に対して、何かしらノイズを加えるなどの編集を行うことでデータを増幅するというもの。
例えば文字の場合だと、文字の画像に若干歪みを加えることで、新たな学習データを生成する。

ここで注意しておくこととして、元のデータに加える変更（歪みやノイズ）は、テストデータで見られる歪みやノイズを代表しているべきである、ということです。
テストデータには出てこなさそうな歪みやノイズを加えても、分類・抽出の役には立ちませんからね。

## 全体的な注意点
1. 人工的に学習データを作る前に、学習データを量産することが本当に役に立つのかを確認しておく。
学習曲線のプロットなどを行い、手持ちの分類器が低バイアスであるか/低バイアスにすることができるかどうか確認する。学習データ量産したけど意味なかった...という徒労は避けるべきです。

2. 学習データを人工的に作るコストと、人手でデータを収集・ラベル付けを行うコストを比較して、どちらの方が簡単か考える。案外、人手の方が早く十分な量を集めることができる場合が多いです。

3. クラウドソーシングの利用を考える。比較的安価に、ラベル付き学習データをたくさん集めてくれる。


# Ceiling Analysis（天井分析）
開発に掛ける時間は最も貴重なリソースの1つです。天井分析では、パイプラインのどのモジュールを改善することが、パフォーマンスを最も改善するのかを分析できます。

天井分析では、パイプラインの各モジュールのパフォーマンスを順に100%にしていき、全体のパフォーマンスがどれだけ向上するのかを調べていきます。
これにより、どのモジュールを改善することが、全体のパフォーマンスを改善する上で最も効果があるのかが分かります。

## 手順
Photo OCRの例で考えます。
Photo OCRの通常の手順で識別を行った結果、72%の識別精度を持っているとします。
![図3.png](https://qiita-image-store.s3.amazonaws.com/0/142563/bd8db3a3-1405-2c34-2525-5bcbc343194e.png)


　
まずは、最初のモジュールであるテキスト検出の精度を100%にしてやります。画像のどこにテキストがあるのかを手動で与えてやるのです。
そして、その結果システム全体のパフォーマンスがどれだけ向上したかを見ます。すなわち、もし完璧にテキスト検出できるとしたら、どれだけ全体のパフォーマンスは向上するのかを分析します。
この例だと、17%の向上が見られました。
![図4.png](https://qiita-image-store.s3.amazonaws.com/0/142563/eae36169-1704-a799-d1cf-02ae8801dd23.png)

　
次に、2つ目のモジュールであるテキスト分割の精度を100%にしてやります。
その結果、1%の向上が見られました。
![図5.png](https://qiita-image-store.s3.amazonaws.com/0/142563/549e28f8-5083-5e6a-3487-d0e6b61d4cff.png)

　
最後に、3つ目のモジュールである文字認識の精度を100%にしてやります。
当然、100%になることを確認します。10%の向上が見られました。
![図6.png](https://qiita-image-store.s3.amazonaws.com/0/142563/cb90cfba-1202-f18f-d405-034bae573d7c.png)

　
この分析を行う良いところは、各モジュールを改善したときの潜在的な上限を見ることができることです。
テキスト検出の改善に時間を使えば、最大で全体パフォーマンスの17%を向上させることが期待できるということが分かります。
一方で、テキスト分割の改善に時間を割いても、最大で1%しか向上させることができない、ということが分かります。

このように天井分析を行うことで、システムのパフォーマンスを向上させるためには、どのモジュールにどれだけの時間を使うべきかを決定するのに、役立てることができます。