日本語の音声認識の市場調査と軽く触ってみた

# はじめに

この記事の対象は、日本語の音声認識をする人を対象としています。

本記事で扱う音声認識は、mp3などのファイルに固定のファイルを想定しています。
ストリーミングしたリアルタイム性のある音声認識は対象外です。

# サービスの紹介と、その特徴

| サービス名 | 料金 | 動作環境 | コメント |
|:-:|:-:|:-:|:-:|:-:|
| [Google Speech-to-Text](https://cloud.google.com/speech-to-text/?hl=ja) | 0~60分：無料トライアル<br>60分超～100万分まで：$0.006/15 秒**  | API  |  簡単に利用できた |
| [Amazon Transcribe](https://aws.amazon.com/jp/transcribe/) | [250,000分まで0.00040USD](https://aws.amazon.com/jp/transcribe/pricing/) | API | S3挟まないと動かない |
| [Azure Speech Services](https://azure.microsoft.com/ja-jp/services/cognitive-services/speech-services/) |[1 か月あたり 5 音声時間は無料](https://azure.microsoft.com/ja-jp/pricing/details/cognitive-services/speech-services/)| API |触ったことがなく、詳しくないです。|
|[AmiVoice](https://www.advanced-media.co.jp/products/service/scribeassist)|API：0.0275円/秒〜<br>スタンドアロンはお問合せから| APIもあるし、スタンドアロン環境のwindowsで可能|お高いらしい。触ったことがなく、詳しくないです。|
|  [julius](https://julius.osdn.jp/) | 無料※BSDライセンス  |  windows、Linux | 無料でするならこれ一択<br>環境構築構築が大変で、単語辞書や文法規則から準備する必要もある。<br>  | 


# 動かしてみる

### Amazon Transcribe

[コンソール画面からの動作はこちら](https://docs.aws.amazon.com/ja_jp/transcribe/latest/dg/getting-started-python.html)
音声認識の流れはS3に音声ファイルを保存し、保存したファイルに向けたジョブを作成し、作成したジョブで判定た判定結果をS3に保存する流れでした。
そのため、音声認識にはAWSにログインして、S3にファイルをあげることとジョブの作成が必要でした。

![スクリーンショット 2021-05-21 10.08.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217551/64f4e145-a2ce-6712-fa29-4fd85193d25c.png)

[プログラムからの動作はこちら](https://docs.aws.amazon.com/ja_jp/transcribe/latest/dg/getting-started-python.html)

コンソール画面とやっていることは原則同じです。S3に音声ファイルをアップロードし、ジョブを作成し、その結果をS３に保存します。その結果のS3にはjsonが出力されるので、出力結果をみる感じでした。

```python
#!/usr/bin/env python3
from __future__ import print_function
import time
import boto3
transcribe = boto3.client('transcribe')
job_name = "job_name"
job_uri = "s3://DOC-EXAMPLE-BUCKET1/key-prefix/file.file-extension"
transcribe.start_transcription_job(
    TranscriptionJobName=job_name,
    Media={'MediaFileUri': job_uri},
    MediaFormat='wav',
    LanguageCode='en-US'
)
while True:
    status = transcribe.get_transcription_job(TranscriptionJobName=job_name)
    if status['TranscriptionJob']['TranscriptionJobStatus'] in ['COMPLETED', 'FAILED']:
        break
    print("Not ready yet...")
    time.sleep(5)
print(status)
```

```json
{
  "jobName": "job_name",
  "accountId": "*************",
  "results": {
    "transcripts": [
      {
        "transcript": "こんにちは"
      }
    ],
    "items": [
      {
        "start_time": "1.27",
        "end_time": "1.96",
        "alternatives": [
          {
            "confidence": "0.9992",
            "content": "こんにちは"
          }
        ],
        "type": "pronunciation"
      }
    ]
  },
  "status": "COMPLETED"
}
```


### google speech to text

サンプルプログラムを以下に記載します。
APIの返り値が認識結果がだけと、かなりシンプルな仕組みになっていました。
あと準備もほとんどしなくてよくて、結構簡単でした。

```python
#!/usr/bin/env python3
import speech_recognition


def api_google():
    file_path = "./voice_file.wav"

    r = speech_recognition.Recognizer()
    with speech_recognition.AudioFile(file_path) as src:
        audio = r.record(src)

    result = r.recognize_google(audio, language='ja-jp')
    print(result)


if __name__ == "__main__":
    api_google()

"""
$ ~/python3 google_api_sound.py 
こんにちは
"""
```

### Azure

Azureはアカウントを持っていないため、紹介だけになります。[Azureはデモがありました。](https://azure.microsoft.com/ja-jp/services/cognitive-services/speech-to-text/#features)

![スクリーンショット 2021-05-21 10.40.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217551/2120044c-d407-ba4c-c086-04402d03318f.png)


[公式のドキュメントはこちら。](https://docs.microsoft.com/ja-jp/azure/cognitive-services/speech-service/rest-speech-to-text)
短い音声（simple）の場合は、JSONが帰ってきて、DisplayTextに認識内容が入るようです。

```json
{
  "RecognitionStatus": "Success",
  "DisplayText": "Remind me to buy 5 pencils.",
  "Offset": "1236645672289",
  "Duration": "1236645672289"
}
```

### AmiVoice
触ったことがないため、割愛します。


### julius

下の画像はjuliusを起動し、hello.wavファイルを読み込ませた画像です。

デフォルトで付属されている単語と文法で、 ```（果物）が（何個）あります。``` の音声認識ができます。
この固定の文章以外で音声認識したい場合は、単語と文法規則の両方の設定ファイルを作成する必要があります。
また、出力結果の画像を下に記載します。
下の出力結果から、sentence1を抜き出して音声認識の結果として出力します。

![スクリーンショット 2021-05-20 11.26.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217551/310b12c9-ed50-08b2-6b0f-9acdfd11c215.png)

環境構築にすごく苦戦しました。
３回は環境構築しましたが、その度に何かしらエラーがでてサクサク環境構築はできなかったです。
以下は環境構築で苦戦したことを箇条書きで書き出します。

* utf-8に統一する
* ファイルには実行権限付与しないといけない（mkdfa.plとyomi2voca.plにchmod 755しました）
* perlは実行場所が大事で、./mkdfa.plと~/foo/mkdfa.plでは意味が違う
* mkdfa.plで ```sh: mkfa: command not found``` 言い出したら、[このサイトに従いソースコードを書き換える](http://uragamism.blogspot.com/2014/11/mkdfa.pl-for-windows.html)
* ノイズキャンセル等の前処理を勝手に追加すると、精度が落ちる。
* 16kHzに統一する。（48kHzや44.1kHzだと精度が落ちる。HMMの関係？）
* [このサイトから使えそうなオプションは積極的に採用する](https://julius.osdn.jp/juliusbook/ja/desc_options.html)。探索幅を広げるのは特に精度向上に一役買った。

# まとめ

前回の合成音声に続き音声認識もまとめました。
大きな流れとして、大企業が精度の良いものをAPIとして開発し、その出来上がっているものを使って、サービスに注力できるようになってるみたいです。

クラウド化した世界で、APIを使ったオンラインでの音声認識が主流になっており、オンプレ環境の音声認識はamiVoiceが一択の雰囲気でした。
無料でするならJuliusですが、本記事でも書いてる他ググったらわかるように、環境構築がかなり苦戦します。また教え込んだ文章しか音声認識できず、使用場面は限られると思います。