Come applicare l'apprendimento della metrica della distanza al problema dello street-to-shop

Cominciamo con una definizione del problema dello street-to-shop: identificare un capo di moda nell'immagine di un utente e trovarlo in un negozio online. Hai mai visto qualcuno per strada e hai pensato "Wow, questo è un bel vestito, mi chiedo dove posso comprarlo?" Non l'ho mai visto. Ma per me, è stato bello provare le tecniche di apprendimento delle metriche a distanza. Spero che lo troverai interessante.

dataset

In primo luogo, abbiamo bisogno di un set di dati per questo. In realtà, sono venuto a questa idea dopo aver scoperto che ci sono tonnellate di immagini scattate dagli utenti su Aliexpress. E ho pensato "Wow, posso fare una ricerca per immagine usando questi dati, ovviamente solo per divertimento". Ho deciso di concentrarmi sull'abbigliamento più femminile per semplicità.

Di seguito è riportato l'elenco delle categorie che ho usato per la demolizione:

  • Abiti
  • Camicette e camicie
  • Felpe con cappuccio e felpe
  • Maglioni
  • Giacche e Cappotti

Ho usato le richieste e BeautifulSoup per la demolizione. Le immagini del venditore possono essere ottenute dalla pagina principale dell'articolo, ma per le immagini degli utenti, dobbiamo passare attraverso le pagine di feedback. C'è una cosa chiamata "colori" nella pagina dell'articolo. Il colore può essere solo un elemento di un altro colore o addirittura completamente altri elementi. Quindi considereremo colori diversi come elementi diversi.

Puoi trovare il codice che ho usato per ottenere tutte le informazioni su un elemento (scarta anche più del necessario per il nostro compito) tramite il link https://github.com/movchan74/street_to_shop_experiments/blob/master/get_item_info.py.

Tutto ciò di cui abbiamo bisogno è di scorrere le pagine di ricerca per ciascuna categoria, prendere gli URL di tutti gli elementi e utilizzare la funzione sopra per ottenere le informazioni su ciascun elemento.

