話者ベクトルをhttps://github.com/speechbrain/speechbrain.gitで取得してみます。
話者ベクトルの計算にはEncoderClassifier.encode_batchを使います。サンプリング周波数16kHzの音声データをこの関数に入力すると話者ベクトルが得られます。 それ以外の部分は音声の読み込みとt-SNEによる2Dベクトル化、散布図描画のための色の選択と、散布図の作成をしているだけです。 35行目でEncoderClassifierを作成して、52行目で話者ベクトルを取得します。 audio-16k.listは1行ごとに.wavファイルへのパスが書かれていることを想定しています。1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | import sys
from collections import defaultdict
import numpy as np
import matplotlib.pyplot as plt
from sklearn.manifold import TSNE
import torchaudio
sys.path.append("speechbrain")
from speechbrain.inference import EncoderClassifier
def make_colormap(label_list, min_count):
color_map = defaultdict(int)
for label in label_list:
color_map[label] += 1
color_map_sorted = []
for k, v in color_map.items():
color_map_sorted.append((v, k))
color_map_sorted = reversed(sorted(color_map_sorted))
colors = ["b", "g", "r", "c", "m", "y", "k", "C0", "C1", "C2", "C3", "C4", "C5", "C6", "C7", "C8", "C9"]
cindex = 0
for v, k in color_map_sorted:
if v < min_count:
color_map[k] = None
continue
color_map[k] = colors[cindex] if cindex < len(colors) else "grey"
cindex += 1
color_list = []
for i in range(len(label_list)):
color_list.append(color_map[label_list[i]])
return color_list
def main(wav_list):
ec = EncoderClassifier.from_hparams(
source="speechbrain/spkrec-ecapa-voxceleb",
savedir="cache",
run_opts={"device": "cuda"},
use_auth_token=False
)
ec.hparams.label_encoder.ignore_len()
embed_list = []
label_list = []
with open(wav_list) as wavs:
i = 0
for line in wavs:
i += 1
line = line.strip()
signal, fs = torchaudio.load(line)
assert fs == 16000
# Get a speaker vector
embed_list.append(ec.encode_batch(signal, wav_lens=None).squeeze(dim=1).cpu().numpy())
label_list.append(line.split("/")[1].split("_")[0]) # Get speaker name
if i % 100 == 0:
print(i)
label_list = make_colormap(label_list, min_count=100)
# Filter speaker vectors
embed_list = [embed_list[i] for i in range(len(label_list)) if label_list[i] is not None]
label_list = [label_list[i] for i in range(len(label_list)) if label_list[i] is not None]
embed_list = np.concatenate(embed_list)
tsne = TSNE(n_components=2, random_state=123)
vec_2d = tsne.fit_transform(embed_list)
plt.figure(figsize=(10, 8))
plt.scatter(vec_2d[:,0], vec_2d[:,1], alpha=0.7, c=label_list)
plt.title("t-SNE visualization of speaker vectors")
plt.xlabel("t-SNE feature 1")
plt.ylabel("t-SNE feature 2")
plt.grid(True, linestyle="--", alpha=0.7)
plt.savefig("spk_distribution.png", dpi=300, bbox_inches="tight")
plt.close()
if __name__ == "__main__":
main("audio-16k.list")
|