大規模コーパスでGoogle Cloud Speech To Text APIの精度検証を行う & アップデート内容の検証

どうもこんにちは!新型コロナウイルスの影響で卒業式が中止になった、2020年新卒入社予定の山口です。

今回はGoogle Cloud Speech-to-Text API(以下GST)を大規模コーパスで精度検証した結果と、GSTアップデートの検証内容について共有していけたらと思います。

過去のGSTに関する記事もどうぞ tech-blog.optim.co.jp

tech-blog.optim.co.jp

大規模コーパスでGSTの精度検証を行う

大規模コーパス(Japanese versatile speech corpus)を用いて、より詳細にGSTの認識精度の検証を行いました。

JVS (Japanese versatile speech) corpusについて

今回はJVS (Japanese versatile speech) corpusを使って、音声認識の精度検証を行います。

JVS corpusは日本語音声のデータベースで、音声データと読みのテキストデータなどが入っています。特にこのコーパスでは話者100人が同じ文章を読んでいるので、話者ごとに精度の比較をすることもできます。

精度検証について

前回までは認識精度は手動で行っていましたが、今回は話者100人、音声データも100通りあるので、精度検証のスクリプトを組みました。

日本語NLPライブラリのGINZAを使って、形態素分析を行い、正解データと認識データを比較、誤っている単語を「挿入誤り」、「脱落誤り」、「置換誤り」に分類します。その数を数えて、単語認識率と単語正解率をそれぞれ算出します。 (誤りの種類と認識率などの計算は以前のテックブログの方に詳細を記載しています。)

*注意

作成した認識精度スクリプトはGINZAの形態素分析の精度に依存しています。そのためここで算出した値は比較・参考の数値として見てください。

認識精度の比較

認識結果は以下の通りになりました。(男性49人、女性51人、合計100人でそれぞれ平均した値です。)

単語認識率 単語正解率
話者100人 87.84 86.24
男性のみ 88.24 86.73
女性のみ 87.45 85.77

話者はコーパスでのラベルに基づいて男女に分けました。男女でそこまで大きな差は見受けられませんでした。

音量ごとによる精度の比較

音量変化の影響も調査を行いました。 ffmpegで音量を下げていきます。

(元の音声は平均-27.81db,最大音量-10.83db。40dbまで5dbづつ音量を下げました)

  • 話者100人
単語認識率 単語正解率
original 87.84 86.24
-5db 87.68 86.04
−10db 87.82 86.21
−15db 87.67 86.03
−20db 87.59 85.96
−25db 87.84 85.88
−30db 87.24 85.63
−35db 86.75 85.11
−40db 85.25 83.7
  • 男性のみ
