Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
vuoi
o PayPal
tutte le volte che vuoi
BASI DI MANIPOLAZIONE DATI.
Usiamo la libreria PyTorch un open source machine learning framework originariamente sviluppato da
⇒
Meta AI.
Usare tensor in PyTorch è simile a ndarray in NumPy, con alcune caratteristiche notevoli quali: la GPU per
accelerare il calcolo numerico (in quanto NumPy funziona solo su CPU) e la differenziazione automatica.
Queste caratteristiche rendono Machine Learning, Computer Vision e qualsiasi calcolo numero facili da
codificare e veloci da eseguire.
Per usare la libreria PyTorch si usa il nome: import torch.
dtype è per specificare il tipo, di default è float32.
Utilizziamo i tensori ovvero matrici a più dimensioni. Per impostazione predefinita, sono spaziati di 1. Se
non specificato, tutti i tensori vengono allocati in memoria principale. Inoltre, viene istanziato tutto a cpu
perchè tutto ha un costo. PyTorch fornisce una varietà di funzioni per la creazione di nuovi tensori pre
compilati con certi particolari valori.
arange(n) → creare un vettore di valori che inizia con indice 0 (incluso) e finisce con n (non incluso).
Questa funzione, crea un tensore con valori equispaziati all'interno di un intervallo specificato.
numel() → ottenere il numero totale di elementi in un tensore.
shape → restituisce una tupla (array immutabile), rappresentando le dimensioni del tensore lungo ciascun
asse.
reshape → manipola la forma del tensore senza modificare i dati contenuti al suo interno (es. vettore di 12
che diventa matrice 3x4). Per dedurre automaticamente la forma, si usa un -1 per la dimensione
interessata; ad esempio se ho vettore di 12 e so che voglio una matrice di 4 colonne ma non voglio fare il
conto per le righe scriverò x.reshape(-1,4) e lui calcola da solo che sarà (3,4). Utile per preparare i dati in
un formato adeguato per l'input di algoritmi.
Inizializzazione tensori con zero, uno o da realizzazioni di una distribuzione Normale → utili per
inizializzare parametri o definire matrici da cui partire. Si usa random se non so come inizializzarle (numeri
casuali). Altrimenti si fornisce una lista di liste (nested list) per assegnare il valore per ciascun elemento
→ consente di creare un nuovo tensore a partire da una lista, una tupla, un array su NumPy o un altro
tensore esistente.
torch.tensor → utile per creare tensori nuovi da file già esistenti.
slicing → consente l’accesso ad intervalli di indici X[start:stop]. Il valore restituito include il primo indice
(start) ma non l'ultimo (stop). Questa è una tecnica per estrarre una porzione di un tensore.
Viene usato anche per assegnare valori, ad esempio se voglio assegnare a più elementi lo stesso valore.
In particolare: con un solo indice (slicing), viene applicato lungo l'asse 0; X[-1] seleziona l’ultima riga;
X[1:3] seleziona la seconda e la terza riga; [start:] estrae tutti gli elementi a partire da start (analogo per
[:stop])
Le operazioni element-wise (fra cui prodotto Hadamard) sono implementate utilizzando gli operatori
matematici standard (oppure torch.add, torch.sub, torch.mul, torch.div) e le funzioni matematiche e
statistiche (torch.exp, torch.log, torch.sqrt, torch.mean, torch.std e molte altre) e vengono usate per
eseguire calcoli efficienti (come la normalizzazione di dati di input).
torch.exp(x) → esempio di operatore che lavora in un solo argomento.
Per normalizzare i dati con torch.mean e torch.std:
Concatenazione: si fornisce l’elenco dei tensori e l’asse su cui concatenarli. Usata ad esempio per
concatenare due features.
Esempio con matrici concatenate lungo le righe (asse 0) e lungo le colonne (asse 1).
Broadcasting → permette la somma poiché estende automaticamente le dimensioni minori → viene fatto
automaticamente.
Sequenze di operazioni possono causare l'allocazione di nuova memoria: Y = Y + X.
Per ridurre l’uso di memoria, se X non viene utilizzato si può fare (assegnamento in place): X += Y.
id() → funzione Python che fornisce l'indirizzo oggetto in memoria.
.from_numpy() → usata per passare da torch a numpy
numpy() → da PyTorch a NumPy
.item o int di Python → usati per convertire uno scalare
a.to ('cuda') → metodo di PyTorch che sposta un tensore dalla CPU alla GPU. Senza spostamento si usa
PyTorch in CPU. La GPU si usa ad esempio per il prodotto matriciale fra matrici di grandi dimensioni.
tecnica di riduzione della dimensionalità
PRINCIPAL COMPONENT ANALYSIS (PCA) ⇒
che estrae le componenti principali dei dati originali, consentendo di rappresentare i dati in
uno spazio di dimensione inferiore mantenendo al contempo la maggior parte della varianza dei dati
originali. Questo permette di ridurre la complessità dei dati mantenendo le informazioni più rilevanti.
Un semplice algoritmo di apprendimento automatico, analisi delle componenti di dati o PCA può essere
derivato utilizzando solo la conoscenza dell’algebra lineare di base e usato attraverso semplici strumenti.
Molti dataset hanno datapoint che si trovano in un sottospazio di dimensione inferiore a quella originale.
Esempio pratico: consideriamo un MNIST dataset → immagini di cifre (28x28) 60000 datapoint. Se
ingrandiamo la risoluzione (100x100, diventa vettore in riempiamo con pixel di valore zero ovvero
ℝ1000)
pixel bianchi che aumenta solo la dimensione dei dati. Apportiamo traslazione e rotazione casuali.
Possiamo vedere un'immagine come un vettore appiattito (flatten) di pixel.
Ogni immagine (datapoint) è un’osservazione in uno spazio di elevata dimensione. I dataset così generati
vivono in un sottospazio di dimensionalità intrinseca 3 perchè ha 3 gdl: due gradi di libertà per traslazione
(uno in x e uno in y) e uno per la rotazione; se aggiungessimo anche una scala, la dimensionalità sarebbe
4. È possibile bilanciare la riduzione della dimensionalità con la conservazione delle informazioni
essenziali; inoltre, possiamo trasformare i datapoint a stare nel loro sottospazio intrinseco e interpretare le
derivazioni da questo sottospazio come rumore ed eliminarle. Nella realtà dei dati, altre deformazioni sono
associate e il sottospazio è funzione di molti gradi di libertà.
La direzione di massima variazione è la componente principale che cattura la maggior parte della
variazione → problema affrontato tramite il concetto di varianza e tramite la sua massimizzazione. Se
voglio ridurre non vado ad agire sulla massima variazione perché voglio preservarla per non perdere
informazione in quanto la maggior parte del segnale varia in quel punto.
La PCA può essere definita come la proiezione ortogonale dei dati su uno spazio lineare inferiore, detto
sottospazio principale, tale che la varianza dei dati proiettati è massimizzata.
Se consideriamo un dataset con , l'obiettivo è proiettare i dati in uno spazio
{ } ∈
con M < D dove M è dato.
Il dataset (figura) può essere approssimato ignorando (PCA ignora, non elimina) la coordinata
2
ma non la poiché vi è bassa variazione lungo la coordinata e alta su . Ignorando il
1 2 1 1
dataset sarebbe totalmente diverso. Cerchiamo un cambio di coordinate in modo da trovare un
asse che catturi più varianza possibile.
La varianza è un indicatore della dispersione e il metodo utilizzato da PCA è massimizzare la
varianza nella rappresentazione.
Consideriamo la proiezione su uno spazio unidimensionale (M = 1).
Possiamo definire la direzione di questo spazio usando un vettore unitario (è di interesse
la sola direzione di , vettore a norma unitaria o versore) D-dimensionale u1 .
⇒
= 1
1 1 1
Ogni datapoint viene quindi proiettato e diventa uno scalare che rappresenta la
1
posizione del punto dati lungo l’asse . Si calcola quindi la varianza dei datapoint proiettati.
1 2
1
La varianza in generale si calcola: , dove è il valor medio dei datapoint
() = ∑ ( − )
=1 2
1
Se la applichiamo al dato proiettato otteniamo: che rappresenta la
∑ ( − ) =
1 1 1 1
1 =1
varianza dei dati proiettati (e ha forma bilineare).
1
Inoltre, la media dei dati proiettati è , dove è la media dei dati .
= ∑
1
=1
S è la matrice di covarianza (matrice simmetrica e sempre definita positiva) dei dati (non proiettati)
definita da:
1
= ∑ ( − )( − )
=1 2
Massimizzazione della varianza proiettata: subject to
|| || = 1
1 1 1
per evitare crescita indefinita → , si impone la condizione di normalizzazione , quindi
∞
|| || = 1
1 1 1
cerchiamo la direzione del versore e non di tutto il vettore. Questo problema si risolve trasformandolo in
1
uno analogo risolvibile con la cosiddetta Lagrangiana che include il moltiplicatore il problema diventa
⇒
λ
1
da massimizzazione vincolata (di difficile soluzione), uno più semplice non vincolato.
La soluzione finale si ottiene attraverso le derivate parziali di rispetto a e , il moltiplicatore (di
λ
1 1
Lagrange) tiene conto del vincolo imposto; i vincoli diventano moltiplicatori aggiunti alla funzione obiettivo.
Uguagliando a zero le due equazioni si ottiene:
I massimi sono nei punti stazionari.
Il problema originario di scegliere una direzione che massimizzi la varianza viene ricondotto ad un
1
problema autovalori/autovettori della matrice di covarianza dei dati.
Moltiplicando a sinistra per si vede il costo della massimizzazione della varianza che equivale a . La
λ
1 1
varianza dei dati proiettati su un sottospazio unidimensionale è uguale al suo autovalore associato .
λ
1
Il sottospazio di varianza massima è quello associato all’autovettore con autovalore più grande questo
⇒
autovettore è chiamato principal component.
3
Costo computazionale: ) = calcolo della scomposizione completa degli autovettori per una matrice di
(
dimensione ×
.
L’analisi delle componenti principali (PCA) implica:
1. calcolo media
2. calcolo matrice di covarianza
3. calcolo degli autovettori di corrispondenti agli autovalori più grandi.
Esempio d’uso PCA:
Passaggi p