def cal_enroll_threshold(single_min_tpl: np.ndarray, eb_dba_tpl: np.ndarray, ls: np.ndarray, enrollment_signatures: list) -> (float, float, float, float): with util.my_timer('single min'): single_min_thresholds = [] for sig in enrollment_signatures: res = dtw.DTW(single_min_tpl, sig) single_min_thresholds.append(res) with util.my_timer('multi mean'): multi_mean_thresholds = [] for i, sig in enumerate(enrollment_signatures): res = tpl.get_multi_mean_dtw(enrollment_signatures[0:i] + enrollment_signatures[i: -1], sig) multi_mean_thresholds.append(res) with util.my_timer('eb-dba'): eb_dba_thresholds = [] for sig in enrollment_signatures: res = dtw.DTW(sig, eb_dba_tpl) eb_dba_thresholds.append(res) with util.my_timer('ls-dba'): ls_dba_thresholds = [] for sig in enrollment_signatures: res = dtw.DTW(sig, eb_dba_tpl, local_stability=ls) ls_dba_thresholds.append(res) return max(single_min_thresholds), max(multi_mean_thresholds), max(eb_dba_thresholds), max(ls_dba_thresholds)
def heatmap_DTW(read_fun, user_no: int, sig_num: int, verbose=False): """ example: pcolormesh_DTW(read_MMSIG, 1, 40) """ sig_array = [read_fun(user_no, i + 1).to_numpy() for i in range(sig_num)] dist_mesh = np.zeros((sig_num, sig_num)) with my_timer("pcolormesh_DTW..."): for sig in range(sig_num): for other_sig in range(sig + 1, sig_num): if (sig == other_sig): continue data1 = sig_array[sig] data2 = sig_array[other_sig] dist = dtw.DTW(data1, data2) dist_mesh[sig, other_sig] = dist if (verbose): print(f"sig: {sig}, other_sig: {other_sig}, DTW: {dist}") dist_mesh = dist_mesh + dist_mesh.T plt.title("DTW heatmap between signatures") plt.imshow(dist_mesh) plt.show()
def single_tpl_min_based_classify(read_fun, users_num: int, training: int, genuine: int, forged: int, penalty=0): if training <= 0 or genuine < training or forged < 0: raise Exception("args has error") sig_sum = genuine + forged # loading signature with util.my_timer("loading signature... "): users_data = [] for u in range(users_num): sig_arr = [ read_fun(u + 1, sig + 1).to_numpy() for sig in range(sig_sum) ] users_data.append(sig_arr) # shuffle true signatures for u in range(users_num): genuine_sig = users_data[u][:genuine] random.shuffle(genuine_sig) users_data[u] = genuine_sig + users_data[u][genuine:] # finding the signature has minimum DTW with others with util.my_timer("finding the signature has minimum DTW with others..."): single_tpls = [] for u in range(users_num): single_tpl = tpl.get_single_min_tpl(users_data[u][0:training], penalty) single_tpls.append(single_tpl) # testing with the minimum signature with util.my_timer("testing..."): DTW_test = np.zeros((users_num, sig_sum)) for u in range(users_num): for sig in range(training, sig_sum): DTW_test[u, sig] = dtw.DTW(users_data[u][sig], single_tpls[u]) with util.my_timer("calculate threshold..."): threshold_array = [] for u in range(users_num): threshold_array.append( util.get_single_min_threshold(single_tpls[u], users_data[u][0:training])) # calculate FAR, FRR, EER with util.my_timer("calculating EER... "): ERR = roc.user_dependent_ROC(users_num, training, genuine, forged, DTW_test) FAR, FRR = roc.user_thres_dependent_ROC(users_num, training, genuine, forged, DTW_test, threshold_array) ERR = roc.user_independent_ROC(users_num, training, genuine, forged, DTW_test, "single min based single template")
def get_ls_dba_tpl_threshold(eb_dba_tpl: np.ndarray, ls: np.ndarray, enrollment_signatures: list) -> float: ls_dba_thresholds = [] for sig in enrollment_signatures: res = dtw.DTW(sig, eb_dba_tpl, local_stability=ls) ls_dba_thresholds.append(res) # return mean_without_min_max(ls_dba_thresholds) # return max(ls_dba_thresholds) return personal_threshold(ls_dba_thresholds, delta=2.8)
def get_eb_dba_tpl_threshold(eb_dba_tpl: np.ndarray, enrollment_signatures: list) -> float: eb_dba_thresholds = [] for sig in enrollment_signatures: res = dtw.DTW(sig, eb_dba_tpl) eb_dba_thresholds.append(res) # return mean_without_min_max(eb_dba_thresholds) # return max(eb_dba_thresholds) return personal_threshold(eb_dba_thresholds, delta=2.8)
def LS_DBA_based_classify(read_fun, users_num: int, training: int, genuine: int, forged: int, times: int, penalty=0): if training <= 0 or genuine < training or forged < 0: raise Exception("args has error") sig_sum = genuine + forged # loading signature with util.my_timer("loading signature... "): users_data = [] for u in range(users_num): sig_arr = [read_fun(u + 1, sig + 1).to_numpy() for sig in range(sig_sum)] users_data.append(sig_arr) # shuffle true signatures for u in range(users_num): genuine_sig = users_data[u][:genuine] random.shuffle(genuine_sig) users_data[u] = genuine_sig + users_data[u][genuine:] # calculate the LS-DBA eb_dba_tpls = [] LS = [] with util.my_timer("calculating LS-DBA..."): for u in range(users_num): eb_dba_tpl, ls = tpl.get_ls_dba_tpl(users_data[u][0:training], times, penalty) eb_dba_tpls.append(eb_dba_tpl) LS.append(ls) # for u in range(users_num): # # util.plot_mean_template_with_train(eb_dba_tpls[u], users_data[u][:training]) # util.plot_mean_template_with_train_3D(eb_dba_tpls[u], users_data[u][:training]) # calculate DTW with the EB-DBA signature with util.my_timer("testing..."): DTW_test = np.zeros((users_num, sig_sum)) for u in range(users_num): for sig in range(training, sig_sum): DTW_test[u, sig] = dtw.DTW( users_data[u][sig], eb_dba_tpls[u], penalty=penalty, local_stability=LS[u]) with util.my_timer("calculate threshold..."): threshold_array = [] for u in range(users_num): threshold_array.append(util.get_ls_dba_tpl_threshold(eb_dba_tpls[u], LS[u], users_data[u][0:training])) # calculate FAR, FRR, EER with util.my_timer("calculating EER... "): ERR = roc.user_dependent_ROC(users_num, training, genuine, forged, DTW_test) FAR, FRR = roc.user_thres_dependent_ROC(users_num, training, genuine, forged, DTW_test, threshold_array) ERR = roc.user_independent_ROC(users_num, training, genuine, forged, DTW_test, "LS-DBA based single template")
def get_multi_mean_dtw(training_data: list, test_data: np.ndarray, penalty=0) -> float: train_num = len(training_data) DTW_result = np.zeros((train_num)) for other_sig in range(train_num): DTW_result[other_sig] = dtw.DTW(test_data, training_data[other_sig], penalty=penalty) return np.mean(DTW_result)
def get_single_min_tpl(training_data: list, penalty=0) -> np.ndarray: train_num = len(training_data) DTW_between = np.zeros((train_num, train_num)) for sig in range(train_num): for other_sig in range(sig + 1, train_num): DTW_between[sig, other_sig] = dtw.DTW(training_data[sig], training_data[other_sig], penalty=penalty) # 利用对称矩阵特性,节省DTW计算量 DTW_between = DTW_between + DTW_between.T min_idx = np.argmin(np.sum(DTW_between, axis=0)) return training_data[min_idx]