単語認識率 単語正解率 「正解データ」また 禰寝 氏 は 中山 王 の 治める 琉球 王国 と の 交易 に も 参加 し た 。 スマートフォン から フィーチャーフォン まで マルチ デバイス に 対応 。 軽妙 洒脱 な ナレーション から 情緒 感 溢れる 語り まで 幅広い 表現力 を 持つ 。 構造 は 鋼製 の 単一 アーチ で 橋脚 は 石積み で ある 。
original 88.24 86.73 また 禰寝 氏 は 中山 王 の 納める 琉球 王国 と の 交易 に も 参加 し た 。 スマートフォン から フィーチャーフォン まで マルチ デバイス に 対応 。 軽妙 洒脱 な ナレーション から 情緒 感 あふれる 語り まで 幅広い 表現力 を 持つ 。 五臓 は 恒星 の 単一 は 家 で 橋脚 は 石積み で ある 。
−5db 88.38 86.91 また 禰寝 氏 は 中山 王 の 納める 琉球 王国 と の 交易 に も 参加 し た 。 スマートフォン から フィーチャーフォン まで マルチ デバイス に 対応 。 軽妙 洒脱 な ナレーション から 情緒 感 あふれる 語り まで 幅広い 表現力 を 持つ 。 構造 は 構成 の 単一 は 家 で 橋脚 は 石積み で ある 。
−10db 88.39 86.96 また 禰寝 氏 は 中山 王 の 納める 琉球 王国 と の 交易 に も 参加 し た 。 スマートフォン から フィーチャーフォン まで マルチ デバイス に 対応 。 軽妙 洒脱 な ナレーション から 情緒 感 あふれる 語り まで 幅広い 表現力 を 持つ 。 構造 は 構成 の 単一 は 家 で 橋脚 は 石積み で ある 。
−15db 88.19 86.71 また 禰寝 氏 は 中山 王 の 納める 琉球 王国 と の 交易 に も 参加 し た 。 スマートフォン から フィーチャーフォン まで マルチ デバイス に 対応 。 軽妙 洒脱 な ナレーション から 情緒 感 あふれる 語り まで 幅広い 表現力 を 持つ 。 構造 は 構成 の 単位 等 で 橋脚 は 石積み で ある 。
−20db 88.09 86.57 また 禰寝 氏 は 中山 王 の 納める 琉球 王国 と の 交易 に も 参加 し た 。 スマートフォン から フィーチャーフォン まで マルチ デバイス に 対応 。 軽妙 洒脱 な ナレーション から 情緒 感 あふれる 語り まで 幅広い 表現力 を 持つ 。 構造 は 構成 の 単一 は 家 で 橋脚 は 石積 で ある 。
−25db 88.19 86.69 また 禰寝 氏 は 中山 王 の 納める 琉球 王国 と の 交易 に も 参加 し た 。 スマートフォン から フィーチャーフォン まで マルチ デバイス に 対応 。 軽妙 洒脱 な ナレーション から 情緒 感 あふれる 語り まで 幅広い 表現力 を 持つ 。 構造 は 構成 の 単一 は 家 で 橋脚 は 石積 で ある 。
−30db 87.55 86.03 また 禰寝 氏 は 中山 王 の 納める 琉球 王国 と の 交易 に も 参加 し た 。 スマートフォン から フィーチャーフォン まで マルチ デバイス に 対応 。 洒脱 な ナレーション から 情緒 感 あふれる 語り まで 幅広い 表現力 を 持つ 。 構造 は 構成 の 単一 は 家 で 橋脚 は 石積 で ある 。
−35db 87.26 85.72 また 禰寝 氏 は 中山 王 の 納める 琉球 王国 と の 交易 に も 参加 し た 。 スマートフォン から フィーチャーフォン まで マルチ デバイス に 対応 。 洒脱 な ナレーション から 情緒 感 あふれる 語り まで 幅広い 表現力 を 持つ 。 構造 は 構成 の 単一 は 家 で 橋脚 は 石積 で ある 。
−40db 85.42 83.9 また 禰寝 氏 は 中山 王 の 納める 琉球 王国 と の 交易 に も 参加 し た 。 スマートフォン から フィーチャーフォン まで マルチ デバイス に 対応 。 バス な ナレーション から 情緒 感 あふれる 語り まで 幅広い 表現力 を 持つ 。 コーセー の 単一 は 家 で 橋脚 は 石積 で ある 。
  • 女性のみ
