python 繪製聲紋識別DET曲線

2021-10-01 18:21:21 字數 3863 閱讀 5459

import matplotlib.pyplot as plt

from sklearn.metrics import roc_curve

from scipy.stats import norm

import numpy as np

def plot_det_curve():

# 設定刻度範圍

pmiss_min = 0.001

pmiss_max = 0.6

pfa_min = 0.001

pfa_max = 0.6

# 刻度設定

pticks = [0.00001, 0.00002, 0.00005, 0.0001, 0.0002, 0.0005,

0.001, 0.002, 0.005, 0.01, 0.02, 0.05,

0.1, 0.2, 0.4, 0.6, 0.8, 0.9,

0.95, 0.98, 0.99, 0.995, 0.998, 0.999,

0.9995, 0.9998, 0.9999, 0.99995, 0.99998, 0.99999]

# 刻度*100

xlabels = [' 0.001', ' 0.002', ' 0.005', ' 0.01 ', ' 0.02 ', ' 0.05 ',

' 0.1 ', ' 0.2 ', ' 0.5 ', ' 1 ', ' 2 ', ' 5 ',

' 10 ', ' 20 ', ' 40 ', ' 60 ', ' 80 ', ' 90 ',

' 95 ', ' 98 ', ' 99 ', ' 99.5 ', ' 99.8 ', ' 99.9 ',

' 99.95', ' 99.98', ' 99.99', '99.995', '99.998', '99.999']

ylabels = xlabels

# 確定刻度範圍

n = len(pticks)

# 倒敘

for k, v in enumerate(pticks[::-1]):

if pmiss_min <= v:

tmin_miss = n - k - 1 # 移動最小值索引位置

if pfa_min <= v:

tmin_fa = n - k - 1 # 移動最小值索引位置

# 正序

for k, v in enumerate(pticks):

if pmiss_max >= v:

tmax_miss = k+1 # 移動最大值索引位置

if pfa_max >= v:

tmax_fa = k+1 # 移動最大值索引位置

# frr

plt.figure()

plt.xlim(norm.ppf(pfa_min), norm.ppf(pfa_max))

plt.xticks(norm.ppf(pticks[tmin_fa:tmax_fa]), xlabels[tmin_fa:tmax_fa])

plt.xlabel('false alarm probability (in %)')

# far

plt.ylim(norm.ppf(pmiss_min), norm.ppf(pmiss_max))

plt.yticks(norm.ppf(pticks[tmin_miss:tmax_miss]), ylabels[tmin_miss:tmax_miss])

plt.ylabel('miss probability (in %)')

return plt

# 計算eer

def compute_eer(frr,far):

threshold_index = np.argmin(abs(frr - far)) # 平衡點

eer = (frr[threshold_index]+far[threshold_index])/2

print("eer=",eer)

return eer

# 計算mindcf p_miss = frr p_fa = far

def compute_mindcf2(p_miss,p_fa):

c_miss = c_fa = 1

p_true = 0.01

p_false = 1-p_true

npts = len(p_miss)

if npts != len(p_fa):

print("error,size of pmiss is not euqal to pfa")

dcf = c_miss * p_miss * p_true + c_fa * p_fa*p_false

min_dcf = min(dcf)

print("min_dcf_2=",min_dcf)

return min_dcf

# 計算mindcf p_miss = frr p_fa = far

def compute_mindcf3(p_miss,p_fa,min_dcf_2):

c_miss = c_fa = 1

p_true = 0.001

p_false = 1-p_true

npts = len(p_miss)

if npts != len(p_fa):

print("error,size of pmiss is not euqal to pfa")

dcf = c_miss * p_miss * p_true + c_fa * p_fa*p_false

# 該操作是我自己加的,因為**中的dcf10-3指標均大於dcf10-2且高於0.1以上,所以通過這個來過濾一下,錯誤請指正

min_dcf = 1

for dcf in dcf:

if dcf > min_dcf_2+0.1 and dcf < min_dcf:

min_dcf = dcf

print("min_dcf_3=",min_dcf)

return min_dcf

if __name__ == "__main__":

# 讀檔案獲取y_true和y_score

y_true = np.load('./dataset/y_true.npy')

y_score = np.load('./dataset/y_pre.npy')

# 計算far和frr

fpr, tpr, thres = roc_curve(y_true, y_score)

frr = 1 - tpr

far = fpr

frr[frr <= 0] = 1e-5

far[far <= 0] = 1e-5

frr[frr >= 1] = 1-1e-5

far[far >= 1] = 1-1e-5

# 畫圖

plt = plot_det_curve()

x, y = norm.ppf(frr), norm.ppf(far)

plt.plot(x, y)

plt.plot([-40, 1], [-40, 1])

# plt.plot(np.arange(0,40,1),np.arange(0,40,1))

plt.show()

eer = compute_eer(frr,far)

min_dcf_2 = compute_mindcf2(frr*100,far*100)

min_dcf_3 = compute_mindcf3(frr*100,far*100,min_dcf_2)

效果圖:

聲紋識別調研

聲紋 voiceprint 是用電聲學儀器顯示的攜帶言語資訊的聲波頻譜。現代科學研究表明,聲紋不僅具有特定性,而且有相對穩定性的特點。成年以後,人的聲音可保持長期相對穩定不變。實驗證明,無論講話者是故意模仿他人聲音和語氣,還是耳語輕聲講話,即使模仿得惟妙惟肖,其聲紋卻始終不相同。聲紋識別的主要任務包...

d vector聲紋識別基礎

dnn訓練好後,提取每一幀語音的filterbank energy 特徵作為dnn輸入,從last hidden layer提取activations,l2正則化,然後將其累加起來,得到的向量就被稱為d vector。如果乙個人有多條enroll語音,那麼所有這些d vectors做平均,就是這個人...

聲紋識別概述(2)聲紋識別原理和過程

多看 聲紋識別技術簡介 化繁為簡的藝術,深入淺出了解聲紋識別。1 困難在哪?不同的人說話語音波形不同,但是相同的人用不同的語調或者在不同的身體狀態下說話其語音波形也不同,還有相同的人說不同的內容波形也不同 那要如何區分出是兩個不同人的語音?2 為什麼可識別?語音具備了乙個良好的性質,稱為短時平穩,在...