<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                # 六、相似性學習 在本章中,我們將學習相似性學習并學習相似性學習中使用的各種損失函數。 當每個類別的數據集都很小時,相似性學習對我們很有用。 我們將了解可用于人臉分析的不同數據集,并建立用于人臉識別,界標檢測的模型。 我們將在本章介紹以下主題: * 相似性學習的不同算法 * 用于相似度學習的各種損失函數 * 可以使用此類模型的各種方案 * 人臉識別的完整過程 # 相似性學習算法 **相似性學習**是訓練度量以計算兩個實體之間的相似性的過程。 由于學習了相似性,這也可以稱為度量學習。 度量可以是歐幾里得或余弦或其他自定義距離函數。 實體可以是任何數據,例如圖像,視頻,文本或表格。 為了計算度量,需要圖像的向量表示。 此表示可以是 CNN 計算的特征,如第 3 章,“圖像檢索”中所述。 為對象分類而學習的 CNN 可以用作計算度量的向量。 為圖像分類而獲得的特征向量將不是手頭任務的最佳表示。 在相似性學習中,我們發現有關 CNN 的信息,這些 CNN 會為相似性學習任務生成經過訓練的特征。 這里給出了相似性學習的一些應用: * 使用生物識別比較兩個人臉的人臉驗證 * 用于在線查找類似產品的現實世界中的對象的視覺搜索 * 某些屬性相似的產品的視覺推薦 在本章中,我們將詳細了解人臉驗證。 因此,讓我們從可用于相似性學習的算法開始。 # 連體網絡 顧名思義,連體網絡是一種神經網絡模型,其中訓練該網絡以區分兩個輸入。 連體網絡可以訓練 CNN,以通過兩個編碼器產生嵌入。 每個編碼器被饋送正對或負對中的一個圖像。 連體網絡所需的數據少于其他深度學習算法。 最初引入連體網絡來比較簽名。 下圖顯示了一個連體網絡。 權重在網絡之間共享: ![](https://img.kancloud.cn/b2/64/b264802ebf097af1a7fdab0b1478a2fb_566x172.png) 連體網絡的另一種用途是一次性學習。 **單次學習**是僅舉一個示例的學習技術。 在這種情況下,可以顯示圖像,并判斷它們是否相似。 對于大多數相似性學習任務,需要一對正負對進行訓練。 可以將此類數據集與可用于分類任務的任何數據集一起形成,前提是它們是歐幾里得距離。 這些算法與前幾章中的算法之間的主要區別在于,這些編碼器試圖將一個編碼器與另一個編碼器區分開。 # 對比損失 對比損失通過相似度區分圖像。 使用相似性度量比較特征或潛在層,并與目標一起訓練相似性得分。 在正對的情況下,目標將為 0,因為兩個輸入相同。 對于負數對,在余弦距離或正則歐幾里得距離的情況下,潛對之間的距離最大為 0。 損耗可以由`contrastive_loss`定義,在以下代碼中進行解釋: ```py def contrastive_loss(model_1, model_2, label, margin=0.1): distance = tf.reduce_sum(tf.square(model_1 - model_2), 1) loss = label * tf.square( tf.maximum(0., margin - tf.sqrt(distance))) + (1 - label) * distance loss = 0.5 * tf.reduce_mean(loss) return loss ``` 比較兩個模型的距離并計算損失。 現在,我們將定義和訓練一個連體網絡。 對于連體網絡,我們將需要兩個相同的模型。 接下來,借助以下代碼,為具有給定輸入的簡單 CNN 定義一個函數: ```py def get_model(input_): input_reshape = tf.reshape(input_, [-1, 28, 28, 1], name='input_reshape') convolution_layer_1 = convolution_layer(input_reshape, 64) pooling_layer_1 = pooling_layer(convolution_layer_1) convolution_layer_2 = convolution_layer(pooling_layer_1, 128) pooling_layer_2 = pooling_layer(convolution_layer_2) flattened_pool = tf.reshape(pooling_layer_2, [-1, 5 * 5 * 128], name='flattened_pool') dense_layer_bottleneck = dense_layer(flattened_pool, 1024) return dense_layer_bottleneck ``` 定義的模型將使用兩次來定義連體網絡所需的編碼器。 接下來,定義兩個模型的占位符。 對于每一對,輸入的相似性也作為輸入提供。 定義的模型相同。 還可以定義模型,以便共享權重。 此處定義了左右兩個模型: ```py left_input = tf.placeholder(tf.float32, shape=[None, input_size]) right_input = tf.placeholder(tf.float32, shape=[None, input_size]) y_input = tf.placeholder(tf.float32, shape=[None, no_classes]) left_bottleneck = get_model(left_input) right_bottleneck = get_model(right_input) ``` 瓶頸層是從模型中獲取的,并被連接在一起。 這對于相似性學習問題至關重要。 可以創建任意數量的模型,并且可以連接最后的層,如下所示: ```py dense_layer_bottleneck = tf.concat([left_bottleneck, right_bottleneck], 1) ``` 接下來,添加一個丟棄層,并從級聯層中計算出對率。 然后,該過程類似于任何其他網絡,如下所示: ```py dropout_bool = tf.placeholder(tf.bool) dropout_layer = tf.layers.dropout( inputs=dense_layer_bottleneck, rate=0.4, training=dropout_bool ) logits = dense_layer(dropout_layer, no_classes) with tf.name_scope('loss'): softmax_cross_entropy = tf.nn.softmax_cross_entropy_with_logits( labels=y_input, logits=logits) loss_operation = tf.reduce_mean(softmax_cross_entropy, name='loss') tf.summary.scalar('loss', loss_operation) with tf.name_scope('optimiser'): optimiser = tf.train.AdamOptimizer().minimize(loss_operation) with tf.name_scope('accuracy'): with tf.name_scope('correct_prediction'): predictions = tf.argmax(logits, 1) correct_predictions = tf.equal(predictions, tf.argmax(y_input, 1)) with tf.name_scope('accuracy'): accuracy_operation = tf.reduce_mean( tf.cast(correct_predictions, tf.float32)) tf.summary.scalar('accuracy', accuracy_operation) session = tf.Session() session.run(tf.global_variables_initializer()) merged_summary_operation = tf.summary.merge_all() train_summary_writer = tf.summary.FileWriter('/tmp/train', session.graph) test_summary_writer = tf.summary.FileWriter('/tmp/test') test_images, test_labels = mnist_data.test.images, mnist_data.test.labels ``` 數據必須分別輸入左右模型,如下所示: ```py for batch_no in range(total_batches): mnist_batch = mnist_data.train.next_batch(batch_size) train_images, train_labels = mnist_batch[0], mnist_batch[1] _, merged_summary = session.run([optimiser, merged_summary_operation], feed_dict={ left_input: train_images, right_input: train_images, y_input: train_labels, dropout_bool: True }) train_summary_writer.add_summary(merged_summary, batch_no) if batch_no % 10 == 0: merged_summary, _ = session.run([merged_summary_operation, accuracy_operation], feed_dict={ left_input: test_images, right_input: test_images, y_input: test_labels, dropout_bool: False }) test_summary_writer.add_summary(merged_summary, batch_no) ``` 我們已經看到了如何定義一個連體網絡。 定義了兩個編碼器,并連接了潛在空間以形成訓練損失。 左右模型分別提供數據。 接下來,我們將看到如何在單個網絡中執行相似性學習。 # FaceNet Schroff 等人提出的 [FaceNet 模型](https://arxiv.org/pdf/1503.03832.pdf)解決了人臉驗證問題。 它學習一個深層的 CNN,然后將人臉圖像轉換為嵌入圖像。 嵌入可用于比較人臉以查看其相似程度,并可通過以下三種方式使用: * **人臉驗證**考慮兩個人臉,并確定它們是否相似。 人臉驗證可以通過計算距離度量來完成。 * **人臉識別**是用于用名字標記人臉的分類問題。 嵌入向量可用于訓練最終標簽。 * **人臉聚類**將相似的人臉分組,就像照片應用將同一個人的照片聚在一起的方式一樣。 諸如 KMeans 之類的聚類算法用于對人臉進行分組。 下圖顯示了 FaceNet 架構: ![](https://img.kancloud.cn/c3/1b/c31b13e8693e75192a6b783687bb0816_566x115.png) 經 Schroff 等人許可復制。 FaceNet 會獲取一批人臉圖像并進行訓練。 在那一批中,將有幾個正對。 在計算損耗時,考慮正對和最接近的幾個負對。 挖掘選擇性對可實現平穩訓練。 如果所有負面因素一直都被推開,則訓練不穩定。 比較三個數據點稱為**三元組損失**。 在計算損耗時,圖像被認為具有正負匹配。 底片僅被推動一定的幅度。 在此詳細說明三元組損失。 # 三元組損失 三元組損失學習圖像的得分向量。 人臉描述符的得分向量可用于驗證歐幾里得空間中的人臉。 在學習投影的意義上,三元組損失類似于度量學習,因此可以區分輸入。 這些投影或描述符或分數向量是緊湊的表示形式,因此可以視為降維技術。 一個三元組由一個錨點,正負面組成。 錨可以是任何人的人臉,正面是同一個人的圖像。 負片圖像可能來自另一個人。 顯然,對于給定的錨點,將會有很多負面的人臉。 通過選擇當前更靠近錨點的底片,編碼器將很難區分人臉,從而使其學習效果更好。 此過程稱為**難負例挖掘**。 可以在歐氏空間中使用閾值獲得更接近的負值。 下圖描述了三元組損失模型: ![](https://img.kancloud.cn/29/fb/29fb6084bba88e56f702c2c5f36ab754_566x149.png) 經 Schroff 等人許可復制。 TensorFlow 中的損失計算如下所示: ```py def triplet_loss(anchor_face, positive_face, negative_face, margin): def get_distance(x, y): return tf.reduce_sum(tf.square(tf.subtract(x, y)), 1) positive_distance = get_distance(anchor_face, positive_face) negative_distance = get_distance(anchor_face, negative_face) total_distance = tf.add(tf.subtract(positive_distance, negative_distance), margin) return tf.reduce_mean(tf.maximum(total_distance, 0.0), 0) ``` 三胞胎的開采是一項艱巨的任務。 每個點都必須與其他點進行比較,以獲得適當的錨點和正對。 三元組的挖掘如下所示: ```py def mine_triplets(anchor, targets, negative_samples): distances = cdist(anchor, targets, 'cosine') distances = cdist(anchor, targets, 'cosine').tolist() QnQ_duplicated = [ [target_index for target_index, dist in enumerate(QnQ_dist) if dist == QnQ_dist[query_index]] for query_index, QnQ_dist in enumerate(distances)] for i, QnT_dist in enumerate(QnT_dists): for j in QnQ_duplicated[i]: QnT_dist.itemset(j, np.inf) QnT_dists_topk = QnT_dists.argsort(axis=1)[:, :negative_samples] top_k_index = np.array([np.insert(QnT_dist, 0, i) for i, QnT_dist in enumerate(QnT_dists_topk)]) return top_k_index ``` 由于距離計算發生在 CPU 中,因此這可能會使在 GPU 機器上的訓練變慢。 FaceNet 模型是訓練人臉相似模型的最新方法。 # DeepNet 模型 DeepNet 模型用于學習用于人臉驗證任務(例如 FaceNet)的人臉嵌入。 這是對上一部分中討論的 FaceNet 方法的改進。 它需要對同一張臉進行多次裁剪,并通過多個編碼器才能獲得更好的嵌入效果。 與 FaceNet 相比,此方法具有更高的準確率,但需要更多時間進行處理。 人臉裁切在相同區域進行,并通過其各自的編碼器。 然后將所有層連接起來以進行三元組損失的訓練。 # DeepRank Wang 等人提出的 [DeepRank](https://users.eecs.northwestern.edu/~jwa368/pdfs/deep_ranking.pdf) 用于根據相似度對圖像進行排名。 圖像通過不同的模型傳遞,如下所示: ![](https://img.kancloud.cn/48/7f/487f3afd83931e0557a3fa4fdc45f386_412x542.png) 經王等人許可轉載。 在此也計算了三元組損耗,并且反向傳播更加順利。 然后可以將圖像轉換為線性嵌入以進行排名,如下所示: ![](https://img.kancloud.cn/5d/07/5d07e3494b8cdd41644003a55c6f3c03_566x293.png) 經 Wang 等人許可復制。 該算法對于排名目的非常有用。 # 視覺推薦系統 視覺推薦系統非常適合獲取給定圖像的推薦。 推薦模型提供具有相似屬性的圖像。 [根據 Shankar 等人提出的以下模型](https://arxiv.org/pdf/1703.02344.pdf),您可以了解相似圖像的嵌入,并提供以下建議: ![](https://img.kancloud.cn/2e/05/2e0557ce3825a97ea844234de63b457d_566x267.png) 圖(a)顯示了深度排名架構,圖(b)顯示了 VisNet 架構(經 Shankar 等人許可復制)。 這些是用于相似性學習的一些算法。 在下一節中,我們將看到如何將這些技術應用于人臉。 # 人臉分析 可以使用計算機視覺以多種方式分析人臉。 為此,需要考慮以下幾個因素: * **人臉檢測**:找到人臉位置的邊界框 * **人臉標志檢測**:查找鼻子,嘴巴等人臉特征的空間點 * **人臉對齊**:將人臉轉換成正面人臉以進行進一步分析 * **屬性識別**:查找諸如性別,微笑等屬性 * **情感分析**:分析人的情感 * **人臉驗證**:查找兩個圖像是否屬于同一個人 * **人臉識別**:識別人臉 * **人臉聚類**:將同一個人的人臉分組在一起 在以下各節中,讓我們詳細了解這些任務的數據集和實現。 # 人臉檢測 人臉檢測類似于對象檢測,我們在第 4 章,“對象檢測”中討論過。 必須從圖像中檢測出人臉的位置。 可以從[這里](http://vis-www.cs.umass.edu/fddb/)下載名為**人臉檢測數據集和基準**(**FDDB**)的數據集。 。 它具有 2,845 張帶有 5,171 張臉的圖像。 可以從[這里](http://mmlab.ie.cuhk.edu.hk/projects/WIDERFace/)下載 Yang 等人提出的另一個稱為**寬臉**的數據集。 它具有 32,203 張圖像和 393,703 張人臉。 這是來自更廣泛的人臉數據集的圖像示例: ![](https://img.kancloud.cn/30/93/309360f62c96b2c86ad8b91d4b130660_566x188.jpg) 由楊等人提出。 并轉載自[這里](http://mmlab.ie.cuhk.edu.hk/projects/WIDERFace/support/intro.jpg) 數據集的比例,姿勢,遮擋,表情,妝容和照明度都有很好的變化。 另一個名**多屬性標簽的人臉**(**MALF**)的數據集包含 5,250 張圖像,其中包含 11,931 張人臉。 可以從[這個](http://www.cbsr.ia.ac.cn/faceevaluation/)鏈接訪問 MALF。 在對象檢測中使用的相同技術也可以應用于人臉檢測。 # 人臉標志和屬性 人臉標志是人臉的空間點。 空間點對應于各種人臉特征的位置,例如眼睛,眉毛,鼻子,嘴巴和下巴。 點數可能會從 5 到 78 不等,具體取決于標注。 人臉界標也稱為**基準點**,**人臉關鍵點**或**人臉姿勢**。 人臉標志具有許多應用,如下所示: * 更好地進行人臉驗證或識別的人臉對齊 * 跟蹤視頻中的人臉 * 測量人臉表情或情感 * 有助于診斷疾病 接下來,我們將看到一些帶有基準點標注的數據庫。 # 多任務人臉標志(MTFL)數據集 `MTFL`數據集由 Zhang 等人提出。 并帶有五個人臉標志以及性別,微笑,眼鏡和頭部姿勢標注。 數據庫中存在 12,995 張人臉。 可以從[這里](http://mmlab.ie.cuhk.edu.hk/projects/TCDCN/data/MTFL.zip)下載`MTFL`。 這是`MTFL`中存在的圖像的示例: ![](https://img.kancloud.cn/e0/4c/e04c7567e5f42061117cefaef0fa4c43_566x350.jpg) 由張等人提出。 并轉載自[這里](http://mmlab.ie.cuhk.edu.hk/projects/TCDCN/img/1.jpg) 人臉在年齡,照度,情感等方面有很多變化。 **頭部姿勢**是人臉方向的角度,以度為單位。 眼鏡,微笑,性別屬性等都用二元標簽標注。 # Kaggle 關鍵點數據集 Kaggle 關鍵點數據集帶有 15 個人臉標志。 數據集中存在 8,832 張圖像。 可以從[這個鏈接](https://www.kaggle.com/c/facial-keypoints-detection/data)下載。 圖像尺寸為 96 像素 x 96 像素。 # 多屬性人臉標志(MAFL)數據集 Zhang 等人提出的`MAFL`數據集。 帶有 5 種具有 40 種不同人臉屬性的人臉標志。 數據庫中存在 20,000 張人臉。 可以從[這里](https://github.com/zhzhanp/TCDCN-face-alignment)下載`MAFL`。 這是`MAFL`中存在的圖像的示例: ![](https://img.kancloud.cn/6b/a9/6ba90663d47489c3ba479018059c9fd8_566x385.png) 由 Liu 等人提出。 并轉載自[這里](http://mmlab.ie.cuhk.edu.hk/projects/celeba/overview.png) 標注的屬性包括尖頭,帶子,小胡子,卷發,戴帽子等。 這些圖像也包含在`CelebA`數據集中,稍后將詳細討論。 # 學習人臉關鍵點 如先前主題中所述,在計算關鍵人臉點時,需要定義一些參數。 我們將使用以下代碼來定義這些參數: ```py image_size = 40 no_landmark = 10 no_gender_classes = 2 no_smile_classes = 2 no_glasses_classes = 2 no_headpose_classes = 5 batch_size = 100 total_batches = 300 ``` 接下來,為各種輸入保留一些占位符。 ```py image_input = tf.placeholder(tf.float32, shape=[None, image_size, image_size]) landmark_input = tf.placeholder(tf.float32, shape=[None, no_landmark]) gender_input = tf.placeholder(tf.float32, shape=[None, no_gender_classes]) smile_input = tf.placeholder(tf.float32, shape=[None, no_smile_classes]) glasses_input = tf.placeholder(tf.float32, shape=[None, no_glasses_classes]) headpose_input = tf.placeholder(tf.float32, shape=[None, no_headpose_classes]) ``` 接下來,使用四個卷積層構造主模型,如以下代碼所示: ```py image_input_reshape = tf.reshape(image_input, [-1, image_size, image_size, 1], name='input_reshape') convolution_layer_1 = convolution_layer(image_input_reshape, 16) pooling_layer_1 = pooling_layer(convolution_layer_1) convolution_layer_2 = convolution_layer(pooling_layer_1, 48) pooling_layer_2 = pooling_layer(convolution_layer_2) convolution_layer_3 = convolution_layer(pooling_layer_2, 64) pooling_layer_3 = pooling_layer(convolution_layer_3) convolution_layer_4 = convolution_layer(pooling_layer_3, 64) flattened_pool = tf.reshape(convolution_layer_4, [-1, 5 * 5 * 64], name='flattened_pool') dense_layer_bottleneck = dense_layer(flattened_pool, 1024) dropout_bool = tf.placeholder(tf.bool) dropout_layer = tf.layers.dropout( inputs=dense_layer_bottleneck, rate=0.4, training=dropout_bool ) ``` 接下來,我們將使用以下代碼為所有不同的任務創建一個對率分支: ```py landmark_logits = dense_layer(dropout_layer, 10) smile_logits = dense_layer(dropout_layer, 2) glass_logits = dense_layer(dropout_layer, 2) gender_logits = dense_layer(dropout_layer, 2) headpose_logits = dense_layer(dropout_layer, 5) ``` 損耗是針對所有人臉特征單獨計算的,如以下代碼所示: ```py landmark_loss = 0.5 * tf.reduce_mean( tf.square(landmark_input, landmark_logits)) gender_loss = tf.reduce_mean( tf.nn.softmax_cross_entropy_with_logits( labels=gender_input, logits=gender_logits)) smile_loss = tf.reduce_mean( tf.nn.softmax_cross_entropy_with_logits( labels=smile_input, logits=smile_logits)) glass_loss = tf.reduce_mean( tf.nn.softmax_cross_entropy_with_logits( labels=glasses_input, logits=glass_logits)) headpose_loss = tf.reduce_mean( tf.nn.softmax_cross_entropy_with_logits( labels=headpose_input, logits=headpose_logits)) loss_operation = landmark_loss + gender_loss + \ smile_loss + glass_loss + headpose_loss ``` 現在,我們將初始化優化器并開始訓練,如以下代碼所示: ```py optimiser = tf.train.AdamOptimizer().minimize(loss_operation) session = tf.Session() session.run(tf.initialize_all_variables()) fiducial_test_data = fiducial_data.test for batch_no in range(total_batches): fiducial_data_batch = fiducial_data.train.next_batch(batch_size) loss, _landmark_loss, _ = session.run( [loss_operation, landmark_loss, optimiser], feed_dict={ image_input: fiducial_data_batch.images, landmark_input: fiducial_data_batch.landmarks, gender_input: fiducial_data_batch.gender, smile_input: fiducial_data_batch.smile, glasses_input: fiducial_data_batch.glasses, headpose_input: fiducial_data_batch.pose, dropout_bool: True }) if batch_no % 10 == 0: loss, _landmark_loss, _ = session.run( [loss_operation, landmark_loss], feed_dict={ image_input: fiducial_test_data.images, landmark_input: fiducial_test_data.landmarks, gender_input: fiducial_test_data.gender, smile_input: fiducial_test_data.smile, glasses_input: fiducial_test_data.glasses, headpose_input: fiducial_test_data.pose, dropout_bool: False }) ``` 此過程可用于檢測人臉特征以及界標。 # 人臉識別 **人臉識別**或**人臉識別**是從數字圖像或視頻中識別人物的過程。 讓我們在下一部分中了解可用于人臉識別的數據集。 # 野生(LFW)數據集中的帶標簽的人臉 `LFW`數據集包含 13,233 張人臉和 5,749 位獨特的人,被視為評估人臉驗證數據集的標準數據集。 精度度量可用于評估計法。 可以在[這個鏈接](http://vis-www.cs.umass.edu/lfw/)中訪問數據集。 # YouTube 人臉數據集 YouTube `faces`數據集包含 3,425 個視頻剪輯,其中包含 1,595 個獨特的人。 這些視頻是從 YouTube 收集的。 數據集每人至少有兩個視頻。 該數據集被視為視頻中人臉驗證的標準數據集。 可以在[這個鏈接](https://www.cs.tau.ac.il/~wolf/ytfaces/)中訪問數據集。 # CelebFaces 屬性數據集(CelebA) `CelebA` 數據集帶有人物身份以及 5 個人臉標志和 40 個屬性的標注。 數據庫中有 10,177 位獨特的人,擁有 202,599 張人臉圖像。 它是可用于人臉驗證,檢測,界標和屬性識別問題的大型數據集之一。 圖像具有帶有各種標注的良好人臉變化。 可以在[這個鏈接](http://mmlab.ie.cuhk.edu.hk/projects/CelebA.html)中訪問數據集。 # CASIA 網絡人臉數據庫 `CASIA`數據集帶有 10,575 個獨特的帶標注人臉,總共有 494,414 張圖像。 該數據集可以從[這個鏈接](http://www.cbsr.ia.ac.cn/english/CASIA-WebFace-Database.html)獲得。 這是可用于人臉驗證和識別問題的第二大公共數據集。 # VGGFace2 數據集 Cao 等人提出的`VGGFace2`數據集。 被 9,131 位獨特的人注解,具有 331 萬張圖片。 數據集可從[這個鏈接](http://www.robots.ox.ac.uk/~vgg/data/vgg_face2/)獲得。 變化包括年齡,種族,姿勢,職業和照度。 這是可用于人臉驗證的最大數據集。 這是數據集中存在的圖像的示例: ![](https://img.kancloud.cn/7a/56/7a5657528c70dc4954161e1420596c70_566x256.png) 由曹等人提出。 并轉載自[這里](http://www.robots.ox.ac.uk/~vgg/data/vgg_face2/web_page_img.png) 每個唯一的人的最小,平均和最大圖像數分別是 87、362.6 和 843。 # 計算人臉之間的相似度 人臉相似度的計算是一個多步驟問題。 必須檢測人臉,然后找到基準點。 面可以與基準點對齊。 對齊的面可以用于比較。 如前所述,人臉檢測類似于對象檢測。 因此,為了找到人臉之間的相似性,我們將首先通過以下代碼導入所需的庫,以及`facenet`庫: ```py from scipy import misc import tensorflow as tf import numpy as np import os import facenet print facenet from facenet import load_model, prewhiten import align.detect_face ``` 可以如下所示加載和對齊圖像: ```py def load_and_align_data(image_paths, image_size=160, margin=44, gpu_memory_fraction=1.0): minsize = 20 threshold = [0.6, 0.7, 0.7] factor = 0.709 print('Creating networks and loading parameters') with tf.Graph().as_default(): gpu_options = tf.GPUOptions(per_process_gpu_memory_fraction=gpu_memory_fraction) sess = tf.Session(config=tf.ConfigProto(gpu_options=gpu_options, log_device_placement=False)) with sess.as_default(): pnet, rnet, onet = align.detect_face.create_mtcnn(sess, None) nrof_samples = len(image_paths) img_list = [None] * nrof_samples for i in range(nrof_samples): img = misc.imread(os.path.expanduser(image_paths[i]), mode='RGB') img_size = np.asarray(img.shape)[0:2] bounding_boxes, _ = align.detect_face.detect_face(img, minsize, pnet, rnet, onet, threshold, factor) det = np.squeeze(bounding_boxes[0, 0:4]) bb = np.zeros(4, dtype=np.int32) bb[0] = np.maximum(det[0] - margin / 2, 0) bb[1] = np.maximum(det[1] - margin / 2, 0) bb[2] = np.minimum(det[2] + margin / 2, img_size[1]) bb[3] = np.minimum(det[3] + margin / 2, img_size[0]) cropped = img[bb[1]:bb[3], bb[0]:bb[2], :] aligned = misc.imresize(cropped, (image_size, image_size), interp='bilinear') prewhitened = prewhiten(aligned) img_list[i] = prewhitened images = np.stack(img_list) return images ``` 現在,我們將處理圖像路徑以獲取嵌入。 相同的代碼在這里給出: ```py def get_face_embeddings(image_paths, model='/20170512-110547/'): images = load_and_align_data(image_paths) with tf.Graph().as_default(): with tf.Session() as sess: load_model(model) images_placeholder = tf.get_default_graph().get_tensor_by_name("input:0") embeddings = tf.get_default_graph().get_tensor_by_name("embeddings:0") phase_train_placeholder = tf.get_default_graph().get_tensor_by_name("phase_train:0") feed_dict = {images_placeholder: images, phase_train_placeholder: False} emb = sess.run(embeddings, feed_dict=feed_dict) return emb ``` 現在,我們將使用以下代碼來計算嵌入之間的距離: ```py def compute_distance(embedding_1, embedding_2): dist = np.sqrt(np.sum(np.square(np.subtract(embedding_1, embedding_2)))) return dist ``` 此函數將計算嵌入之間的**歐幾里德**距離。 # 尋找最佳閾值 使用前面的函數,可以計算出該系統的精度。 以下代碼可用于計算最佳閾值: ```py import sys import argparse import os import re from sklearn.metrics import classification_report from sklearn.metrics import accuracy_score ``` 現在,使用以下代碼從文件夾中獲取圖像路徑: ```py def get_image_paths(image_directory): image_names = sorted(os.listdir(image_directory)) image_paths = [os.path.join(image_directory, image_name) for image_name in image_names] return image_paths ``` 通過嵌入時,將獲得圖像的距離,如以下代碼所示: ```py def get_labels_distances(image_paths, embeddings): target_labels, distances = [], [] for image_path_1, embedding_1 in zip(image_paths, embeddings): for image_path_2, embedding_2 in zip(image_paths, embeddings): if (re.sub(r'\d+', '', image_path_1)).lower() == (re.sub(r'\d+', '', image_path_2)).lower(): target_labels.append(1) else: target_labels.append(0) distances.append(compute_distance(embedding_1, embedding_2)) # Replace distance metric here return target_labels, distances ``` 閾值隨以下代碼所示而變化,并相應打印各種度量: ```py def print_metrics(target_labels, distances): accuracies = [] for threshold in range(50, 150, 1): threshold = threshold/100. predicted_labels = [1 if dist <= threshold else 0 for dist in distances] print("Threshold", threshold) print(classification_report(target_labels, predicted_labels, target_names=['Different', 'Same'])) accuracy = accuracy_score(target_labels, predicted_labels) print('Accuracy: ', accuracy) accuracies.append(accuracy) print(max(accuracies)) ``` 現在,借助以下代碼將圖像路徑傳遞給嵌入: ```py def main(args): image_paths = get_image_paths(args.image_directory) embeddings = get_face_embeddings(image_paths) # Replace your embedding calculation here target_labels, distances = get_labels_distances(image_paths, embeddings) print_metrics(target_labels, distances) ``` 最后,圖像目錄作為這些方法的主要參數傳遞,如以下代碼所示: ```py if __name__ == '__main__': parser = argparse.ArgumentParser() parser.add_argument('image_directory', type=str, help='Directory containing the images to be compared') parsed_arguments = parser.parse_args(sys.argv[1:]) main(parsed_arguments) ``` 在此示例中,我們采用了預先訓練的模型并將其用于構建人臉驗證方法。 ; # 人臉聚類 **人臉聚類**是將同一個人的圖像分組在一起以形成相冊的過程。 可以提取人臉的嵌入,并且可以使用諸如 K 均值的聚類算法將同一個人的人臉合并在一起。 TensorFlow 為 KMeans 算法提供了一個稱為 `tf.contrib.learn.KmeansClustering` 的 API。 K 均值算法將數據點分組在一起。 借助這種 KMeans 算法,可以提取專輯的嵌入內容,并且可以一起找到個人的人臉,或者換句話說,可以將聚在一起。 # 總結 在本章中,我們介紹了相似性學習的基礎知識。 我們研究了度量學習,連體網絡和 FaceNet 等算法。 我們還介紹了損失函數,例如對比損失和三重損失。 還涵蓋了兩個不同的領域,即排名和推薦。 最后,通過理解幾個步驟(包括檢測,基準點檢測和相似性評分)涵蓋了人臉識別的分步演練。 在下一章中,我們將了解循環神經網絡及其在自然語言處理問題中的使用。 稍后,我們將使用語言模型和圖像模型來對圖像進行字幕。 我們將針對該問題訪問幾種算法,并查看兩種不同類型數據的實現。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看