Android 用の音声と単語の認識

このチュートリアルでは、事前に構築された機械学習モデルで TensorFlow Lite を使用し、Android アプリで音声や話し言葉を認識する方法を説明します。このチュートリアルで示したような音声分類モデルは、アクティビティの検出、アクションの識別、または音声コマンドの認識に使用できます。

音声認識のアニメーションデモこのチュートリアルでは、サンプル コードをダウンロードし、プロジェクトをAndroid Studioにロードする方法を示し、コード サンプルの重要な部分を説明して、この機能を独自のアプリに追加できるようにします。サンプル アプリ コードでは、オーディオ データの記録と前処理の大部分を処理する TensorFlow Task Library for Audioを使用します。機械学習モデルで使用するために音声を前処理する方法の詳細については、 「 音声データの準備と拡張 」を参照してください。

機械学習による音声分類

このチュートリアルの機械学習モデルは、Android デバイスのマイクで録音されたオーディオ サンプルから音または単語を認識します。このチュートリアルのサンプル アプリでは、音を認識するモデルであるYAMNet/classifierと、TensorFlow Lite Model Makerツールを使用してトレーニングされた特定の話し言葉を認識するモデルを切り替えることができます。モデルは、クリップごとに 15600 の個別のサンプルを含み、長さが約 1 秒のオーディオ クリップに対して予測を実行します。

セットアップと実行の例

このチュートリアルの最初の部分では、GitHub からサンプルをダウンロードし、Android Studio を使用して実行します。このチュートリアルの次のセクションでは、例の関連セクションを検討して、それらを独自の Android アプリに適用できるようにします。

システム要求

  • Android Studioバージョン 2021.1.1 (Bumblebee) 以降。
  • Android SDK バージョン 31 以降
  • 開発者モードが有効になっている、SDK 24 (Android 7.0 - Nougat) の最小 OS バージョンを搭載した Android デバイス。

サンプルコードを入手する

サンプル コードのローカル コピーを作成します。このコードを使用して Android Studio でプロジェクトを作成し、サンプル アプリケーションを実行します。

サンプルコードを複製してセットアップするには、次のようにします。

  1. git リポジトリ
    git clone https://github.com/tensorflow/examples.git
    
    のクローンを作成します
  2. 必要に応じて、スパース チェックアウトを使用するように git インスタンスを構成して、サンプル アプリのファイルのみを用意します。

    cd examples
    git sparse-checkout init --cone
    git sparse-checkout set lite/examples/audio_classification/android
    

プロジェクトをインポートして実行する

ダウンロードしたサンプル コードからプロジェクトを作成し、プロジェクトをビルドして実行します。

サンプル コード プロジェクトをインポートしてビルドするには:

  1. Android Studioを起動します。
  2. Android Studio で、 [ファイル] > [新規作成] > [プロジェクトのインポート]を選択します。
  3. build.gradleファイルを含むサンプル コード ディレクトリ ( .../examples/lite/examples/audio_classification/android/build.gradle ) に移動し、そのディレクトリを選択します。

正しいディレクトリを選択すると、Android Studio は新しいプロジェクトを作成してビルドします。コンピューターの速度や、他のプロジェクトで Android Studio を使用しているかどうかによっては、このプロセスに数分かかる場合があります。ビルドが完了すると、Android Studio の[ビルド出力ステータス] パネルにBUILD SUCCESSFULメッセージが表示されます。

プロジェクトを実行するには:

  1. Android Studio から、 [実行] > ['app' を実行]を選択してプロジェクトを実行します。
  2. アプリをテストするには、マイクが接続されている Android デバイスを選択します。

次のセクションでは、このサンプル アプリを参照ポイントとして使用して、この機能を独自のアプリに追加するために既存のプロジェクトに加える必要がある変更を示します。

プロジェクトの依存関係を追加する

