當前位置:
首頁 > 最新 > 如何通過距離度量學習解決Street-to-Shop問題

如何通過距離度量學習解決Street-to-Shop問題

選自Medium

作者:Aleksandr Movchan

機器之心編譯

參與:Nurhachu Null、黃小天

本文將向你介紹用機器學習解決街道到商店 (street-to-shop) 問題的流程:如何從用戶圖像中識別衣服,並從網上商店找到它。你可曾有過這樣的經歷,在大街上看到某個人,然後不禁感嘆,「哇哦,多麼漂亮的衣服,我在哪裡能買到它呢?」本文作者雖然沒有過這樣的經歷,但是對其而言,嘗試使用距離度量學習技術是一項很酷的任務。希望你也會覺得這很有趣。

數據集

首先,我們需要數據集。實際上,當我發現 Aliexpress 上有很多用戶圖像的時候我就有了這個想法。我心裡想,「哇,我可以通過使用這種數據來搜索,當然是僅僅為了有趣」。為了簡便,我決定重點關注女裝。

下面是我所使用的類別:

連衣裙

襯衣&襯衫

衛衣和運動衫

夾克和外套

我使用 requests(https://pypi.python.org/pypi/requests)和 beautifualSoup(https://pypi.python.org/pypi/beautifulsoup4)來爬取圖像。賣家的圖像可從商品頁面上獲得,但是為了得到用戶圖像,我們需要瀏覽反饋頁面。在商品頁面上有一個叫做「colors」的屬性,指的是另一種不同的顏色或者甚至是另一件商品,所以我們需要將不同顏色的衣服視為不同的商品。

商品頁面上的「顏色」

你可以在 github 上找到我用來得到關於一件服飾的所有信息的代碼(https://github.com/movchan74/street_to_shop_experiments/blob/master/get_item_info.py)(它爬取到的信息甚至比我們任務中需要的信息還要多)。

我們需要做的就是通過每一個類別取瀏覽對應的頁面,拿到所有商品的 URL,然後使用上面提到的函數取得有關每個商品的信息。

最終,我們得到了每個商品的兩個圖片集合:來自於賣家的圖片(商品頁面上每個「colors」對應的元素)以及來自於用戶的圖片(商品頁面上每個「feedbacks」對應的元素)。

對於每個 color,我們只有一張賣家圖片,但是可能具有多於一個的用戶圖像 (然而有時候根本沒有用戶圖像)。

很棒現在我們有數據了。然而得到的數據集有雜訊:

用戶圖像中含有雜訊(包裹箱子的照片,商品中一些無關區域的照片,以及剛拆開包裝的照片)。

用戶數據中的雜訊示例

為了減輕這個問題,我們給 5000 張圖像打了兩種不同類別的標籤:好圖片和雜訊圖片。起初,我計劃訓練一個分類器來清洗數據集。但是後來我決定將數據清洗分類器這項工作留在後面,僅僅將乾淨的數據用在測試集和驗證集中。

第二個問題是,一些商品有好幾個賣家。這些賣家有時候甚至用的是相同圖像(經過輕微編輯)。那麼如何處理這個問題呢?最簡單的方法就是對數據不做任何處理,使用一個魯棒的距離度量學習演算法。但是這會影響到驗證,因為在這種情況下,我們在驗證數據和訓練數據中有相同的商品。因此這就造成了數據泄露。另一種方式就是使用某種方法來尋找相似的(甚至完全相同的)商品,並將其合併。我們可以使用感知哈希來尋找相同的圖像(例如 phash 和 whash)。或者我們可以在雜訊數據集上訓練一個模型來尋找相似的圖像。我選擇了後者,因為這種方法可以合併經過輕微編輯的圖像。

距離度量學習

最常用的距離度量演算法之一就是 triplet loss:

其中,max(x, 0) 是 hinge 函數,d(x, y) 是 x 和 y 之間的距離函數。F(x) 是一個深度神經網路,M 是邊際,a 是 anchor,p 是正例點,n 是反例點。

F(a), F(p), F(n) 都是由深度神經網路產生的高維空間中的向量。值得提及的是,為了讓模型應對對照變化的時候更加魯棒以及訓練過程中具有更好的穩定性,這些向量需進行正則化處理,以擁有相同的長度,例如||x|| = 1。anchor 和正例樣本屬於同一類別,反例點屬於其他類別。

所以 triplet loss 的主要思想就是使用一個距離邊際 M 來區分正例對(anchor 和 positive)的向量。

但是如何選擇元組 (a, p, n) 呢?我們可以隨機選擇一個 triplet,但是這樣會導致以下問題。首先,存在 N3種可能的 triplet。這意味著我們需要花費很多時間來遍歷所有可能的 triplet。但是實際上我們沒必要這麼做,因為經過少數幾次的訓練迭代之後,很多元 triplet 已經符合 triplet 限制(例如 0 損失)。這意味著這些 triplet 在訓練中是沒用的。

最常用的 triplet 選擇的方式就是 hard negative mining:

實際上,選擇最嚴格的負樣本會在訓練早期導致糟糕的局部最小值。尤其是,它能夠導致一個收縮的模型(例如 F(x) = 0)),為了緩解這個問題,我們使用 semi-hard negative mining(半嚴格負樣本最小化)。

半嚴格負樣本要比 anchor 離正樣本更加遠,但是它們仍然是嚴格的(違背了 triplet 限制),因為它們在邊際 M 內部。

半嚴格負樣本的 triplet 的限制條件

下面是生成半嚴格和嚴格負樣本的兩種方式:在線和離線。

在線方式意味著我們從數據集中隨機地選擇樣本作為一個 mini-batch,並從這個 Mini-batch 中選擇 triplet。然而,在線方法需要一個較大的 mini-batch。在我的情況中是不可能的,因為我只有一塊具有 8GB 顯存的 GTX 1070。

在離線方式中,我們需要在一段時間之後停止訓練,為一定數量的樣本預測向量,從中選擇 triplet 並為這些 triplet 訓練模型。這意味著我們要進行兩次,然而這就是離線方法的代價。

好了,現在我們可以開始用 triplet loss 和離線半嚴格負樣本最小化來訓練模型了。但是,為了成功地解決 street-to-shop 問題,我們還需要一個技巧。我們面臨的任務是找到與用戶照片最相似的賣家圖像。然而,通常賣家的圖像具有更高的質量,所以我們有兩個域:賣家圖像和用戶圖像。為了得到更有效的模型,我們需要減小這兩個域之間的差距。這個問題就叫做域適應。

左邊是用戶的圖像;右邊是賣家的圖像

我想出了一個非常簡單的方法來減少這種域差距:我們在賣家圖像中選擇 anchor,從用戶圖像中選擇正例樣本和負例樣本。這個方法簡單有效。

實現

為了實現我的想法並快速實驗,我使用了基於 TensorFlow 的 Keras 庫。

我選擇 inception V3 作為模型的基本卷積網路。像往常一樣我使用 ImageNet 權重初始化卷積神經網路。我在使用 L2 正則化的全局池化之後又加了兩個全連接層,向量的維度是 128。

我們還需要實現 triple 損失函數。我們傳遞一個 anchor,正樣本和負樣本作為一個 mini-batch,在損失函數中將其分為三個張量。距離函數就是歐氏距離的平方。

並優化模型:

實驗結果

結果:第一列-查詢(用戶圖像),後五列-最相似的賣家圖像。

性能衡量指標是 R@K。

我們來看一下 R@K 是如何計算的。驗證集裡面的每張用戶圖像作為一次查詢,我們需要找到對應的賣家圖像。我們不僅使用了驗證集中的賣家圖像,還使用了訓練集中的圖像,因為這樣可以使我們增加干擾數量,使得我們的任務更加具有挑戰性。

所以我們就有一張查詢圖像,以及一些很相似的賣家圖像。如果在 K 個最相似的圖像中有對應的賣家數據,我們就返回 1,否則就返回 0。現在我們需要為驗證集中的每一次查詢返回這麼一個結果,然後找到每次查詢的平均得分。這就是 R@K。

正如我之前講到的,我從雜訊圖像中清洗了一部分用戶圖像。所以我在兩個驗證集上衡量了一下模型的質量:完整的驗證集只包含乾淨數據的子驗證集。

驗證數據中的 R@K

結果距離理想情況還很遠,還有很多需要做:

從雜訊數據中清洗用戶圖像。我在第一步中已經做了一部分。

更加準確地合併相似的圖像(至少在驗證集中)。

降低域差距。假設可以通過特定域增強的方法(例如亮度增強)以及其他特定的方法完成(例如這篇論文中的方法 https://arxiv.org/abs/1409.7495)。

應用其他的距離指標學習技術。我試了這篇論文中的方法(https://arxiv.org/abs/1703.07464),但是比我所用的方法性能要差一些。

當然,要收集更多的數據。

DEMO,代碼和訓練好的模型

我做了一個 demo。你可以在這裡看到 vps389544.ovh.net:5555。你可以上傳你自己的圖像或者隨便使用驗證集中的圖像來搜索。

代碼和訓練好的模型在這裡:https://github.com/movchan74/street_to_shop_experiments。

本文為機器之心編譯,轉載請聯繫本公眾號獲得授權。

?------------------------------------------------

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 機器之心 的精彩文章:

ET城市大腦來到吉隆坡,阿里雲要培養數據科學家、孵化300家公司
走,到線下去!Amazon Go的開業把我們一把拉進了智能零售時代

TAG:機器之心 |