単語認識率 単語正解率 「正解データ」また 禰寝 氏 は 中山 王 の 治める 琉球 王国 と の 交易 に も 参加 し た 。 スマートフォン から フィーチャーフォン まで マルチ デバイス に 対応 。 軽妙 洒脱 な ナレーション から 情緒 感 溢れる 語り まで 幅広い 表現力 を 持つ 。 構造 は 鋼製 の 単一 アーチ で 橋脚 は 石積み で ある 。
original 87.45 85.77 また 禰寝 氏 は 中山 王 の 納める 琉球 王国 と の 交易 に も 参加 し た 。 スマートフォン から フィーチャーフォン まで マルチ デバイス に 対応 。 軽妙 洒脱 な ナレーション から 情緒 感 あふれる 語り まで 幅広い 表現力 を 持つ 。 構造 は 構成 の 単一 味 で 橋脚 は 石積 で ある 。
−5db 87 85.2 また 禰寝 氏 は 中山 王 の 納める 琉球 王国 と の 交易 に も 参加 し た 。 スマートフォン から フィーチャーフォン まで マルチ デバイス に 対応 。 軽妙 洒脱 な ナレーション から 情緒 感 あふれる 語り まで 幅広い 表現力 を 持つ 。 構造 は 構成 の 単一 味 で 橋脚 は 石積 で ある 。
−10db 87.27 85.5 また 禰寝 氏 は 中山 王 の 納める 琉球 王国 と の 交易 に も 参加 し た 。 スマートフォン から フィーチャーフォン まで マルチ デバイス に 対応 。 軽妙 洒脱 な ナレーション から 情緒 感 あふれる 語り まで 幅広い 表現力 を 持つ 。 構造 は 構成 の 単一 味 で 橋脚 は 石積 で ある 。
−15db 87.18 85.38 また 禰寝 氏 は 中山 王 の 納める 琉球 王国 と の 交易 に も 参加 し た 。 スマートフォン から フィーチャーフォン まで マルチ デバイス に 対応 。 軽妙 洒脱 な ナレーション から 情緒 感 あふれる 語り まで 幅広い 表現力 を 持つ 。 構造 は 構成 の 単一 味 で 橋脚 は 石積 で ある 。
−20db 87.10 85.39 また 禰寝 氏 は 中山 王 の 納める 琉球 王国 と の 交易 に も 参加 し た 。 スマートフォン から フィーチャーフォン まで マルチ デバイス に 対応 。 軽妙 洒脱 な ナレーション から 情緒 感 あふれる 語り まで 幅広い 表現力 を 持つ 。 構造 は 構成 の 単一 味 で 橋脚 は 石積 で ある 。
−25db 86.78 85.09 また 禰寝 氏 は 中山 王 の 納める 琉球 王国 と の 交易 に も 参加 し た 。 スマートフォン から フィーチャーフォン まで マルチ デバイス に 対応 。 軽妙 洒脱 な ナレーション から 情緒 感 あふれる 語り まで 幅広い 表現力 を 持つ 。 構造 は 構成 の 単一 味 で 橋脚 は 石積 で ある 。
−30db 86.95 85.23 また 禰寝 氏 は 中山 王 の 納める 琉球 王国 と の 交易 に も 参加 し た 。 スマートフォン から フィーチャーフォン まで マルチ デバイス に 対応 。 軽妙 洒脱 な ナレーション から 情緒 感 あふれる 語り まで 幅広い 表現力 を 持つ 。 構造 は 構成 の 単一 味 で 橋脚 は 石積 で ある 。
−35db 86.26 84.52 また 禰寝 氏 は 中山 王 の 納める 琉球 王国 と の 交易 に も 参加 し た 。 スマートフォン から フィーチャーフォン まで マルチ デバイス に 対応 。 軽妙 洒脱 な ナレーション から 情緒 感 あふれる 語り まで 幅広い 表現力 を 持つ 。 構造 は 構成 の 単一 味 で 橋脚 は 石積 で ある 。
−40db 85.08 83.5 また 飯 は 中山 太 納める 琉球 王国 と の 交易 に も 参加 し た 。 スマートフォン から フィーチャーフォン まで マルチ デバイス に 対応 。 軽妙 洒脱 の ナレーション から 情緒 感 あふれる 語り まで 幅広い 表現力 を 持つ 。 構造 は 構成 の 単一 味 で 橋脚 は 石積 で ある 。

音量変化と認識精度の変化のグラフは以下の通りになります。

f:id:optim-tech:20200317120310p:plain:h600