独自のアプリケーションでは、TensorFlow Lite 機械学習モデルを実行するための特定のプロジェクト依存関係を追加し、オーディオなどの標準データ形式を、使用しているモデルで処理できる tensor データ形式に変換するユーティリティ関数にアクセスする必要があります。

サンプル アプリでは、次の TensorFlow Lite ライブラリを使用します。

次の手順では、必要なプロジェクトの依存関係を独自の Android アプリ プロジェクトに追加する方法を示します。

モジュールの依存関係を追加するには:

  1. TensorFlow Lite を使用するモジュールで、モジュールのbuild.gradleファイルを更新して、次の依存関係を含めます。コード例では、このファイルは次の場所にあります: .../examples/lite/examples/audio_classification/android/build.gradle

    dependencies {
    ...
        implementation 'org.tensorflow:tensorflow-lite-task-audio'
    }
    
  2. Android Studio で、 [ファイル] > [プロジェクトを Gradle ファイルと同期]を選択して、プロジェクトの依存関係を同期します。

ML モデルを初期化する

Android アプリでは、モデルで予測を実行する前に、パラメーターを使用して TensorFlow Lite 機械学習モデルを初期化する必要があります。これらの初期化パラメーターはモデルに依存しており、モデルが認識できる単語や音の予測やラベルのデフォルトの最小精度しきい値などの設定を含めることができます。

TensorFlow Lite モデルには、モデルを含む*.tfliteファイルが含まれています。モデル ファイルには予測ロジックが含まれており、通常は予測クラス名など、予測結果の解釈方法に関するメタデータが含まれています。コード例にあるように、モデル ファイルは開発プロジェクトのsrc/main/assetsディレクトリに保存する必要があります。

  • <project>/src/main/assets/yamnet.tflite

利便性とコードの読みやすさを考慮して、この例ではモデルの設定を定義するコンパニオン オブジェクトを宣言しています。

アプリでモデルを初期化するには:

  1. コンパニオン オブジェクトを作成してモデルの設定を定義します。

    companion object {
      const val DISPLAY_THRESHOLD = 0.3f
      const val DEFAULT_NUM_OF_RESULTS = 2
      const val DEFAULT_OVERLAP_VALUE = 0.5f
      const val YAMNET_MODEL = "yamnet.tflite"
      const val SPEECH_COMMAND_MODEL = "speech.tflite"
    }
    
  2. AudioClassifier.AudioClassifierOptionsオブジェクトを構築して、モデルの設定を作成します。

    val options = AudioClassifier.AudioClassifierOptions.builder()
      .setScoreThreshold(classificationThreshold)
      .setMaxResults(numOfResults)
      .setBaseOptions(baseOptionsBuilder.build())
      .build()
    
  3. この設定オブジェクトを使用して、モデルを含む TensorFlow Lite AudioClassifierオブジェクトを構築します。

    classifier = AudioClassifier.createFromFileAndOptions(context, "yamnet.tflite", options)
    

ハードウェアアクセラレーションを有効にします

アプリで TensorFlow Lite モデルを初期化するときは、モデルの予測計算を高速化するためにハードウェア アクセラレーション機能の使用を検討する必要があります。 TensorFlow Liteデリゲートは、グラフィックス プロセッシング ユニット (GPU) やテンソル プロセッシング ユニット (TPU) など、モバイル デバイス上の特殊な処理ハードウェアを使用して機械学習モデルの実行を高速化するソフトウェア モジュールです。コード例では、NNAPI デリゲートを使用して、モデル実行のハードウェア アクセラレーションを処理します。

val baseOptionsBuilder = BaseOptions.builder()
   .setNumThreads(numThreads)
...
when (currentDelegate) {
   DELEGATE_CPU -> {
       // Default
   }
   DELEGATE_NNAPI -> {
       baseOptionsBuilder.useNnapi()
   }
}

TensorFlow Lite モデルの実行にはデリゲートを使用することが推奨されますが、必須ではありません。 TensorFlow Lite でのデリゲートの使用の詳細については、 「TensorFlow Lite デリゲート」を参照してください。

