TensorFlow Speech Recognition Challenge 紹介と実践

# はじめに
kaggleの[TensorFlow Speech Recognition Challenge](https://www.kaggle.com/c/tensorflow-speech-recognition-challenge/)を紹介し、
Tutorialに従って学習し、結果を送信するまで実践します。
この競技は、**1秒の英語音声データの12クラス識別**タスクです。
Tensorflowで実行できるモデルが対象で、かつRaspberrypi3上で一定時間内に実行できるモデルである必要があります。

# 競技ルール

* 1秒のwavファイルが入力で、以下12クラスを識別。unknownは初めの10クラスのどれでもなく、かつsilenceでないもの。

```
yes, no, up, down, left, right, on, off, stop, go, silence, unknown
```

* train/testデータは[こちら](https://www.kaggle.com/c/tensorflow-speech-recognition-challenge/data)からダウンロード。
train : TensorflowとAIYのチームが作成・公開した[Speech Commands Data Set v0.01](https://research.googleblog.com/2017/08/launching-speech-commands-dataset.html)と同じもの。約65000個のwavファイル。上記12クラスだけでなく、全部で31クラスあり、今回該当しないクラスはunknownとして扱う。\_background_noise_には長時間のsilenceデータが入っている。
test : 158538個のwavファイル。正解ラベル無し。


* testデータに対する結果を以下の形式の.csvファイルにし、送信します。

```
fname,label
clip_000044442.wav,silence
clip_0000adecb.wav,left
clip_0000d4322.wav,unknown
```

* 学習に、上記のデータ以外は使用してはならない。合成データ等も不可。
* モデルは、TensorFlow 1.4で実行できる、frozen TensorFlow GraphDefである必要がある。このため自前の推論コードは使えない。
* モデルサイズ < 5MB
* モデルの入力は16000個,floatのPCM。出力は各12クラスの確率(softmax)。
* RaspberryPi3(overclock無)上の実行時間 <= 200 msec
* モデルの学習にpretrainedを使っていいかはグレー?
* [leaderboard](https://www.kaggle.com/c/tensorflow-speech-recognition-challenge/leaderboard)に表示されているScore,順位は、testデータの30%によるもの。実際の順位は残り70%で決められる。
* 何回でもentryできるようだが、最終提出は1アカウントにつき ~~2~~ 3つ選択する必要がある。
* 2018.1.8 19時現在、参加チーム数1263。leaderboardの1位Scoreは0.90。
* 賞金や日程は割愛。参加者の初めの500人に$500のGCPクレジット付与もあり。


# Speech Commands Dataset
[Google Research Blog : Launching the Speech Commands Dataset](https://research.googleblog.com/2017/08/launching-speech-commands-dataset.html)　[和訳](https://developers-jp.googleblog.com/2017/09/launching-speech-commands-dataset.html)
約65000個, 31クラスのwavファイル。Creative Commons BY 4.0 license。
inference用に、4つのAndroidデモアプリが用意されている。　[github](https://github.com/tensorflow/tensorflow/tree/master/tensorflow/examples/android/)　[apk](http://ci.tensorflow.org/view/Nightly/job/nightly-android/lastSuccessfulBuild/artifact/out/tensorflow_demo.apk)
TF Speechが発話認識アプリ。マイクに発話すると認識したラベルがライトアップする。
![](https://3.bp.blogspot.com/-Mo-sJK2QM5U/WZ31e7iMvHI/AAAAAAAAB-A/IEzEr4P6up4jagW2H0NcxyK3w26DQ_kVgCLcBGAs/s400/image1.png)

# Tutorial : Simple Audio Recognition 実践
[Tensorflow : Tutorials : Simple Audio Recognition](https://www.tensorflow.org/versions/master/tutorials/audio_recognition)に従って実践してみます。

## 学習
Tensorflowのコードツリーを取得しておきます。
https://github.com/tensorflow/tensorflow
このTutorialで使用するのは、tensorflow/examples/speech_commands 以下です。
train.py を実行すると、上記Speech Commands Datasetを/tmpにダウンロードし、学習を始め、18000回iterationを行って終了します。

```
python tensorflow/examples/speech_commands/train.py
```

|展開ディレクトリ|内容|
|:---|:---|
| /tmp/speech_dataset | 上記Speech Commands Dataset |
| /tmp/speech_commands_train | 学習時のTensorflowのワークディレクトリ|
| /tmp/retrain_logs|学習時のログ|

|主なコマンドオプション|デフォルト|内容|
|:---|:---|:---|
|--how_many_training_steps|15000,3000|iteration数|
|--learning_rate|0.001,0.0001|leaning rate|
|--batch_size|100|batch size|
|--wanted_words|yes,no,up,down,left,right,on,off,stop,go|識別するラベル(これ以外はunknown扱い)|

Tensorboardで経過を見ることができます。以下を実行後、http://localhost:6006 を開きます。

```
tensorboard --logdir /tmp/retrain_logs
```

![kaggle_tensorboard.png](https://qiita-image-store.s3.amazonaws.com/0/198573/7e8a857c-5f0f-0c6b-1b2e-c1dcf0062123.png)

18000回実行後、以下のログで終了します。学習画像セットはtrain,validation,testに分けられますが、今回はvalidationで88.8%, testで88.4%でした。
Confusion Matrixは12クラスのどれが精度良く識別できているか確認するもので、正解クラスが各行に対し推論結果が各列であり、精度100%であれば対角行列になります。

```
INFO:tensorflow:Step 18000: Validation accuracy = 88.8% (N=3093)
INFO:tensorflow:Saving to "/tmp/speech_commands_train/conv.ckpt-18000"
INFO:tensorflow:set_size=3081
INFO:tensorflow:Confusion Matrix:
 [[257   0   0   0   0   0   0   0   0   0   0   0]
 [  1 188   6   2   5  11   1   6   7   0  11  19]
 [  2   2 235   4   2   5   4   1   0   0   1   0]
 [  1   6   0 216   3  12   2   1   0   0   3   8]
 [  2   1   0   0 259   0   3   0   0   2   4   1]
 [  2   4   0  14   2 217   1   0   1   0   1  11]
 [  1   4  11   0   3   1 245   2   0   0   0   0]
 [  2  14   0   0   4   0   2 235   0   2   0   0]
 [  1   4   0   0   2   1   1   2 232   2   0   1]
 [  2   4   0   0  17   1   2   2   8 222   4   0]
 [  0   1   1   0   9   2   2   0   0   2 229   3]
 [  1   9   0  32   5   6   6   1   0   0   2 189]]
INFO:tensorflow:Final test accuracy = 88.4% (N=3081)
```

## freeze化と推論テスト
学習したcheckpointデータから、デバイスで実行するコンパクトなモデルに変換するために、freeze化する必要があります。

```
python tensorflow/examples/speech_commands/freeze.py \
--start_checkpoint=/tmp/speech_commands_train/conv.ckpt-18000 \
--output_file=出力モデル.pb
```

1つのwavファイルを識別するテストコードが用意されています。

```
python tensorflow/examples/speech_commands/label_wav.py \
--graph=出力モデル.pb \
--labels=/tmp/speech_commands_train/conv_labels.txt \
--wav=テスト音声ファイル.wav
```

top3のスコアが表示されます。

```
left (score = 0.98706)
_unknown_ (score = 0.00531)
yes (score = 0.00315)
```

## (余談) bazel インストール
Tensorflowの.ccなどをビルド・実行するのにGoogleのビルドツール[bazel](https://www.bazel.build/)が必要になります。
私の環境(Ubuntu16.04)では、apt installできる bazel 0.9 ではbazel runがエラーになり、[こちら](https://github.com/tensorflow/tensorflow/issues/15492)を参考に、bazel 0.8.1を入れるとうまくできました。
[0.8.1のインストーラ](https://github.com/bazelbuild/bazel/releases)をダウンロードしてインストールします。

## Raspberrypi3 benchmark

Raspberrypi3での実行時間を確認する必要があります。
まずTensorflow1.4をインストールします。[こちら](https://www.kaggle.com/c/tensorflow-speech-recognition-challenge/discussion/43693)を参照して以下を実行。

```
sudo apt-get install libblas-dev liblapack-dev python-dev libatlas-base-dev gfortran python-setuptools
sudo ​pip2 install http://ci.tensorflow.org/view/Nightly/job/nightly-pi/lastSuccessfulBuild/artifact/output-artifacts/tensorflow-1.4.0-cp27-none-any.whl
```

ARM用ビルド済みbenchmarkツールが用意されているのでダウンロードします。
（Discussionで、x86用があれば開発促進できるのではという話があって、ソースオープンなので自分でbuildすればいいとのこと）

```
curl -O https://storage.googleapis.com/download.tensorflow.org/deps/pi/2017_10_07/benchmark_model
chmod +x benchmark_model
```
実行します。実行にはモデルファイルだけで、データを用意する必要はないようです。
なお、pretrainedモデル[conv_actions_frozen.pb](https://storage.googleapis.com/download.tensorflow.org/models/speech_commands_v0.01.zip)も用意されています。

```
./benchmark_model --graph=モデルファイル --input_layer=decoded_sample_data:0,decoded_sample_data:1 --input_layer_shape=16000,1: --input_layer_type=float,int32 --input_layer_values=:16000 --output_layer=labels_softmax:0 --show_run_order=false --show_time=false --show_memory=false --show_summary=true --show_flops=true
```

以下のように結果表示され、avg= のところがusec単位の平均実行時間。この値が200msec以下である必要があり、マージンを考えて175msecくらいが推奨とのこと。

```
2018-01-08 10:16:12.082806: I tensorflow/core/util/stat_summarizer.cc:468] Timings (microseconds): count=134 first=72637 curr=72947 min=71803 max=95794 avg=74473.2 std=4549
2018-01-08 10:16:12.082838: I tensorflow/core/util/stat_summarizer.cc:468] Memory (bytes): count=134 curr=1643420(all same)
2018-01-08 10:16:12.082869: I tensorflow/core/util/stat_summarizer.cc:468] 26 nodes observed
```


## kaggle 結果送信
テストデータの推論を実行し結果csvを出力するツールは用意されてなさそうなので、[label_wav.py](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/examples/speech_commands/label_wav.py)を参考に書きました。
結果送信するとすぐに評価が行われます。今回のTutorialそのままで学習したモデルは、Score 0.78 でした。(現在1位は0.90)
![kaggle_post.png](https://qiita-image-store.s3.amazonaws.com/0/198573/d3432b31-5d95-ce5a-bdf1-ce30bde1cf9b.png)


# Discussionから引用
kaggleの[Discussion](https://www.kaggle.com/c/tensorflow-speech-recognition-challenge/discussion)では有用なまとめ・議論がされており参考になります。
いくつか引用します。

[43516](https://www.kaggle.com/c/tensorflow-speech-recognition-challenge/discussion/43516)　主催者の１人、Peteさんから。[Tutorial](https://www.tensorflow.org/tutorials/audio_recognition)はこの人が書いた。
[43520](https://www.kaggle.com/c/tensorflow-speech-recognition-challenge/discussion/43520)　同じく主催者、Razielさん。"ok Google"等の認識エンジンを開発するグループ所属。
[44091](https://www.kaggle.com/c/tensorflow-speech-recognition-challenge/discussion/44091)　Speech Recognition を始める人のための参照リスト
[46839](https://www.kaggle.com/c/tensorflow-speech-recognition-challenge/discussion/46839)　学習データにノイズを付加してaugmentationする
[46945](https://www.kaggle.com/c/tensorflow-speech-recognition-challenge/discussion/46945)　My Tricks and Solution この方が様々な実験手法を公開していて参考になる
[43624](https://www.kaggle.com/c/tensorflow-speech-recognition-challenge/discussion/43624)　精度87.8%の実装 (pytorch)
[44970](https://www.kaggle.com/c/tensorflow-speech-recognition-challenge/discussion/44970)　train, testのcsvファイルを生成するスクリプト
[46981](https://www.kaggle.com/c/tensorflow-speech-recognition-challenge/discussion/46981)　TUT Acoustic Scene Classificationの紹介

# おわりに
* ここまでが準備段階で、これからモデルを精製していく。（締切間近
* Discussionを見ても、テストデータに対する汎化性能を出すのが難しそうです。
* 実際の順位は未発表の残70%で決まるそうで、順位がどのように変わるかも見どころです。
* 運営がルールチェックをどうするのかも気になります。