読者です 読者をやめる 読者になる 読者になる

Intelligent Technology's Technical Blog

株式会社インテリジェントテクノロジーの技術情報ブログです。

Google Cloud Speech API の精度を試す

こんにちは。中山です。

機械学習機能によって、音声をテキストに変換するサービスである、Google Cloud Speech API。こちらが先日、正式にリリースされたとアナウンスがありました。その精度がいかほどのものか、試してみたいと思います。

課金体系

Google Cloud Speech API は、Google Cloud Platform 自体の無料トライアルの枠(2017年5月時点では、12ヶ月間有効な $300 分の枠)を利用すれば、課金なしにすぐに試すことができるようです。
なお、Cloud Speech API は、毎月60分までは無料で利用でき、それ以降は時間単位で課金されるとのこと。(参考

準備

まずは公式ページの「クイックスタート」の内容にしたがって、準備を進めていきます。
なお今回は、Mac(macOS Sierra)環境で動作を検証しています。

1.Google アカウントにログイン

Google アカウントにログインします。(アカウントを持っていない場合は、新規作成します。)

2.無料トライアル開始

Cloud Speech API の 公式ページ などに設置されている、「無料トライアル」ボタンをクリックして、無料トライアルを開始します。

3.プロジェクト選択

クイックスタート のページから「【プロジェクト】ページに移動」ボタンをクリックして、新規作成した、もしくは既存の Google Cloud Platform のプロジェクトを選択します。またそのプロジェクトへの課金が有効になっていることを確認します。
(無料トライアルを開始した状態であれば、課金設定も正しく行われているはず。)

4.Speech API の有効化

同じく クイックスタート のページから「ENABLE THE API」ボタンをクリックして、Cloud Speech API を有効化します。
以下のようなページが表示されますので、プロジェクトを選択して、「続行」をクリックします。
 
  f:id:IntelligentTechnology:20170502160609p:plain:w400

続けて以下のようなページが表示されますので、「認証情報に進む」ボタンをクリックします。
 
  f:id:IntelligentTechnology:20170502160754p:plain:w400

Google App Engine または Google Compute Engine の利用状況を選択した上で、「必要な認証情報」ボタンをクリックします。
 
  f:id:IntelligentTechnology:20170502162111p:plain:w400

「サービスアカウント名」に任意の値を設定します。また「役割」欄には「プロジェクトオーナー」を指定して、「次へ」ボタンをクリックします。
 
  f:id:IntelligentTechnology:20170502164754p:plain:w400

認証情報が記載された JSON ファイルがダウンロードされますので、それを保存しておきます。

実行

公式の クイックスタート のページでは、このあと、音声が録音されたファイルを指定して、その内容を解析して、テキスト化して返す、という例が載っています。
しかし、音声認識の API の使われ方というのは、たぶんそれよりも、リアルタイムに発話した内容を、その場でテキスト化する、というパターンが多いのではないか、と想像しています。
というわけで、クイックスタートにある、音声ファイルの認識についてはスキップして、サンプルアプリケーション ページにある、Android 版のサンプルを試してみたいと思います。
(このため、クイックスタートページで記載のあった、「Google Cloud SDK のインストール」の手順もスキップしています。)

1.サンプルアプリのソースコード取得

Android 版のサンプルアプリのソースコードは こちら に公開されています。
以下コマンドでソースコードを取得します。

git clone https://github.com/GoogleCloudPlatform/android-docs-samples.git
2.Android Studio でプロジェクトを開く

取得したサンプルソースコードのフォルダの中の、「speech/Speech」フォルダを、Android Studio(Android Studio 2.3.1)で開きます。
f:id:IntelligentTechnology:20170502181035p:plain:w480

3.認証情報の適用

プロジェクトフォルダ内の「app/src/main/res/raw/」フォルダに、先ほどダウンロードした、認証情報を含む json ファイルを、「credential.json」という名前で配置します。
配置後は以下のようになります。
 
  f:id:IntelligentTechnology:20170502183331p:plain:w360

4.アプリの実行

Android 実機(Nexus5X)で、サンプルアプリを実行します。

・・・
アプリに向かって発話した内容の認識結果が画面内に出力されます。
長文もかなりの精度で認識できているのでは、とも思ったのですが、だいたいこんなものかな、という感じも受けます。
 
  f:id:IntelligentTechnology:20170508212129p:plain:w360

ソースコードの解析

1.AndroidManifest.xml

サンプルアプリのプロジェクトを見ますと、AndroidManifest.xml は、以下のように、発話した内容を録音するための設定と、インターネット接続のための設定が入っているくらいで、ほかには特別な設定は無いようです。

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
2.Java クラス

実際に音声認識処理を実行しているのが、「SpeechService」クラスの「startRecognizing」メソッド。
Speech API が提供する StreamingRecognizeRequest クラスを用いて、リアルタイムに音声認識・解析を実行するようになっています。

mRequestObserver = mApi.streamingRecognize(mResponseObserver);
mRequestObserver.onNext(StreamingRecognizeRequest.newBuilder()
    .setStreamingConfig(StreamingRecognitionConfig.newBuilder()
        .setConfig(RecognitionConfig.newBuilder(
            .setLanguageCode(getDefaultLanguageCode()) // 言語を設定して、
            .setEncoding(RecognitionConfig.AudioEncoding.LINEAR16) // 音声のエンコーディングを指定して、
            .setSampleRateHertz(sampleRate) // 音声のサンプルレートを指定
            .build())
        .setInterimResults(true)
        .setSingleUtterance(true)
        .build())
    .build());

この解析結果を受け取るのが、同じく「SpeechService」クラスで Override されている、「StreamObserver<StreamingRecognizeResponse>」クラスの「onNext」メソッド。

private final StreamObserver<StreamingRecognizeResponse> mResponseObserver
        = new StreamObserver<StreamingRecognizeResponse>() {
    @Override
    public void onNext(StreamingRecognizeResponse response) {
        String text = null;
        boolean isFinal = false;
        if (response.getResultsCount() > 0) {
            final StreamingRecognitionResult result = response.getResults(0);
            isFinal = result.getIsFinal();
            if (result.getAlternativesCount() > 0) {
                final SpeechRecognitionAlternative alternative = result.getAlternatives(0);
                text = alternative.getTranscript();
            }
        }
        if (text != null) {
            for (Listener listener : mListeners) {
                // MainActivity で定義されている Listener の 
                // onSpeechRecognized を呼び出して、結果を描画
                listener.onSpeechRecognized(text, isFinal);
            }
        }
    }

これら、Speech API が提供するクラスについては、こちら に情報があるようです。

応用

1.ヒントの設定

あらかじめ、発話が予想される単語、認識してほしい単語を「ヒント」として登録しておくことで、その単語(または一連のフレーズ)の認識精度を高める、ということが可能であるようです。

「ヒント」の登録は、Speech API が提供する「SpeechContext」クラスを用います。
たとえば、「コウカ」と発話された場合に、「効果」「高架」などではなく、「校歌」と認識させたい、という場合には、以下のように「addSpeechContexts」メソッドを用いて設定します。

mRequestObserver = mApi.streamingRecognize(mResponseObserver);
mRequestObserver.onNext(StreamingRecognizeRequest.newBuilder()
  .setStreamingConfig(StreamingRecognitionConfig.newBuilder()
    .setConfig(RecognitionConfig.newBuilder(
        .setLanguageCode(getDefaultLanguageCode())
        .setEncoding(RecognitionConfig.AudioEncoding.LINEAR16)
        .setSampleRateHertz(sampleRate)
        .addSpeechContexts(
          SpeechContext.newBuilder().addPhrases("校歌").build()) // ヒント設定
        .build())
    .setInterimResults(true)
    .setSingleUtterance(true)
    .build())
  .build());

この設定を入れる前は、「コウカ ヲ オシエテクダサイ」という発話に対して、以下のように認識されます。
 
  f:id:IntelligentTechnology:20170508212509p:plain:w360

 
「校歌」のヒント設定を入れた後は、以下のように認識されるようになりました。(2回試したため、出力も2回分になってます。)
 
  f:id:IntelligentTechnology:20170508212549p:plain:w360
 
この機能は、専門用語を多用する分野での利用、また上記のように、同音異義語をうまく使い分けたい、という場合など、使い方によっては、けっこう強力なものになるのではないかと思いました。

まとめ

たとえば iOS などでも、iOS10 以降の環境用に、同じような Speech Recognition API が提供されたりしています。
モバイルデバイスとのインタフェースとして「音声」というものが注目されている中、この Speech API も、無視できない存在になるのだろう、と感じました。