Open3
音声の類似度を測定する方法を調べる
WavLMが使えそう
Speaker Verification, 話者認識として
2つの音声からベクトルを取得し
コサイン類似度をとるまでのサンプルコードあり
まずは如実にサンプルを動かして諸々の型を確認
ライブラリをインストール
pip install transformers datasets torch
最後の行に以下を加えて実行
print(similarity)
Tensor型でかえってきた
tensor(0.9746, grad_fn=<SumBackward1>)
英語で同一の話者の場合、かなり高い数値になるようす
任意の2つの音声ファイルを使って類似度をかえす関数を目指す
Wav2Vec2FeatureExtractorはnp.ndarrayを受け取っていたので
音声ファイルはlibrosaで読み込んでみる
追加でインストール
pip install librosa
WavLMの都合上、16kHzにリサンプリングが必要なことに注意
from transformers import Wav2Vec2FeatureExtractor, WavLMForXVector
import torch
import librosa
model_name = "microsoft/wavlm-base-plus-sv"
feature_extractor = Wav2Vec2FeatureExtractor.from_pretrained(model_name)
model = WavLMForXVector.from_pretrained(model_name)
def get_audio_similarity(audio_path1, audio_path2) -> float:
target_sr = 16000
waveform1, sample_rate1 = librosa.load(audio_path1)
waveform1 = librosa.resample(waveform1, orig_sr=sample_rate1, target_sr=target_sr)
waveform2, sample_rate2 = librosa.load(audio_path2)
waveform2 = librosa.resample(waveform2, orig_sr=sample_rate2, target_sr=target_sr)
inputs = feature_extractor(
[waveform1, waveform2],
return_tensors="pt",
padding=True,
)
embeddings = model(**inputs).embeddings
embeddings = torch.nn.functional.normalize(embeddings, dim=-1).cpu()
cosine_sim = torch.nn.CosineSimilarity(dim=-1)
return cosine_sim(embeddings[0], embeddings[1]).item()
if __name__ == "__main__":
audio_path1 = "speaker1_1.wav"
audio_path2 = "speaker1_2.wav"
similarity = get_audio_similarity(audio_path1, audio_path2)
print(f"similarity : {similarity }")
いくつかのパターンを試した
同じ女性の話者だと0.8~0.9ぐらい
異なる女性の話者だと0.7前後、女性と男性で0.3前後など
音声の時間が短いと類似度も低くなっているようなので
厳密なシーンでは5秒以上の同じセリフを使ってきっちり比較すべきか
TTSで再現した音声ファイルを元の音声と比較した場合も0.9の値が得られたので
アーリーストッピングの基準として活用できそう