Deep Metric Learning 🇬🇧
Note a cura di Antonino Furnari - antonino.furnari@unict.it🔝
Università di Catania, Dipartimento di Matematica e Informatica
Note disponibili qui: http://www.antoninofurnari.github.iohttps://antoninofurnari.github.io/lecture-notes/it/data-science-python/deep-metric-learning/
In questo laboratorio, vedremo alcuni metodi di deep metric learning. Iniziamo impostanto i seed per riproducibilità:
|
|
Il metric learning è una tipologia di learning supervisionato che ha come obiettivo quello di apprendere una funzione distanza tra degli elementi.
Vediamo un esempio. Supponiamo di avere un database contenente immagini di volti $I_i$ con le rispettive etichette $l_i$ che indicano le identità dei soggetti ritratti nelle immagini $l_i$. Il database può essere indicato con $D={(I_i, l_i)}_i^N$. Data una nuova immagine contenente un volto $I_j$ di identità sconosciuta, vorremmo poter “cercare” il nuovo volto all’interno del database al fine di inferire l’identità nel soggetto ritratto nell’immagine. Per poter effettuare questa ricerca, abbiamo bisogno di stimare la distanza tra il nuovo volto $I_j$ e tutti i volti presenti nel database $D$. Alla fine assegneremo al nuovo volto l’etichetta del volto più vicino nel database:
\begin{equation} \hat l_j = l_{\arg \max_{i} d(I_i, I_j)} \end{equation}
Dove $d$ è una funzione che misura la distanza tra le immagini di due volti. Questa procedura è una ricerca di tipo nearest neighbour.
Va notato che la funzione $d$ di cui abbiamo bisogno deve avere determinate caratteristiche. In particolare, vorremmo che la distanza tra due immagini $d(I_i, I_j)$ sia grande nel caso in cui le immagini non ritraggano lo stesso soggetto ($l_i \neq l_j$) e piccola nel caso in cui le identità siano uguali ($l_i = l_j$). Definire questa funzione a mano non è banale. Ad esempio, scegliendo $d$ uguale alla distanza Euclidea, non abbiamo nessuna garanzia che le proprietà richieste vengano rispettate. L’ideale sarebbe apprendere $d$ dai dati, ma non è chiaro come costruire una funzione parametrica $d$ che prende in input due immagini.
Possiamo però vedere il problema in maniera leggermente diversa. Definiamo una funzione $\Phi$ che mappa un’immagine $I$ in uno spazio di dimensionalità limitata ($\Phi$ è simile all’encoder di un autoencoder) e ridefiniamo la funzione distanza come:
\begin{equation} d(I_i, I_j) = ||\Phi(I_i) - \Phi(I_j)||_2 \end{equation}
Dove $||\Phi(I_i) - \Phi(I_j)||_2$ è la norma L2 del vettore differenza, che equivale a calcolare la distanza Euclidea tra $\Phi(I_i)$ e $\Phi(I_j)$. Se $\Phi$ è una funzione parametrica (es. una CNN), possiamo ottimizzare i parametri di $\Phi$ in maniera tale che $d$ rispetti le caratteristiche richieste. In pratica, stiamo fissando la metrica vera e propria (scegliendo quella Euclidea) e stiamo scegliendo di risolvere un problema leggermente diverso: trovare una funzione $\Phi$ che mappi elementi $I_i$ e $I_j$ della stassa classe ($l_i=l_j$) vicini nello spazio di destinazione ed elementi di classi diverse ($l_i \neq l_j$) lontani tra di loro nello spazio di destinazione.
Esistono diverse tecniche per determinare la funzione $\Phi$ in maniera opportuna. Noi vedremo due possibilità: la rete siamese e la rete triplet.
1 Rete Siamese
Il modo più semplice per ottenere una funzione $\Phi$ opportuna consiste nel prevedere una loss che renda la distanza $||\Phi(I_i) - \Phi(I_j)||_2$ piccola se $l_i=l_j$ e grande se $l_i \neq l_j$. Dato che l’espressione $||\Phi(I_i) - \Phi(I_j)||_2$ prende in input due elementi $I_i$ e $I_j$, conviene ragionare su coppie di elementi $(I_i, I_j)$ piuttosto che su elementi singoli. Esistono due tipi di coppie: quelle in cui le etichette dei due elementi sono uguali, e quelle in cui i le due etichette sono diverse. Chiameremo queste coppie “coppie simili” e “coppie dissimili”. Assegneremo dunque ad ogni coppia una etichetta $l_{ij}$. In pratica $l_{ij}=0$ se la coppia è “simile”, mentre $l_{ij}=1$ se la coppia è “dissimile”. Al fine di lavorare su coppie, è possibile utilizzare una rete “siamese”, ovvero un’architettura composta da due rami identici che condividono i medesimi pesi che mappano i due elementi della coppia $I_i$ e $I_j$ in due codici $\Phi(I_i)$ e $\Phi(I_j)$. Una volta ottenute queste due rappresentazioni, possiamo applicare una loss opportuna.
Una rete Siamese può essere rappresentata come mostrato di seguito:
Nel grafico sopra:
- L’input della rete non è un singolo elemento $I_i$, ma una coppia di elementi con la rispettiva etichetta: $(I_i, I_j, l_{ij})$;
- La funzione $\Phi$ è rappresentata come un MLP. In pratica $\Phi$ può avere diverse forme, ad esempio $\Phi$ può essere una CNN;
- I due rami (superiore e inferiore) hanno pesi condivisi. Ciò vuole dire che ogni volta il valore di uno dei pesi in una delle due reti viene aggiornato, esso viene aggiornato anche nell’altra rete;
- I pallini azzurri rappresentano i due codici $\Phi(I_i)$ e $\Phi(I_j)$;
- La loss utilizzata per allenare la rete $L[\Phi(I_i), \Phi(I_j),l_i,l_j]$ dipende sia dai due codici che dalle due etichette.
Diverse funzioni di loss sono possibili. In pratica, la loss più utilizzata è la contrastive loss, che viene definita come segue per una data coppia in input:
\begin{equation} d(I_i, I_j) = ||\Phi(I_i)-\Phi(I_j)||_2 \end{equation}
\begin{equation} L(I_i, I_j, l_{ij}) = \frac{1}{2}(1-l_{ij})d(I_i, I_j)^2+\frac{1}{2}l_{ij}{max[0,m-d(I_i, I_j)]}^2 \end{equation}
dove $m$ è un parametro della loss detto “margine”. La loss assomiglia a una binary cross entropy. Analizziamola:
- Se la coppia è di tipo “simile”, allora $l_{ij}=0$. In tal caso, $L(I_i,I_j,1) = \frac{1}{2}d(I_i,I_j)^2$, che risulta minimizzata quando $d(I_i, I_j)$ è piccola. Pertanto, in questo caso, $\Phi$ viene incoraggiata a mappare i due elementi in posizioni vicine tra di loro nello spazio di destinazione;
- Se la coppia è di ditpo “dissimile”, allora $l_{ij}=1$. In tal caso, $L(I_i,I_j,0) = \frac{1}{2}{max([0, m-d(I_i, I_j)]}^2$. Abbiamo adesso due casi:
- $d(I_i, I_j)>m$: in tal caso $m-d(I_i, I_j)<0$ e $L(I_i,I_j,0)=0$. Pertanto, se la distanza $d(I_i, I_j)$ è superiore al margine $m$, la rete non viene penalizzata in quanto si ritiene che i due mapping sono già abbastanza lontani;
- $d(I_i, I_j)<m$: in tal caso $m-d(I_i, I_j)>0$ e $L(I_i,I_j,0)=(m-d(I_i,I_j))^2$, e la rete riceve una penalità quadratica rispetto alla differenza tra la distanza e il margine. Se la distanza è molto piccola, la penalità sarà maggiore, se è abbastanza vicina a $m$, la penalità sarà minore.
In pratica, il margine $m$ stabilisce la distanza minima tra due elementi diversi nello spazio di destinazione. Esistono diversi tecniche per impostare il valore del margine. Per semplicità, in questo laboratorio imposteremo $m=2$, che è un valore comunemente usato.
1.1 Dataset
Per costruire la nostra rete Siamese, abbiamo innanzitutto bisogno di costruire un oggetto dataset che restituisca coppie di immagini con le rispettive etichette. Vedremo un semplice esempio relativo al dataset MNIST. Le nostre coppie saranno dunque composte da due immagini rappresentanti cifre. L’etichetta relativa sarà pari a $0$ se le etichette delle due immagini sono uguali e $1$ altrimenti. Costruiremo un oggetto database che ha tanti elementi quanti sono gli elementi di MNIST. A ciascun elemento verrà associato un elemento simile o dissimile con probabilità $\frac{1}{2}$. Ciò ci permetterà di avere un dataset di coppie bilanciato.
|
|
Costruiamo il dataset e visualizziamo qualche coppia di esempio:
|
|
Domanda 1 Si osservino le coppie rappresentate nelle colonne. Ha senso dire che elementi in coppie positive sono in genere più simili di elementi in coppie negative? |
1.2 Modello
Implementiamo $\Phi$ basandoci su LeNet. Dato che non useremo $\Phi$ per classificare i dati in input, ometteremo l’ultimo livello con $10$ unità. Chiameremo questa rete EmbeddingNet
in quanto il suo ruolo è quello di ottenere degli embedding (o codici) delle immagini in input:
|
|
Verifichiamo che l’output sia quello desiderato con un batch fittizio:
|
|
torch.Size([16, 128])
1.3 Funzione di loss
Prima di effettuare il training, dobbiamo implementare la funzione di loss. Ricordiamo che la loss per un dato campione è definita come segue:
\begin{equation} d(I_i, I_j) = ||\Phi(I_i)-\Phi(I_j)||_2 \end{equation}
\begin{equation} L(I_i, I_j, l_{ij}) = \frac{1}{2}(1-l_{ij})d(I_i, I_j)^2+\frac{1}{2}l_{ij}{max[0,m-d(I_i, I_j)]}^2 \end{equation}
|
|
dove F.pairwise_distance(x,y)
calcola la distanza euclidea tra tutti gli elementi di $x$ e tutti gli elementi di $y$ quando $x$ e $y$ sono dei batch, torch.pow(x,2)
implementa $x^2$ e torch.clamp(x, min=0)
implementa min(x,o)
.
1.4 Training del modello
Adesso che abbiamo tutti gli elementi necessari, definiamo un modulo di PyTorch Lightning che ci permetta di fare training della rete siamese. Per monitorare lo stato di training della rete in termini qualitativi, alla fine di ogni epoca stamperemo l’embedding del primo batch di test.
|
|
Costruiamo dataset e data loaders:
|
|
Costruiamo e alleniamo il modello:
|
|
GPU available: True, used: True
TPU available: False, using: 0 TPU cores
IPU available: False, using: 0 IPUs
LOCAL_RANK: 0 - CUDA_VISIBLE_DEVICES: [0,1,2,3]
| Name | Type | Params
--------------------------------------------------
0 | embedding_net | EmbeddingNet | 350 K
1 | criterion | ContrastiveLoss | 0
--------------------------------------------------
350 K Trainable params
0 Non-trainable params
350 K Total params
1.400 Total estimated model params size (MB)
Alla fine della procedura di training, i grafici su tensorboard avranno un aspetto simile a questo:
Cliccando su “projector” possiamo visualizzare un embedding 3D creato in automatico dai dati di cui abbiamo fatto log. Selezioniamo l’ultimo tensore disponibile (quello relativo all’ultima epoca) nel secondo menù a tendina a sinistra (“x tensors found”), ad esempio, selezioniamo default:01061
. Selezioniamo poi label
in Color by
.
Domanda 2 Si esplori il grafico ottenuto in tensorboard. Gli embedding ottenuti sono buoni? |
Come visto nel caso degli autoencoders, possiamo adesso utilizzare la rete per estrarre le rappresentazioni di ciascuna immagine del dataset:
|
|
|
|
Utilizziamo dunque TSNE per visualizzare gli embedding di acluni esempi:
|
|
Domanda 3 Si commenti il grafico ottenuto. Le rappresentazioni ottenute sono buone per risolvere task di classificazione? |
2 Rete Triplet
La rete Siamese viene allenata includendo all’interno dello stesso batch sia esempi negativi che esempi positivi. Se includessimo solo esempi positivi, la rete imparerebbe a mappare qualsiasi input sullo stesso punto, in modo da ottenere sempre distanza nulla. Se includessimo solo esempi negativi, al contrario, la rete cercherebbe di mappare i nuovi campioni sempre lontani rispetto ai campioni già visti. Una rete di tipo Triplet estende l’idea di avere coppie positive e negative lavorando su triplette invece che su coppia.
Ogni tripletta $(I_i, I_j, I_k)$ contiene tre elementi:
- Un’ancora $I_i$, ovvero un elemento di classe qualsiasi;
- Un esempio positivo $I_j$, ovvero un elemento della stessa classe di $I_i$;
- Un esempio negativo $I_k$, ovvero un elemento di classe diversa rispetto a $I_i$ e $I_j$.
Ogni elemento in input presenta dunque un esempio positivo (la coppia ($I_i, I_j$)) e un esempio negativo (la coppia ($I_i, I_k$)). A differenza per quanto avveniva nel caso delle reti siamesi, le triplette non hanno una etichetta associata. Il modello viene dunque allenato facendo sì che $I_i$ venga mappato vicino a $I_j$ ma allo stesso tempo lontano da $I_k$. Ciò costituisce un criterio di training più forte rispetto a quello delle reti siamesi. Infatti, mentre le caso delle reti siamesi le coppie positive e negative potevano non avere alcuna relazione tra di esse, le triplette offrono sempre un esempio positivo e un esempio negativo relativi al medesimo elemento ancora $I_i$.
Una rete Triplet può essere rappresentata come segue:
Anche in questo caso i pesi delle tre reti sono condivisi. Esistono diversi tipi di loss, ma la più comune è la Triplet margin loss, definita come segue:
\begin{equation} d(I_i, I_j) = ||\Phi(I_i) - \Phi(I_j)||_2 \end{equation}
\begin{equation} L(I_i, I_j, I_k) = \max{d(I_i, I_j)-d(I_i, I_k)+m, 0} \end{equation}
In maniera simile a quanto visto nel caso della contrastive loss, $m$ è un margine. In questo laboratorio imposteremo $m=1$.
La loss scritta sopra incoraggia la rete $\Phi$ a mappare l’elemento simile $I_j$ vicino all’elemento $I_i$ e al contempo, l’elemento $I_k$ lontano da $I_i$. Ciò avviene penalizzando la rete ogni volta che $d(I_i, I_j)$ non è maggiore di $d(I_i, I_k)$ di un valore almeno pari ad $m$. Abbiamo infatti due casi:
- $d(I_i, I_j) + m <=d(I_i, I_k)$: in questo caso $d(I_i, I_j)-d(I_i, I_k)+m<0$ e $L(I_i, I_j, I_k)=0$. In pratica il modello non viene penalizzato in quanto la distanza tra l’ancora $I_i$ e l’elemento simile $I_j$ è già sufficientemente inferiore (ovver inferiore di almento $m$) alla distanza tra l’ancora $I_i$ e l’elemento dissimile $I_k$;
- $d(I_i, I_k) +m >d(I_i, I_k)$: in questo caso $d(I_i, I_j)-d(I_i, I_k)+m>0$ e $L(I_i, I_j, I_k)=d(I_i, I_j)-d(I_i, I_k)+m$. Pertanto il modello riceve una penalità (una loss positiva) in quanto non vi è abbastanza margine tra le due distanze. La loss è tanto più alta quanto questo margine è grande.
Questa funzione di loss è già implementata in PyTorch da modulo nn.TripletMarginLoss
, che utilizzeremo per i nostri esperimenti.
2.1 Dataset
Dobbiamo implementare un dataset che restituisca delle triplette di valori. L’implementazione è analoga a quanto visto nel caso delle reti siamesi:
|
|
Costruiamo il dataset e visualizziamo qualche tripletta di esempio:
|
|
Domanda 4 Si confrontino e commentino le triplette visualizzate qui con le coppie mostrate nel caso della rete siamese. Che vantaggio hanno le triplette rispetto alle coppie viste in precedenza? |
2.2 Training
Definiamo una procedura di training analoga a quella vista nel caso delle reti siamesi. Anche in questo caso plotteremo gli embedding durante il training.
|
|
Definiamo i dataloader di training e test:
|
|
Effettuiamo adesso il training:
|
|
GPU available: True, used: True
TPU available: False, using: 0 TPU cores
IPU available: False, using: 0 IPUs
LOCAL_RANK: 0 - CUDA_VISIBLE_DEVICES: [0,1,2,3]
| Name | Type | Params
----------------------------------------------------
0 | embedding_net | EmbeddingNet | 350 K
1 | criterion | TripletMarginLoss | 0
----------------------------------------------------
350 K Trainable params
0 Non-trainable params
350 K Total params
1.400 Total estimated model params size (MB)
Alla fine del training otterremo dei grafici di questo tipo:
E un grafico di embedding di questo tipo:
Come nel caso della rete siamese, possiamo estrarre le rappresentazione e stampare i valori a schermo:
|
|
Domanda 5 Si confrontino gli embedding ottenuti mediante la rete triplet con quelli ottenuti mediante la rete siamese. Ci sono differenze? |
3 Metric Learning per la localizzazione basata su immagini
Vediamo adesso un esempio concreto di uso del metric learning per risolvere il problema della localizzazione basata su immagini. In questo esempio, tratteremo il problema della localizzazione com un problema di image retrieval. Assumeremo di avere a disposizione un insieme di immagini associate alle posizioni in cui queste immagini sono state acquisite in un sistema di riferimento. Utilizzeremo parte di questi dati come spazio di ricerca (o training set). Data una nuova immagine, cercheremo dunque all’interno del training set l’immagine più simile e restituiremo la sua posizione come stima della posizione dell’immagine di input. Questo approccio è riassunto nell’immagine seguente:
Nello schema sopra, $\phi$ rappresenta una funzione utilizzata per rappresentare le immagini in modo da poterle proiettare in uno spazio di rappresentazione nel quale effettuare la ricerca.
Domanda 6 Che caratteristiche deve avere la funzione di rappresentazione $\phi$? Il metric learning può essere d’aiuto? Perché? |
3.1 Dataset
Per questo esempio, utilizzeremo il dataset EgoCart disponibile a questa pagina: https://iplab.dmi.unict.it/EgocentricShoppingCartLocalization/#dataset. Il dataset contiene immagini acquisite da un carrello della spesa all’interno di un supermercato. A ciascuna immagine sono associate due coordinate spaziali $x$ e $y$ in metri che indicano la posizione del carrello nel supermercato e le componenti $u$ e $v$ di un versore che indica l’orientamento del carrello (ovvero la direzione verso la quale punta la camera posizionata sul carrello). Le coordinate seguono lo schema mostrato di seguito:
L’immagine seguente mostra alcune immagini prese dal dataset con le corrispondenti posizioni all’interno del supermercato:
Iniziamo scaricando il dataset con il comando:
wget https://iplab.dmi.unict.it/EgocentricShoppingCartLocalization/egocart.zip
Lo zip occupa circa 2.5GB. Una volta scaricato il file, estraiamone il contenuto con:
unzip egocart.zip -d egocart
.
Dopo aver eseguito questo comando, troveremo le cartelle train_set
, test_set
e il file README.txt
. All’interno di train_set
sono contenute le cartelle train_depth
e train_RGB
e il file train_set.txt
. Noi utilizeremo solo la cartella train_RGB
, che contiene le immagini RGB e train_set.txt
che contiene le etichette (ovvero le posizioni associate a ciascuna immagine). Il test set ha una struttura simile.
Definiamo un modulo Dataset
per leggere le immagini e le rispettive etichette da file:
|
|
Visualizziamo qualche esempio di immagine:
|
|
3.2 Baseline basata nearest neighbor su RGB
Iniziamo implementando una semplice baseline che effettua una ricerca nearest neighbor basandosi sui valori RGB grezzi. In pratica, questa baseline ricerca l’immagine visivamente più simile. Iniziamo convertendo le immagini RGB in vettori monodimensionali mediante una operazione di reshape:
|
|
Definiamo i dataloader per training e test set. Per questa baseline, considereremo immagini di dimensione $64 \times 64$ per ridurre il numero di feature:
|
|
Estraiamo adesso le rappresentazioni per training e test set:
|
|
100%|██████████| 418/418 [01:09<00:00, 5.98it/s]
100%|██████████| 193/193 [00:51<00:00, 3.72it/s]
Controlliamo la dimensionalità delle rappresentazioni:
|
|
(13360, 5376)
Costruiamo adesso una funzione che permetta di predire le etichette sul test set utilizzando l’algoritmo nearest neighbor. Utilizzeremo la libreria faiss
per effettuare la ricerca in maniera efficiente. Da Anaconda, possiamo installare la libreria con il comando:
conda install -c pytorch faiss-gpu
Definiamo la funzione:
|
|
Otteniamo le predizioni sul test set:
|
|
3.3 Misure di valutazione
Valuteremo la bontà delle predizioni ottenute calcolando la distanza euclidea tra i vettori xy
predetti e quelli di ground truth e la distanza angolare media tra gli orientamenti dei vettori uv
. Definiamo una funzione di valutazione per fare ciò:
|
|
Calcoliamo dunque l’errore di posizione e quello di orientamento:
|
|
Position error: 1.66m
Orientation error: 11.82°
Domanda 7 Si discutano le perfomance della baseline. Si tratta di buone performance? |
3.4 Training della funzione di rappresentazione mediante triplet
Vedremo adesso come effettuare il training di una funzione di rappresentazione mediante loss triplet. Utilizzeremo una MobileNetv2
pre-allenata per estrarre le feature. Utilizzeremo poi l’algoritmo Nearest Neighbor per risolvere il problema di localizzazione. Importiamo il modello:
|
|
Vogliamo utilizzare il modello per estrarre le feature, quindi dobbiamo rimuovere il classificatore finale. Nello specifico, imposteremo il classificatore a un modulo identità:
|
|
Verifichiamo qual è la dimensione del vettore di feature estratto per una immagine di input di shape $3 \times 224 \times 224$:
|
|
torch.Size([1, 1280])
Il modello estrae vettori di rappresentazione di $1080$ unità. Definiamo una funzione per estrarre le rappresentazioni dai dataloader di training e test:
|
|
Definiamo i dataloader per training e test set:
|
|
Usiamo il modello non ancora allenato per estrarre le rappresentazioni dal training e dal test set:
|
|
100%|██████████| 418/418 [00:42<00:00, 9.94it/s]
100%|██████████| 193/193 [00:20<00:00, 9.27it/s]
Valutiamo adesso le performance del sistema con queste rappresentazioni non ancora ottimizzate:
|
|
Position error: 4.41m
Orientation error: 36.01°
Domanda 8 Si confrontino le performance ottenute con quelle del modello di base che usa i valori RGB come rappresentazione. Si tratta di buone performance? Perché? |
Procediamo adesso ad allenare la rete mediante Triplet. Per fare ciò, definiremo delle triplette di immagini dal dataset in cui la coppia simile è composta di immagini la cui posizione xy
ha una distanza inferiore a $0.3m$ e una differenza angolare tra gli orientamenti inferiore a $45°$. Iniziamo costruendo un oggetto dataset che ci permetta di campionare le triplette:
|
|
Instanziamo l’oggetto dataset:
|
|
Visualizziamo adesso alcuni esempi di triplet:
|
|
Domanda 9 Si discutano gli esempi di triplet mostrati. Sono esempi validi? Si possono notare differenze visibili tra coppie di immagini simili e dissimili? |
Definiamo i dataloader di training e test:
|
|
Vista la complessità del task, aggiungeremo un termine di regolarizzazione che penalizza la rete se questa cerca di produrre embedding di modulo troppo grande. Si tratta di un vincolo simile a quello di sparsità visto nel caso degli autoencoder, che aiuta a ridurre l’overfitting.
La loss di training sarà dunque:
$$ L(I_i, I_j, I_k) + \beta \cdot (||\Phi(I_i)||_2 + ||\Phi(I_j)||_2 + ||\Phi(I_k)||_2 ) $$
Sceglieremo $\beta=0.001$. Ridefiniamo il modulo triplet di lightning con la nuova loss ed eliminiamo la visualizzazione degli embedding su tensorboard:
|
|
Adesso possiamo utilizzare il modulo di Lightning definito in precedenza per effettuare il training del modello:
|
|
GPU available: True, used: True
TPU available: False, using: 0 TPU cores
IPU available: False, using: 0 IPUs
LOCAL_RANK: 0 - CUDA_VISIBLE_DEVICES: [0,1,2,3]
| Name | Type | Params
----------------------------------------------------
0 | embedding_net | MobileNetV2 | 2.2 M
1 | criterion | TripletMarginLoss | 0
----------------------------------------------------
2.2 M Trainable params
0 Non-trainable params
2.2 M Total params
8.895 Total estimated model params size (MB)
Alla fine del training otterremo dei grafici simili ai seguenti su Tensorboard:
Una volta terminato il training, estraiamo le rappresentazioni e valutiamo il modello:
|
|
Domanda 10 Si commentino i risultati ottenuti. Sono migliori di quelli ottenuti in precedenza? Perché? |
Esercizi
Esercizio 1 Si adatti la EmbeddingNet per effettuare la classificazione dei dati di MNIST e si esegua il fine-tuning per questo task. Si confronti questo modello con un modello analogo allenato da zero. Quale dei due modelli converge prima? Il pre-training mediante rete Siamese offre dei vantaggi? |
Esercizio 2 Si ripeta l’esecizio precedente adattando la EmbeddingNet allenata mediante rete Triplet per il task di classificazione. Il pre-training mediante rete Triplet offre dei vantaggi? E’ più efficace del pre-training mediante rete Siamese? Perché? |
Esercizio 3 Ripetere gli esperimenti su rete siamese con il dataset Fashion MNIST. |
Esercizio 4 Ripetere gli esperimenti su rete triplet con il dataset Fashion MNIST. |
Esercizio 5 Ripetere gli esperimenti di training della rete per localizzazione con triplet cambiando le soglie utilizzate per determinare coppie simili e dissimili e il numero di epoche di training. Provare a trovare dei parametri che permettano di migliorare le performance del modello di localizzazione. Provare a fare fine-tuning di un modello pre-allenato. I risultati migliorano? |
References
- Documentazione di PyTorch. http://pytorch.org/docs/stable/index.html
- Documentazione di PyTorch Lightning. https://www.pytorchlightning.ai/