日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人工智能 > pytorch >内容正文

pytorch

人脸识别相似度计算方法

發布時間:2023/12/20 pytorch 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 人脸识别相似度计算方法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在人臉識別中,我們通常采用歐氏距離和余弦距離來衡量人臉特征的相似度,判別是否為同一個人。

歐氏距離

歐氏距離比較簡單,采用歐氏公式直接計算兩個點之間的距離,如下:

代碼:

diff = np.subtract(feature1, feature2) dist = np.sqrt(np.sum(np.square(diff)))

feature1.shape 和feature2.shape 為(n, )

?

余弦距離

余弦距離,也稱為余弦相似度,是用向量空間中兩個向量夾角的余弦值作為衡量兩個個體間差異的大小的度量。

當兩個向量直接的夾角趨向0時,兩個向量越接近,差異就越小。此時?= 1,即越接近1值時,說明人臉越相似。

代碼:

dot = np.sum(np.multiply(feature1, feature2), axis=1) norm = np.linalg.norm(feature1, axis=1) * np.linalg.norm(feature2, axis=1) dist = dot / norm

?

區別

歐氏距離計算的是空間中兩個點的絕對距離,距離dist越小,特征越相似;

余弦距離衡量的是空間中兩個向量的夾角,夾角越靠近0,即dist越接近1,特征越相似。

?

閾值選取

以下是一段摘自facenet 的代碼:

def distance(embeddings1, embeddings2, distance_metric=0):if distance_metric==0:# Euclidian distancediff = np.subtract(embeddings1, embeddings2)dist = np.sum(np.square(diff),1)elif distance_metric==1:# Distance based on cosine similaritydot = np.sum(np.multiply(embeddings1, embeddings2), axis=1)norm = np.linalg.norm(embeddings1, axis=1) * np.linalg.norm(embeddings2, axis=1)similarity = dot / normdist = np.arccos(similarity) / math.pielse:raise 'Undefined distance metric %d' % distance_metric return distdef calculate_roc(thresholds, embeddings1, embeddings2, actual_issame, nrof_folds=10, distance_metric=0, subtract_mean=False):assert(embeddings1.shape[0] == embeddings2.shape[0])assert(embeddings1.shape[1] == embeddings2.shape[1])nrof_pairs = min(len(actual_issame), embeddings1.shape[0])nrof_thresholds = len(thresholds)k_fold = KFold(n_splits=nrof_folds, shuffle=False)tprs = np.zeros((nrof_folds,nrof_thresholds))fprs = np.zeros((nrof_folds,nrof_thresholds))accuracy = np.zeros((nrof_folds))indices = np.arange(nrof_pairs)for fold_idx, (train_set, test_set) in enumerate(k_fold.split(indices)):if subtract_mean:mean = np.mean(np.concatenate([embeddings1[train_set], embeddings2[train_set]]), axis=0)else:mean = 0.0dist = distance(embeddings1-mean, embeddings2-mean, distance_metric)# Find the best threshold for the foldacc_train = np.zeros((nrof_thresholds))for threshold_idx, threshold in enumerate(thresholds):_, _, acc_train[threshold_idx] = calculate_accuracy(threshold, dist[train_set], actual_issame[train_set])best_threshold_index = np.argmax(acc_train)for threshold_idx, threshold in enumerate(thresholds):tprs[fold_idx,threshold_idx], fprs[fold_idx,threshold_idx], _ = calculate_accuracy(threshold, dist[test_set], actual_issame[test_set])_, _, accuracy[fold_idx] = calculate_accuracy(thresholds[best_threshold_index], dist[test_set], actual_issame[test_set])tpr = np.mean(tprs,0)fpr = np.mean(fprs,0)return tpr, fpr, accuracydef calculate_accuracy(threshold, dist, actual_issame):predict_issame = np.less(dist, threshold)tp = np.sum(np.logical_and(predict_issame, actual_issame))fp = np.sum(np.logical_and(predict_issame, np.logical_not(actual_issame)))tn = np.sum(np.logical_and(np.logical_not(predict_issame), np.logical_not(actual_issame)))fn = np.sum(np.logical_and(np.logical_not(predict_issame), actual_issame))tpr = 0 if (tp+fn==0) else float(tp) / float(tp+fn)fpr = 0 if (fp+tn==0) else float(fp) / float(fp+tn)acc = float(tp+tn)/dist.sizereturn tpr, fpr, acc def evaluate(embeddings, actual_issame, nrof_folds=10, distance_metric=0, subtract_mean=False):# Calculate evaluation metricsthresholds = np.arange(0, 4, 0.01)embeddings1 = embeddings[0::2]embeddings2 = embeddings[1::2]tpr, fpr, accuracy = facenet.calculate_roc(thresholds, embeddings1, embeddings2,np.asarray(actual_issame), nrof_folds=nrof_folds, distance_metric=distance_metric, subtract_mean=subtract_mean)thresholds = np.arange(0, 4, 0.001)val, val_std, far = facenet.calculate_val(thresholds, embeddings1, embeddings2,np.asarray(actual_issame), 1e-3, nrof_folds=nrof_folds, distance_metric=distance_metric, subtract_mean=subtract_mean)return tpr, fpr, accuracy, val, val_std, far

從上面的代碼,可以看到其實我們在實際的人臉識別中,可以對標準的歐氏距離和余弦距離做適當的放大,這樣在更有利于閾值的比較,更精準。那么閾值我們怎么選值呢?在上面第二段代碼中可以找到答案,可以看到最佳閾值是可以算出來的,代碼 thresholds = np.arange(0, 4, 0.001) ,最佳閾值在(0, 4)之間進行查找,在acc_train 最高時的threshold來當中最佳閾值。

diff = np.subtract(embeddings1, embeddings2) dist = np.sum(np.square(diff),1)

通過跑LFW數據集測試,facenet算法下,歐氏距離經過上面兩個語句變形后的最佳閾值為1.21;在arcface算法,mobilefacenet模型下自己閾值為1.45,可見在選取閾值的時候要根據自己的model來計算一下才合適。

?


更新:2020.11.6

關于歐氏距離怎么轉換為百分比的問題

我們在百度等AI開放平臺會看到人臉相似度是一個百分比,我們要怎么把歐氏轉換為百分比呢,今天就說一下自己的思路。

首先我們想到的是sigmoid函數,這個函數y的范圍是(0, 1),對應的百分比范圍0%~100%,我們同樣可以通過sigmoid函數的變形來實現映射。

通過上面的式子實現百分比的計算,我們只需要計算參數,就可以計算百分比了。

計算方法:我們在驗證集里面跑一下,把歐氏距離最大的值x1記錄下來,此時設定一個該值對應最大百分比(比如95%),然后在把歐氏距離最小的值x2也記錄下來,對應最小百分比(比如5%),然后把x1, x2代入上式子,就可以算出,?的值。

?


參考:

https://blog.csdn.net/liunian920305/article/details/73456736

https://blog.csdn.net/u014657795/article/details/85850891

https://www.zhihu.com/question/312564645?rf=403423583

?

總結

以上是生活随笔為你收集整理的人脸识别相似度计算方法的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。