HuggingFaceのwav2vecで音声認識をしてみる

HuggingFaceのwav2vecで音声認識ができるようになったぞ

自然言語処理だけでなく音声認識もできるようになったんですね。

今回も少ないコードで動作確認できるので、音声認識のハードルが下がっているぞ

Wav2Vec

下記の論文で紹介された手法になります。

wav2vec 2.0: A Framework for Self-Supervised Learning of Speech Representations

https://arxiv.org/pdf/2006.11477.pdf

大きな特徴は事前学習とファインチューニングのフェーズに分かれており、事前学習ではラベルデータが必要ない。つまり音声データのみでOKという手法になります。

ラベルコストをさげて学習できる手法ということで有用な手法になります。

下記はモデルの図です。

ラベルなしの事前学習部分が重要なので、その部分にフォーカスして説明します。

  • 音声データを前処理せずにCNNに入力して、音声データを圧縮して量子化しています。
  • 量子化のモジュールではゆらぎを与えるためにギャンブルソフトマックスを採用して、固定的な値を出力しないようにしています。
  • 量子化された出力の一部をマスクします。
  • Transformer部(ContextNet)に量子化せずに入力して対象となる語彙に当てはめた出力を出す。Transformerについては下記記事をご覧ください

事前学習ではロスの設計が重要になってきます。

Contrastive Loss.とDiversity Lossで構成されています。

Contrastive Lossは量子化された出力とTransformerのマスクされた部分の出力をなるべく近づけようとするLossになります。

Diversity Lossは特定の出力に偏ることを抑えて、出力がなるべく等しくなるように設計されています。

下記にラベリングされたデータ・セットサイズごとの性能を示しています。

10分のラベリングされたデータの”test:clean”の性能がWERで4.8になっています。WERは低いほど良い性能です。Discrete BERTの性能16.3に比べるとかなり性能が改善されていることが分かります。

Wav2Vecの動作確認

コードの動作はGoogle Colabで確認しました。下記記事で環境構築方法を記述しています。

まずは必要なライブラリを導入します。

! pip install transformers datasets librosa

必要なライブラリをインポートします。

import librosa
import matplotlib.pyplot as plt
from IPython.display import display, Audio
import librosa.display
import numpy as np

import torch
from transformers import Wav2Vec2Processor, Wav2Vec2ForCTC
from datasets import load_dataset
import soundfile as sf

モデルと前処理を設定します。

processor = Wav2Vec2Processor.from_pretrained("facebook/wav2vec2-base-960h")
model = Wav2Vec2ForCTC.from_pretrained("facebook/wav2vec2-base-960h")

取得したデータから必要な部分を抽出する関数を設定します。

def map_to_array(batch):
    speech, sr_db = sf.read(batch["file"])
    batch["speech"] = speech
    batch['sr_db'] = sr_db
    return batch

librispeechで用意されているダミーデータを取得します。先程作成した関数を使用してこのデータから必要な部分を抽出します。

ds = load_dataset("patrickvonplaten/librispeech_asr_dummy", "clean", split="validation")
ds = ds.map(map_to_array)

取得した音声データを確認します。下記のコードでは音声波形の確認と音声を流して音声の内容を確認できます。

librosa.display.waveplot(np.array(ds['speech'][0]), sr=ds['sr_db'][0])
plt.show()
display(Audio(np.array(ds['speech'][0]), rate=ds['sr_db'][0]))

下記のコードで取得した音声を前処理して、Wav2Vecによって音声認識を行ってみます。

input_values = processor(ds["speech"][0], return_tensors="pt").input_values  # Batch size 1
logits = model(input_values).logits
predicted_ids = torch.argmax(logits, dim=-1)

transcription = processor.decode(predicted_ids[0])

transcription

認識結果は下記になります。著者が聞いた限り正しく認識できていました。

BECAUSE YOU ARE SLEEPING INSTEAD OF CONQUERING THE LOVELY ROSE PRINCESS HAS BECOME A FIDDLE WITHOUT A BAW WHILE POOR SHAGGY SITS THERE A COOING DOVE

少ないコードで音声認識できました!!

日本語対応するには学習からやり直す必要があるがラベリングされたデータが少なくて済む点は非常に価値がある手法だな

Close Bitnami banner
Bitnami