Infine, avremo due serie di immagini per ogni articolo: immagini di un venditore (URL del campo per ciascun elemento initem ['colori']) e immagini degli utenti (campi di campo per ciascun elemento initem '' feedback ']).

Per ogni colore, abbiamo solo un'immagine di un venditore, ma può essere più di un'immagine per ogni colore degli utenti (a volte non ci sono immagini per il colore).

Grande! Abbiamo dati. Tuttavia, il set di dati raccolti è rumoroso:

  • Ci sono immagini rumorose da parte degli utenti (foto di scatole del pacchetto, foto di trama o solo una parte di un articolo, articoli non imballati, foto non correlate).
Esempi di rumore nelle immagini dell'utente.

Per mitigare questo problema ho etichettato 5000 immagini in due categorie: buone immagini e immagini di rumore. All'inizio, il mio piano era di formare un classificatore per due categorie e usarlo per pulire il set di dati. Ma in seguito ho deciso di lasciare questa idea per il lavoro futuro e ho appena aggiunto immagini pulite ai set di test e di validazione.

  • Il secondo problema è che ci sono articoli venduti da più venditori. I venditori hanno persino le stesse immagini qualche volta (o immagini leggermente modificate). Ma come affrontarlo? Il modo più semplice è non fare nulla e utilizzare un algoritmo robusto per l'apprendimento delle metriche a distanza. Può tuttavia influire sulla convalida perché possiamo avere lo stesso articolo nei dati di convalida e formazione. Quindi porta a una perdita di dati. Un altro modo è usare qualcosa per trovare immagini simili (o addirittura identiche) e unirle in un elemento. Possiamo usare l'hashing percettivo per trovare immagini identiche (come phash o whash), oppure possiamo addestrare un modello su dati rumorosi e applicare il modello per trovare immagini simili. Ho scelto la seconda opzione perché consente di unire anche le immagini leggermente modificate.

Apprendimento metrico a distanza

Uno dei metodi di apprendimento metrici a distanza più popolari è la perdita di tripletta:

dove max (x, 0) è la funzione di cerniera, d (x, y) è la funzione di distanza tra x e y, F (x) è la rete neurale profonda, M è il margine, a è l'ancora, p è il positivo punto, n è il punto negativo.

F (a), F (p), F (n) sono punti nello spazio tridimensionale (embeddings) prodotti da una rete neurale profonda. Vale la pena ricordare che gli incastri spesso devono essere normalizzati per avere una lunghezza unitaria, vale a dire || x || = 1, per essere robusto alle variazioni di illuminazione e contrasto e per la stabilità dell'allenamento. L'ancoraggio e i campioni positivi appartengono alla stessa classe, il campione negativo è l'istanza di un'altra classe.

Quindi l'idea principale della perdita della tripletta è quella di separare gli incastri della coppia positiva (ancora e positivo) dagli incastri della coppia negativa (ancora e negativo) da un margine di distanza M.

Ma come selezionare la tripletta (a, p, n)? Siamo in grado di selezionare casualmente i campioni come tripletta ma causa i seguenti problemi. Innanzitutto, ci sono N³ possibili terzine. Significa che abbiamo bisogno di molto tempo per esaminare tutte le terzine possibili. Ma in realtà, non abbiamo bisogno di farlo, perché dopo poche iterazioni di allenamento ci saranno molte terzine che non violano il vincolo delle terzine (danno zero perdite). Significa che queste terzine sono inutili per un allenamento.

Uno dei modi più comuni di selezione delle terzine è il mining fortemente negativo:

La selezione dei negativi più difficili può in pratica portare a minimi locali negativi all'inizio dell'allenamento. In particolare, può risultare in un modello compresso (ovvero F (x) = 0). Per mitigare questo, possiamo usare il mining negativo semi-duro.

I campioni negativi semi-duri sono più lontani dall'ancora rispetto al campione positivo ma sono ancora duri (violano il vincolo della tripletta) perché si trovano all'interno del margine M.

Condizioni per una tripletta con campione negativo semiduro

Esistono due modi per generare campioni negativi semi-duri (e difficili): online e offline.

  • Online significa che selezioniamo casualmente campioni dall'insieme di dati del treno come mini-batch e selezioniamo terzine dai campioni al suo interno. Tuttavia, per il metodo online è necessario disporre di grandi dimensioni in mini-batch. Nel mio caso non è possibile perché ho solo una GTX 1070 con 8 GB di RAM.
  • Nel metodo offline è necessario interrompere l'allenamento dopo un po 'di tempo, prevedere incorporamenti per un certo numero di campioni, selezionare terzine e formare il modello con queste terzine. Significa che dobbiamo fare il forward pass due volte, ma è il prezzo per il metodo offline.

Buono! Possiamo già iniziare ad addestrare il modello con la perdita della tripletta e il mining negativo semiduro offline. Ma! C'è sempre un "ma" in questo mondo imperfetto. Abbiamo bisogno di un altro trucco per risolvere con successo il problema dello street-to-shop. Il nostro compito è di trovare l'immagine del venditore più simile all'immagine dell'utente. Tuttavia, in genere le immagini del venditore hanno una qualità molto migliore (in termini di illuminazione, videocamera, posizione) rispetto alle immagini degli utenti, quindi abbiamo due domini: le immagini del venditore e le immagini dell'utente. Per ottenere un modello efficiente dobbiamo ridurre un divario tra questi due domini. Questo problema si chiama adattamento del dominio.

A sinistra: l'immagine dell'utente, a destra: l'immagine del venditore

Propongo una tecnica davvero semplice per ridurre il gap del dominio: selezioniamo gli ancoraggi dalle immagini del venditore, i campioni positivi e negativi dalle immagini degli utenti. È tutto! Semplice ma efficace.

Implementazione

Per implementare le mie idee e fare esperimenti veloci ho usato la libreria Keras con il backend Tensorflow.

Ho scelto il modello Inception V3 come CNN di base per il mio modello. Come al solito, ho inizializzato la CNN con i pesi di ImageNet. Ho aggiunto due livelli completamente collegati dopo il pool globale con la normalizzazione L2 alla fine della rete. La dimensione dell'incorporamento è 128.

Dobbiamo anche implementare la funzione di tripla perdita. Passiamo l'ancora, i campioni positivi / negativi come singolo mini-batch e lo dividiamo in 3 tensori all'interno della funzione di perdita. La funzione della distanza è la distanza euclidea al quadrato.

E compila modello:

Risultati sperimentali

Risultati del recupero. Prima colonna: query (immagine dell'utente), 5 successive: immagini del venditore più simili.

Le prestazioni sono misurate in termini di richiamo a K (R @ K).

Diamo un'occhiata a come calcolare R @ K. L'immagine di ciascun utente dal set di convalida è stata utilizzata come query e dobbiamo trovare l'immagine del venditore corrispondente. Prendiamo un'immagine di query, calcoliamo l'incorporamento del vettore e cerchiamo i vicini più vicini di questo vettore tra i vettori di tutte le immagini del venditore. Utilizziamo non solo le immagini del venditore dal set di convalida, ma anche le immagini del set del treno perché consente di aumentare il numero di distrattori e rende il nostro compito più impegnativo.

Quindi abbiamo un'immagine di query e un elenco delle immagini del venditore più simili. Se esiste un'immagine del venditore corrispondente nelle immagini più simili di K, restituiamo 1 per questa query altrimenti restituiamo 0. Ora dobbiamo crearla per l'immagine di ciascun utente nel set di convalida e trovare una media di punteggi per ogni query. Sarà R @ K.

Come ho detto prima, ho pulito la piccola quantità di immagini dell'utente da immagini rumorose. Quindi ho misurato una qualità del modello su due set di dati di validazione: set di validazione completo e un sottoinsieme di sole immagini pulite.

R @ K per i dati di validazione

I risultati sono tutt'altro che ideali, ci sono molte cose da fare:

  • Pulisci le immagini degli utenti dal rumore. Ho già fatto il primo passo in questa direzione pulendo un piccolo set.
  • Unisci gli elementi in modo più accurato (almeno nel set di convalida).
  • Ridurre il divario di dominio. Suppongo che possa essere fatto tramite un aumento specifico del dominio (ad esempio un aumento dell'illuminazione) e usando metodi specializzati (come questo https://arxiv.org/abs/1409.7495).
  • Applicare un'altra tecnica di apprendimento della metrica a distanza. Ho provato questo https://arxiv.org/abs/1703.07464, ma nel mio caso funziona peggio.
  • Colleziona più dati ovviamente.

Demo, codice e modello addestrato

Ho fatto una demo del modello. Puoi verificarlo qui: http://vps389544.ovh.net:5555/. Puoi caricare la tua immagine per la ricerca o utilizzare un'immagine casuale dal set di convalida.

Codice e modello addestrato: https://github.com/movchan74/street_to_shop_experiments

Grazie per aver letto. Se ti piace l'articolo, fammi sapere battendo le mani. Se vuoi maggiori informazioni, puoi connetterti con me su LinkedIn.