f:id:optim-tech:20200317120306p:plain:h600

以上が大規模コーパスを用いたGSTの精度検証でした!

アップデート検証

GSTのアップデートとして、話者識別と句読点が追加されたので試してみました。
(Python, Java, JavaScriptで動作を確認しました。)

話者識別

ベータ版と実装の仕方が違うので注意をしてください。

configパラメータに値を追加すると話者識別ができます。

  • python
diarization_config={
    "enable_speaker_diarization": True, #"True" にすると話者識別ができます
    "max_speaker_count": 4  #最大話者数 何も設定していない時、default値は6です
    "min_speaker_count": 2, #最小話者数 何も設定していない時、default値は2です
    }
  • java
// ここで話者識別の設定情報を作成します。
SpeakerDiarizationConfig DiarizationConf = 
    SpeakerDiarizationConfig.newBuilder()
    .setEnableSpeakerDiarization(true) // true にすると話者識別ができます
    .setMaxSpeakerCount(4) // 最大話者数 何も設定していない時、default値は6です
    .setMinSpeakerCount(2) // 最小話者数 何も設定していない時、default値は2です
    .build();

RecognitionConfig config = RecognitionConfig.newBuilder()
    .setEncoding(AudioEncoding.LINEAR16)
    .setSampleRateHertz(16000)
    .setLanguageCode("ja-JP")
    .setDiarizationConfig(DiarizationConf) // 設定した情報を入れます
    .build();
  • javascript
const config = {
    encoding: 'LINEAR16',
    sampleRateHertz: 16000,
    languageCode: 'ja-JP',
    diarizationConfig: {
        enableSpeakerDiarization:true, // true にすると話者識別ができます
        maxSpeakerCount:4 // 最大話者数 何も設定していない時、default値は6です
        minSpeakerCount:2 // 最小話者数 何も設定していない時、default値は2です
    }
};

実行したコードが以下の通りになります。(configの設定以外はベータ版と仕様が変わってないので、Java, JavaScriptの分はリンク先のコードを参考に実装してください。)

import argparse

def transcribe_file(speech_file):
    from google.cloud import speech
    from google.cloud.speech import enums
    from google.cloud.speech import types
    import io
    client = speech.SpeechClient()
    speech_python_migration_sync_request]
    speech_python_migration_config]
    with io.open(speech_file, 'rb') as audio_file:
        content = audio_file.read()

    audio = types.RecognitionAudio(content=content)
    config = types.RecognitionConfig(
        encoding=speech.enums.RecognitionConfig.AudioEncoding.LINEAR16,
        sample_rate_hertz=16000,
        language_code='ja-JP',
        audio_channel_count=1,
        ##追加部分##
        diarization_config={
            "enable_speaker_diarization":True, "min_speaker_count":2,
            "max_speaker_count":2 }
        ####
        )

    response = client.recognize(config, audio)

    for result in response.results:
        alternative = result.alternatives[0]

        sen = ''
        result_ = ''
        pre_speaker = -1
        for word in alternative.words:
            sentence = word.word.split("|")
            if word.speaker_tag == pre_speaker:
                sen += sentence[0]
            else:
                if not pre_speaker == -1:
                    result_ += "speaker{}:".format(pre_speaker) + sen + '\n'
                sen = sentence[0]
                pre_speaker = int(word.speaker_tag)
        
        print(result_)

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('path')
    args = parser.parse_args()
    transcribe_file(args.path)

与えた音声ファイル元 → 元音声動画

結果

speaker2:農林水産省九州農政局の白石です
speaker1:がです新型コロナウイルスの
speaker2:影響で入学式卒業式をはじめとした式典の開催がの需要が減少しております農林
speaker1:水産省が花の消費拡大を図るため家庭や職場に花を飾って楽しむ花いっぱいプロジェクトを始めますたまには心を癒す季節感を醸す部屋が華やぐ心が豊かになるなどの魅力がありますようにしたい関係団体の皆様職場での華かざりコスプレの花の展示なのにご協力お願い致します九州農政局では
speaker2:九州産の花を中心にオフィスの