モデルのデータを準備する

Android アプリでは、コードはオーディオ クリップなどの既存のデータをモデルで処理できるTensorデータ形式に変換することにより、解釈用のデータをモデルに提供します。モデルに渡す Tensor 内のデータは、モデルのトレーニングに使用されるデータの形式と一致する特定の次元または形状を持っている必要があります。

このコード例で使用されるYAMNet/分類子モデルとカスタマイズされた音声コマンドモデルは、16kHz で 0.975 秒のクリップ (15600 サンプル) に記録されたシングル チャネルまたはモノラルのオーディオ クリップを表す Tensor データ オブジェクトを受け入れます。新しいオーディオ データに対して予測を実行する場合、アプリはそのオーディオ データをそのサイズと形状の Tensor データ オブジェクトに変換する必要があります。 TensorFlow Lite タスク ライブラリオーディオ API は、データ変換を処理します。

サンプルコードAudioClassificationHelperクラスでは、アプリは Android AudioRecordオブジェクトを使用してデバイスのマイクからライブオーディオを録音します。このコードは、 AudioClassifierを使用して、モデルに適切なサンプリング レートでオーディオを録音するオブジェクトを構築および構成します。このコードでは、AudioClassifier を使用してTensorAudioオブジェクトを構築し、変換されたオーディオ データを保存します。次に、TensorAudio オブジェクトが分析のためにモデルに渡されます。

