Cos'è un Tensore e come viene utilizzato nel Machine Learning?

I tensori sono fondamentali in molte tecniche di machine learning, soprattutto nel deep learning. Grazie alla loro struttura e alla capacità di lavorare con GPU e altre unità di calcolo ad alte prestazioni, i tensori consentono di rappresentare e manipolare dati complessi, come immagini, audio e testo. In questo articolo, esploreremo cosa sono i tensori, come funzionano e perché sono così importanti nell'apprendimento automatico.

Definizione di Tensore

Un tensore è una struttura di dati multidimensionale che rappresenta insiemi di dati di vario tipo, come vettori e matrici, ma in più dimensioni. È simile a un array di Numpy, con la differenza che è progettato per sfruttare l'accelerazione hardware, rendendolo ideale per operazioni complesse eseguite su GPU (come le GPU NVIDIA o Intel, nelle versioni più recenti di PyTorch).

I tensori permettono di rappresentare dati in vari formati:

  • Scalare (0D): un singolo numero, come 5.5. È un tensore di dimensione 0, o un tensore “scalare”.
  • Vettore (1D): un array monodimensionale, come [1, 2, 3]. È un tensore di dimensione 1.
  • Matrice (2D): una tabella bidimensionale, come [[1, 2, 3], [4, 5, 6]]. È un tensore di dimensione 2.
  • Tensore 3D e oltre: un array con tre o più dimensioni, come [[[1, 2], [3, 4]], [[5, 6], [7, 8]]]. È un tensore di dimensione 3 o superiore.

Struttura e Caratteristiche dei Tensori

La struttura di un tensore può essere descritta da:

  • Dimensione (Rank): rappresenta il numero di dimensioni (o assi) del tensore.
  • Forma (Shape): rappresenta la lunghezza (numero di elementi) in ciascuna dimensione. Ad esempio, per una matrice 2D con 2 righe e 3 colonne, la forma è (2, 3).

Queste caratteristiche sono fondamentali perché consentono di rappresentare e manipolare diversi tipi di dati. Ad esempio, un'immagine RGB di dimensione 64x64 pixel potrebbe essere rappresentata come un tensore 3D con la forma (3, 64, 64), dove i 3 canali rappresentano rispettivamente i colori rosso, verde e blu.

Creazione e Manipolazione di Tensori in PyTorch

In PyTorch, i tensori possono essere creati e manipolati facilmente. Ecco alcuni esempi di creazione di tensori:

Tensore scalare:

codiceimport torch scalar = torch.tensor(3.14) print(scalar)

Tensore vettore:

vector = torch.tensor([1.0, 2.0, 3.0]) print(vector)

Tensore matrice:

matrix = torch.tensor([[1, 2, 3], [4, 5, 6]]) print(matrix)

Tensore tridimensionale per immagini:

tensor_3d = torch.tensor([[[1, 2], [3, 4]], [[5, 6], [7, 8]]]) print(tensor_3d)

Un tensore tridimensionale può rappresentare una serie di immagini, ma in ambito di deep learning, si utilizza spesso un tensore 4D per batch di immagini. In un tensore 4D, le dimensioni sono:

  • batch_size: numero di immagini nel batch.
  • channels: numero di canali di colore (1 per immagini in scala di grigi, 3 per RGB).
  • height e width: dimensioni dell’immagine.

Ad esempio, un batch di due immagini RGB 3x3 si può rappresentare così:

images = torch.tensor([ [[[255, 0, 0], [255, 255, 0], [0, 255, 0]], [[0, 0, 255], [0, 255, 255], [0, 0, 255]], [[255, 255, 255], [128, 128, 128], [0, 0, 0]]], [[[0, 0, 0], [128, 128, 128], [255, 255, 255]], [[255, 0, 255], [255, 255, 0], [0, 255, 0]], [[0, 0, 255], [255, 255, 255], [128, 128, 128]]] ])

Questo tensore ha forma (2, 3, 3, 3), con:

  • 2 immagini nel batch.
  • 3 canali (RGB).
  • Immagini di 3x3 pixel.

Uso dei Tensori con le GPU

Uno dei vantaggi principali dei tensori è che possono essere elaborati sia su CPU che su GPU. Trasferire un tensore su GPU è semplice in PyTorch e rende le operazioni molto più rapide. Ad esempio, per trasferire un tensore su una GPU NVIDIA:

tensor = torch.tensor([1.0, 2.0]).to("cuda")

Nelle versioni recenti, come PyTorch 2.5, è stato introdotto il supporto anche per le GPU Intel. In questo caso, si usa "xpu" per specificare che il tensore deve essere trasferito su una GPU Intel:

tensor = torch.tensor([1.0, 2.0]).to("xpu")

Tensore come Contenitore di Dati Temporaneo

In molti modi, un tensore può essere considerato simile a un "database temporaneo" che organizza e gestisce i dati per l'elaborazione. Tuttavia, un database è ottimizzato per archiviazione e interrogazione, mentre un tensore è progettato per gestire calcoli numerici intensivi:

  • Efficienza: i tensori permettono di eseguire operazioni complesse in modo ottimizzato grazie alla loro struttura e al supporto hardware.
  • Parallelismo: i tensori possono essere calcolati in parallelo su migliaia di processori GPU.
  • Elasticità multi-dimensionale: i tensori permettono di rappresentare dati con molte dimensioni, rendendo possibile lavorare con batch di dati complessi, come immagini e sequenze temporali.
Un tensore non è un modello, ma una struttura di dati utilizzata all'interno dei modelli di machine learning e deep learning per rappresentare e manipolare i dati.

Differenza tra Tensore e Modello

  • Tensore: è una struttura che memorizza i dati in forma multidimensionale e permette di eseguire operazioni matematiche su di essi. Ad esempio, i tensori possono contenere immagini, testo, o dati numerici usati per addestrare un modello.
  • Modello: è una costruzione algoritmica che prende i dati (in forma di tensori) e li elabora per fare previsioni, classificazioni o generare risposte. I modelli di machine learning utilizzano funzioni matematiche (come reti neurali, alberi decisionali, regressione lineare) che vengono addestrate e ottimizzate sui dati per migliorare le loro prestazioni.

Come interagiscono

Il modello si "allena" usando i tensori:

  1. I tensori rappresentano i dati di input (es. immagini, testi, numeri) e le etichette associate (es. “gatto” o “cane” per classificazione delle immagini).
  2. Durante l'addestramento, il modello elabora questi tensori per imparare una funzione che mappa gli input agli output desiderati.
  3. Una volta addestrato, il modello può ricevere nuovi tensori (nuovi dati) per fare previsioni.

I modelli rilasciati da LLaMA (Large Language Model Meta AI), come altri modelli di linguaggio di grandi dimensioni (LLM), sono una combinazione di tensori e algoritmi. Vediamo come funziona questa combinazione:

Tensori per la rappresentazione dei dati e dei parametri:

  • In un modello come LLaMA, ogni parametro (peso e bias delle reti neurali) è rappresentato tramite tensori. Questi tensori memorizzano i valori numerici che il modello usa per effettuare calcoli e prendere decisioni.
  • Anche i dati di input (come il testo in linguaggio naturale) vengono trasformati in tensori. Ad esempio, ogni parola o frammento di frase viene codificato in vettori numerici tramite una tecnica chiamata embedding, per poter essere elaborato dal modello.

Algoritmi per l’elaborazione e l’apprendimento:

  • L'architettura di LLaMA è basata su una rete neurale profonda, specificamente un trasformatore (Transformer). Questo è un tipo di algoritmo che sfrutta operazioni sui tensori per apprendere le relazioni tra parole, frasi e contesti linguistici.
  • Gli algoritmi usati nel modello specificano come i dati rappresentati nei tensori vengono elaborati. Ad esempio, nel trasformatore, ci sono meccanismi come l'attenzione (attention) che aiutano il modello a "concentrarsi" su parti specifiche del testo in base al contesto.

Modello pre-addestrato e fine-tuning:

  • LLaMA e altri LLM sono addestrati su enormi quantità di testo e ottimizzati per minimizzare l'errore nei risultati. Durante l'addestramento, il modello regola i valori nei tensori dei parametri per migliorare le sue risposte.
  • Questo processo, chiamato addestramento o training, è un processo iterativo in cui i tensori vengono aggiornati per migliorare le capacità del modello. Dopo l’addestramento, il modello può essere ulteriormente raffinato (fine-tuned) per compiti specifici.