まだ公式の方でサンプルプログラムなどがでていないので、一部正しくない部分があるかもしれませんが以上のコードを実行することで話者識別ができるようになりました。

句読点

こちらはベータ版との仕様変更はありませんでした。

configパラメータに値を追加すると句読点を打つことができます。

enable_automatic_punctuation=True

実行したコードは以下の通りになります。

import argparse

def transcribe_file(speech_file):
    from google.cloud import speech
    from google.cloud.speech import enums
    from google.cloud.speech import types
    import io
    client = speech.SpeechClient()
    speech_python_migration_sync_request]
    speech_python_migration_config]
    with io.open(speech_file, 'rb') as audio_file:
        content = audio_file.read()

    audio = types.RecognitionAudio(content=content)
    config = types.RecognitionConfig(
        encoding=speech.enums.RecognitionConfig.AudioEncoding.LINEAR16,
        sample_rate_hertz=16000,
        language_code='ja-JP',
        audio_channel_count=1,
        ##追加部分##
        enable_automatic_punctuation=True
        ####
        )

    response = client.recognize(config, audio)

    for result in response.results:
        print(u'Transcript: {}'.format(result.alternatives[0].transcript))
        
if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('path')
    args = parser.parse_args()
    transcribe_file(args.path)

結果

Transcript: 農林水産省九州農政局の白石ですがです新型コロナウイルスの影響で入学式卒業式をはじめとした式典の開催がの需要が減少しております農林水産省が花の消費拡大を図るため、家庭や職場に花を飾って楽しむ花いっぱいプロジェクトを始めますたまには心を癒す季節感を醸す部屋が華やぐ心が豊かになるなどの魅力がありますようにしたい関係団体の皆様、職場での華かざりコスプレの花の展示なのにご協力お願い致します九州農政局では九州産の花を中心にオフィスのとこでもなんか立っていませんか。

以上のように文章に句読点を打つことができました。

2つを同時に試してみると

アップデートで追加された以上の2つを同時に試してみるとどうなるか検証してみました。

結果としては、話者識別した結果に句読点が付きませんでした。

APIから返される結果は以下の構造になっており、

response
    results
        alternatives
            transcript : 句読点が入った全体の認識結果
            words : 言葉単位の認識結果(リスト形式)
                word : 言葉(読みと漢字などに変換されたもの)
                speaker_tag : 話者のタグ

これらの結果からgoogleの音声認識は

音声 → 読み → 単語分割(ここか読みの部分で話者識別が入る) → 文章生成(ここで句読点が入る)

の流れで処理が行われているのかなと思います。

また句読点のついた文(transcript)に話者識別を行いたい時は、API側でなく自分たちの方でtranscriptとwordsの結果をマッチングさせてあげるとできます。

以上が今回のアップデートで追加された項目でした!

まとめ

今回は大規模コーパスを用いての精度とGSTのアップデートの検証を行いました。精度検証の方ではある程度の音量低下は問題なかったが、極端に音量が下がると認識率が低下することを確認しました。

アップデートの検証の方では、今までベータ版のみでの提供が今回から公式で使えるようになり、今回はその検証を行いました。ざっくりと使用した感じの精度はそこまでいいものではなかったですが、新機能によってできることの幅が広がるので、嬉しいアップデートになりました。

オプティムでは大規模データセットにワクワクするエンジニアを募集しています。

JVS (Japanese versatile speech) corpus ライセンス表記

テキストデータは,CC-BY-SA 4.0などにてライセンスされています.

音声データは,以下の場合に限り使用可能です.

  • アカデミック機関での研究
  • 非商用目的の研究(営利団体での研究も含む)
  • 個人での利用(ブログなどを含む)