ProSDD-ASV19 / subset_eer.py
korallll's picture
Wrapper code (speech-spoof-bench)
22aafa1 verified
Raw History Blame Contribute Delete
1.45 kB
# subset_eer.py [N] -- quick EER on a fixed random ASVspoof2019_LA eval subset:
# N rows sampled uniformly without replacement (seed 0) from shard 0. Cheap sanity vs the paper's ASV19 EER.
import io, os, sys
import numpy as np, pyarrow.parquet as pq, soundfile as sf
HERE = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, HERE)
mod = __import__([m for m in ("prosdd_asv19", "prosdd_asv5") if os.path.exists(os.path.join(HERE, m + ".py"))][0])
Cls = getattr(mod, [n for n in dir(mod) if n.startswith("ProSDDASV")][0])
N = int(sys.argv[1]) if len(sys.argv) > 1 else 2000
t = pq.read_table(os.path.join(HERE, "..", "ASVspoof2019_LA", "data", "test-00000-of-00009.parquet"), columns=["audio", "label"])
idx = np.sort(np.random.default_rng(0).choice(t.num_rows, N, replace=False))
t = t.take(idx).to_pylist()
m = Cls(); m.load()
scores, labels = [], []
B = 16
for k in range(0, len(t), B):
rows = t[k:k + B]
scores += m.score_batch([sf.read(io.BytesIO(r["audio"]["bytes"]), dtype="float32")[0] for r in rows], [16000] * len(rows))
labels += [r["label"] for r in rows]
s, y = np.array(scores), np.array(labels)
bona, spoof = s[y == 0], s[y == 1]
th = np.sort(s)
frr = np.array([(bona < x).mean() for x in th]); far = np.array([(spoof >= x).mean() for x in th])
i = np.argmin(np.abs(frr - far))
print(f"{Cls.__name__} ASVspoof2019_LA subset n={len(s)} bona={len(bona)} spoof={len(spoof)} EER~{100 * (frr[i] + far[i]) / 2:.3f}%")