音声データを ML モデルに提供するには:

  • AudioClassifierオブジェクトを使用して、 TensorAudioオブジェクトとAudioRecordオブジェクトを作成します。

    fun initClassifier() {
    ...
      try {
        classifier = AudioClassifier.createFromFileAndOptions(context, currentModel, options)
        // create audio input objects
        tensorAudio = classifier.createInputTensorAudio()
        recorder = classifier.createAudioRecord()
      }
    

予測を実行する

Android アプリで、 AudioRecordオブジェクトとTensorAudioオブジェクトを AudioClassifier オブジェクトに接続すると、そのデータに対してモデルを実行して、予測または推論を生成できます。このチュートリアルのサンプル コードは、ライブ録音されたオーディオ入力ストリームからのクリップに対して特定のレートで予測を実行します。

モデルの実行は大量のリソースを消費するため、ML モデル予測を別のバックグラウンド スレッドで実行することが重要です。サンプル アプリでは、 [ScheduledThreadPoolExecutor](https://developer.android.com/reference/java/util/concurrent/ScheduledThreadPoolExecutor)オブジェクトを使用して、モデルの処理をアプリの他の機能から分離します。

単語など、始まりと終わりが明確な音を認識するオーディオ分類モデルは、重複するオーディオ クリップを分析することで、受信オーディオ ストリームに対してより正確な予測を生成できます。このアプローチは、モデルがクリップの最後で切り取られた単語の予測の欠落を回避するのに役立ちます。サンプル アプリでは、予測を実行するたびに、コードがオーディオ録音バッファから最新の 0.975 秒のクリップを取得して分析します。モデル分析スレッドの実行プールinterval値を、分析対象のクリップの長さよりも短い長さに設定することで、モデルが重複するオーディオ クリップを分析できるようにすることができます。たとえば、モデルが 1 秒のクリップを分析し、間隔を 500 ミリ秒に設定した場合、モデルは毎回前のクリップの後半と 500 ミリ秒の新しいオーディオ データを分析し、クリップ分析の 50% の重複が作成されます。

音声データの予測の実行を開始するには:

  1. AudioClassificationHelper.startAudioClassification()メソッドを使用して、モデルのオーディオ録音を開始します。

    fun startAudioClassification() {
      if (recorder.recordingState == AudioRecord.RECORDSTATE_RECORDING) {
        return
      }
      recorder.startRecording()
    }
    
  2. ScheduledThreadPoolExecutorオブジェクトで固定レートintervalを設定することにより、モデルがオーディオ クリップから推論を生成する頻度を設定します。

    executor = ScheduledThreadPoolExecutor(1)
    executor.scheduleAtFixedRate(
      classifyRunnable,
      0,
      interval,
      TimeUnit.MILLISECONDS)
    
  3. 上記のコードのclassifyRunnableオブジェクトは、 AudioClassificationHelper.classifyAudio()メソッドを実行します。これにより、利用可能な最新のオーディオデータがレコーダーからロードされ、予測が実行されます。

    private fun classifyAudio() {
      tensorAudio.load(recorder)
      val output = classifier.classify(tensorAudio)
      ...
    }
    

予測処理を停止する

アプリの音声処理フラグメントまたはアクティビティがフォーカスを失ったときに、アプリ コードが音声分類を停止するようにしてください。機械学習モデルを継続的に実行すると、Android デバイスのバッテリー寿命に大きな影響を与えます。音声の録音と予測処理を停止するには、音声分類に関連付けられた Android アクティビティまたはフラグメントのonPause()メソッドを使用します。

音声の録音と分類を停止するには:

  • 以下のAudioFragmentクラスに示すようにAudioClassificationHelper.stopAudioClassification()メソッドを使用して録音とモデルの実行を停止します。

    override fun onPause() {
      super.onPause()
      if (::audioHelper.isInitialized ) {
        audioHelper.stopAudioClassification()
      }
    }
    

モデル出力を処理します

Android アプリでは、オーディオ クリップを処理した後、追加のビジネス ロジックの実行、ユーザーへの結果の表示、またはその他のアクションの実行によってアプリ コードが処理する必要がある予測のリストがモデルによって生成されます。特定の TensorFlow Lite モデルの出力は、生成される予測の数 (1 つまたは複数)、および各予測の説明情報によって異なります。サンプル アプリのモデルの場合、予測は認識された音または単語のリストです。コード例で使用されている AudioClassifier オプション オブジェクトを使用すると、「ML モデルの初期化」セクションに示すように、 setMaxResults()メソッドで予測の最大数を設定できます。

モデルから予測結果を取得するには:

  1. AudioClassifierオブジェクトのclassify()メソッドの結果を取得し、リスナー オブジェクトに渡します (コード リファレンス)。

    private fun classifyAudio() {
      ...
      val output = classifier.classify(tensorAudio)
      listener.onResult(output[0].categories, inferenceTime)
    }
    
  2. リスナーの onResult() 関数を使用して、ビジネス ロジックを実行するか、結果をユーザーに表示することで出力を処理します。

    private val audioClassificationListener = object : AudioClassificationListener {
      override fun onResult(results: List<Category>, inferenceTime: Long) {
        requireActivity().runOnUiThread {
          adapter.categoryList = results
          adapter.notifyDataSetChanged()
          fragmentAudioBinding.bottomSheetLayout.inferenceTimeVal.text =
            String.format("%d ms", inferenceTime)
        }
      }
    

この例で使用されるモデルは、分類された音または単語のラベルを含む予測のリストと、予測の信頼度を表す Float として 0 から 1 までの予測スコア (1 が最も高い信頼度評価) を生成します。一般に、スコアが 50% (0.5) を下回る予測は決定的ではないと考えられます。ただし、値の低い予測結果をどのように処理するかは、アプリケーションのニーズとユーザー次第です。

モデルが一連の予測結果を返したら、アプリケーションは結果をユーザーに提示するか、追加のロジックを実行することで、それらの予測に基づいて動作できます。コード例の場合、アプリケーションは、識別された音または単語をアプリのユーザー インターフェイスにリストします。

次のステップ

オーディオ処理用の追加の TensorFlow Lite モデルは、 TensorFlow Hubおよび事前トレーニング済みモデルのガイドページから見つけることができます。 TensorFlow Lite を使用してモバイル アプリケーションに機械学習を実装する方法の詳細については、 「 TensorFlow Lite 開発者ガイド 」を参照してください。