Dopo aver introdotto le basi dell’algebra lineare, in questa lezione descriviamo l’algebra delle matrici. Approfondiamo come eseguire operazioni tra queste entità. Queste operazioni comprendono l’addizione e la moltiplicazione, che per le entità vettoriali seguono regole leggermente diverse rispetto a quelle per gli scalari. In questa lezione definiamo con precisione queste operazioni e includiamo alcuni esempi numerici per chiarire ogni passaggio.
L’Algebra delle Matrici
Potremmo non cogliere subito perché queste operazioni risultano utili nel contesto del deep learning. Tuttavia, nella lezione precedente abbiamo affermato che l’algebra lineare rappresenta il “linguaggio in cui scriviamo il machine learning”. Quando assimiliamo le basi di questo linguaggio, possiamo comprendere più facilmente i concetti complessi che costituiscono l’ossatura dei modelli di rete neurale, che approfondiremo nelle prossime lezioni.
Per introdurre l’algebra delle matrici cominciamo descrivendo la somma di matrici e poi introduciamo la moltiplicazione di matrici. Queste operazioni ci permettono di affrontare un argomento chiave noto come inversione di matrice, che costituirà il nucleo della prossima lezione.
Somma di matrice
La prima operazione dell’algebra delle matrici è la somma. Esploriamo tale operazione e osserviamo come, in realtà, risulti piuttosto intuitiva.
Possiamo sommare matrici a scalari, vettori e altre matrici. Ogni tipo di somma ha una definizione ben precisa. Queste tecniche ricorrono spesso nel machine learning e nel deep learning, quindi ci conviene familiarizzare con esse.
Addizione matrice-matrice
Consideriamo due matrici di dimensione \(m \times n\), \(\boldsymbol{A}=[a_{ij}]\) e \(\boldsymbol{B}=[b_{ij}]\). Definiamo la matrice \(\boldsymbol{C}=[c_{ij}]\) come somma di \(\boldsymbol{A}\) e \(\boldsymbol{B}\), ossia \(\boldsymbol{C} = \boldsymbol{A} + \boldsymbol{B}\) con \(c_{ij} = a_{ij} + b_{ij}\).
In altre parole, ogni elemento di C rappresenta la somma degli elementi corrispondenti delle due matrici. Questa operazione risulta possibile solo quando le matrici hanno la stessa dimensione, quindi C avrà dimensione \(m \times n\).
La somma di matrici è commutativa, cioè otteniamo lo stesso risultato indipendentemente dall’ordine con cui le sommiamo:
\(\begin{equation}\boldsymbol{A} + \boldsymbol{B} = \boldsymbol{B} + \boldsymbol{A}\end{equation}\)
Questa somma è anche associativa, quindi otteniamo lo stesso risultato sia che sommiamo prima due matrici e poi la terza, sia che invertiamo l’ordine dell’addizione:
\(\begin{equation}\boldsymbol{A} + (\boldsymbol{B} + \boldsymbol{C}) = (\boldsymbol{A} + \boldsymbol{B}) + \boldsymbol{C}\end{equation}\)
Entrambe queste proprietà derivano dalla somma scalare, che presenta anch’essa le proprietà commutativa e associativa, poiché sommiamo gli elementi delle matrici uno a uno.
Mettiamo in evidenza queste proprietà perché la moltiplicazione di matrici, che vedremo tra poco, non è commutativa.
Esempio
Consideriamo due matrici A e B. Calcoliamo la matrice C come somma:
\(\boldsymbol{A} + \boldsymbol{B} = \left[ \begin{array}{ccc}
1 & 4 & 17 \\
18 & 3 & 2 \\
5 & 19 & 1 \\
\end{array} \right] +
\left[ \begin{array}{ccc}
12 & 18 & 6 \\
4 & 3 & 33 \\
23 & 5 & 8 \\
\end{array} \right] =
\left[ \begin{array}{ccc}
13 & 22 & 23 \\
22 & 6 & 35 \\
28 & 24 & 9 \\
\end{array} \right] =
\boldsymbol{C}\)
Possiamo notare che gli elementi di C corrispondono alla somma dei valori di A e B nelle rispettive posizioni.
Somma matrice-scalare
Sommando un valore scalare x a una matrice \(\boldsymbol{A}=[a_{ij}]\), otteniamo una nuova matrice \(\boldsymbol{B}=[b_{ij}]\), dove \(b_{ij} = x + a_{ij}\). In pratica, aggiungiamo lo stesso valore scalare a ciascun elemento della matrice. Esprimiamo questa operazione con \(\boldsymbol{B} = x + \boldsymbol{A}\).
Nell’algebra delle matrici la somma tra uno scalare e una matrice mantiene le proprietà commutativa e associativa, in quanto la somma tra numeri reali gode anch’essa di queste proprietà.
Trasmissione
In alcune applicazioni di machine learning utilizziamo una notazione abbreviata chiamata broadcasting. Supponiamo di avere una matrice \(\boldsymbol{A} \in \mathbb{R}^{m \times n}\) e un vettore \(\boldsymbol{x} \in \mathbb{R}^m\).
Definiamo la somma \(\boldsymbol{B} = \boldsymbol{A} + \boldsymbol{x}\), anche se A e x hanno dimensioni diverse. In questo caso, calcoliamo \(b_{ij} = a_{ij} + x_j\).
Cioè, aggiungiamo ciascun elemento di x a ogni riga della matrice. Poiché il vettore viene “trasmesso” lungo ogni riga, chiamiamo questo processo broadcasting.
Moltiplicazioni di matrici
La seconda operazione dell’algebra delle matrici è la moltiplicazione. Le regole per la somma di matrici sono relativamente semplici e intuitive. Tuttavia, quando si tratta di moltiplicare le matrici, le regole diventano più complesse.
Matrice trasposta
Per definire alcune operazioni di moltiplicazione matrice-matrice come il prodotto scalare (discusso di seguito) è necessario definire la trasposizione di una matrice. La trasposizione di una matrice \(\boldsymbol{A}=[a_{ij}]_{m \times n}\) di dimensione \(n \times m\) è indicata come \(\boldsymbol{A}^{T}\) di dimensione \(n \times m\) e dal punto di vista degli elementi è definita come:
\(\begin{equation}\boldsymbol{A}^{T} = [a_{ji}]_{n \times m}\end{equation}\)
Cioè, gli indici i e j sono invertiti. Questo ha l’effetto di
riflettere la matrice lungo la linea degli elementi diagonali. L’operazione è definita per matrici non quadrate, così come per vettori e scalari (che sono semplicemente matrici 1×1). Per definizione è ovvio che la trasposizione di uno scalare è lo scalre stesso: \(x = x^T\). Inoltre la trasposizione della trasposta di una matrice corrisponde alla matrice stessa: \(\boldsymbol{A}^{TT} = \boldsymbol{A}\).
Esempi
\(\boldsymbol{A} = \left[ \begin{array}{ccc}
a_{11} & a_{12} & a_{13} \\
a_{21} & a_{22} & a_{23}
\end{array} \right], \quad
\boldsymbol{A}^T = \left[ \begin{array}{cc}
a_{11} & a_{21} \\
a_{12} & a_{22} \\
a_{13} & a_{23}
\end{array} \right]\)
\(\boldsymbol{x} = \left[ \begin{array}{c}
x_{1} \\
x_{2} \\
x_{3}
\end{array} \right], \quad
\boldsymbol{x}^T = \left[ \begin{array}{ccc}
x_{1} & x_{2} & x_3
\end{array} \right]\)
Sottolineiamo che \(\boldsymbol{A}^{T}\) non rappresenta A moltiplicata per se stessa T volte. Questa è un’operazione completamente diversa. Fortunatamente, di solito risulta chiaro dal contesto se intendiamo la trasposizione di una matrice o la moltiplicazione ripetuta per se stessa.
Moltiplicazione matrice-matrice
Nelle applicazioni dell’algebra delle matrici per il deep learning è molto importante le moltiplicazione matrice-matrice. Questa è un’operazione più complessa della somma di matrici perché non consiste semplicemente nella moltiplicazione elemento per elemento delle matrici. Si usa invece una procedura più complessa, per ogni elemento, che coinvolge un’intera riga di una matrice e un’intera colonna dell’altra.
L’operazione è prevista solo per matrici di specifiche dimensioni. La prima matrice deve avere tante colonne quante sono le righe della seconda matrice, altrimenti l’operazione non è possibile.
La definizione seguente può essere un po’ difficile da capire inizialmente, quindi consigliamo di leggere attentamente e quindi provare ad applicare la procedura attraverso gli esempi per vedere come le istanze numeriche specifiche corrispondono alla formula generale.
Data una matrice \(\boldsymbol{A}=[a_{ij}]_{m \times n}\) e una matrice \(\boldsymbol{B}=[b_{ij}]_{n \times p}\) il prodotto di matrice \(\boldsymbol{C}=\boldsymbol{A}\boldsymbol{B}=[c_{ij}]_{m \times p}\) è definito elemento per elemento come:
\(\begin{equation}
c_{ij} = \sum^n_{k=1} a_{ik} b_{kj}
\end{equation}\)
In altre parole gli elementi \(c_{ij}\) della matrice \(\boldsymbol{C}=\boldsymbol{A}\boldsymbol{B}\) sono ricavati sommando i prodotti degli elementi dell’i-esima fila di A con gli elementi della j-esima colonna di B.
Da notare che la moltiplicazione matrice-matrice non gode della proprietà commutativa, cioè:
\(\begin{eqnarray}
\boldsymbol{A}\boldsymbol{B} \neq \boldsymbol{B}\boldsymbol{A}
\end{eqnarray}\)
Esempi
Date le due matrici seguenti:
\(\boldsymbol{A} = \left[ \begin{array}{ccc}
2 & 5 & 1 \\
7 & 3 & 6
\end{array} \right], \quad
\boldsymbol{B} = \left[ \begin{array}{cc}
1 & 8 \\
9 & 4 \\
3 & 5
\end{array} \right]\)
È possibile costruire il prodotto AB di dimensione 2×2:
\(\boldsymbol{AB} = \left[ \begin{array}{cc}
2 \cdot 1 + 5 \cdot 9 + 1 \cdot 3 & 2 \cdot 8 + 5 \cdot 4 + 1 \cdot 5 \\
7 \cdot 1 + 3 \cdot 9 + 6 \cdot 3 & 7 \cdot 8 + 3 \cdot 4 + 6 \cdot 5
\end{array} \right] =
\left[ \begin{array}{cc}
50 & 41 \\
52 & 98
\end{array} \right]\)
È anche possibile costruire il prodotto BA di dimensione 3×3:
\(\boldsymbol{BA} = \left[ \begin{array}{ccc}
1 \cdot 2 + 8 \cdot 7 & 1 \cdot 5 + 8 \cdot 3 & 1 \cdot 1 + 8 \cdot 6 \\
9 \cdot 2 + 4 \cdot 7 & 9 \cdot 5 + 4 \cdot 3 & 9 \cdot 1 + 4 \cdot 6 \\
3 \cdot 2 + 5 \cdot 7 & 3 \cdot 5 + 5 \cdot 3 & 3 \cdot 1 + 5 \cdot 6 \\
\end{array} \right] =
\left[ \begin{array}{ccc}
58 & 29 & 49 \\
46 & 57 & 33 \\
41 & 30 & 33
\end{array} \right]\)
La definizione di cui sopra inizialmente non sembra essere definita in modo semplice. La moltiplicazione matrice-matrice è definita in questo modo perchè nel dominio dell’algebra delle matrici rappresentano funzioni di mappa lineare tra due spazi vettoriali. Non dobbiamo preoccuparci dei concetti relativi alle mappe lineari poiché esulano dallo scopo di questa serie di articoli.
Composizione delle funzioni
Tuttavia, possiamo fornire brevemente alcune definizioni attraverso l’idea di comporre insieme le funzioni. In matematica è possibile comporre insieme due funzioni e produrre una nuova funzione. la nuova funzione h può essere definita come \(h = f \circ g\), dove il simbolo \(\circ\) rappresenta la composizione delle funzioni. Questa notazione significa che h è l’applicazione di g e poi l’applicazione di f al risultato.
Se, per esempio, \(f=sin(x)\) e \(g=x^2\) allora \(h = sin(x^2)\). La composizione delle funzioni non è commutativa quindi \(f \circ g \neq g \circ f\) quindi \(g \circ f = sin^2 (x) è una funzione completamente diversa. Questo è il motivo per cui la moltiplicazione matrice-matrice non è commutativa e anche perché è definita come sopra.
Si noti inoltre che questa definizione non implica che gli elementi della matrice A sono definiti come la moltiplicazione elemento per elemento di quelli di A e B, cioè gli elementi in ogni posizione non possono essere semplicemente moltiplicati insieme per ottenere la nuova matrice del prodotto. Questa è un’operazione completamente diversa nota come Prodotto Hadamard che è descritta nei paragrafi successivi.
Dato che un vettore colonna è una matrice n x 1 allora è possibile effettuare la moltiplicazione matrice-vettore. Se la matrice di moltiplicazione a sinistra ha dimensione m x n allora questa è un’operazione valida che produce un’altra matrice m x 1 (vettore colonna) come output.
La moltiplicazione matrice-matrice e vettore-matrice sono operazioni estremamente comuni nei campi delle scienze fisiche, della grafica computazionale e del machine learning. Sono state sviluppate librerie software altamente ottimizzate come BLAS e LAPACK per consentire un efficiente calcolo scientifico, in particolare con le GPU.
Moltiplicazione matrice-scalare
La moltiplicazione matrice-scalare è più semplice rispetto alla moltiplicazione tra matrici. Data una matrice \(\)\boldsymbol{A}=[a_{ij}]_{m \times n} e uno scalare \(\)\lambda \in \mathbb{R}\) il prodotto a matrice scalare \(\lambda \boldsymbol{A}\) si calcola moltiplicando ogni elemento di \(\boldsymbol{A}\) per \(\lambda\) tale che \(\lambda \boldsymbol{A} = [\lambda a_{ij}]_{m \times n}\)
Se consideriamo due scalari a valori reali \(\lambda, \mu \in \mathbb{R}\) allora dalle definizione derivano le seguenti relazioni:
\(\begin{eqnarray}
\lambda (\boldsymbol{A} + \boldsymbol{B}) &=& \lambda \boldsymbol{A} + \lambda \boldsymbol{B} \\
(\lambda + \mu) \boldsymbol{A} &=& \lambda \boldsymbol{A} + \mu \boldsymbol{A} \\
\lambda (\mu \boldsymbol{A}) &=& (\lambda \mu) \boldsymbol{A}
\end{eqnarray}\)
La prima relazione afferma che la somma di due matrici moltiplicata per uno scale corrisponde alla moltiplicazione individuale di ciascuna matrice per lo scalare e poi sommate insieme.
La seconda relazione afferma che la somma di due scalari moltiplicata per una matrice corrisponde alla somma dei risultati delle singole moltiplicazioni dei due scalari per la matrice.
La terza relazione afferma che l’ordine della moltiplicazione scalare non ha importanza. Se moltiplichiamo la matrice per uno scalare e quindi moltiplichiamo il risultato per un altro scalare, corrisponde alla moltiplicazione di entrambi gli scalari e poi per la matrice.
Tutti questi risultati derivano dalle semplici regole di moltiplicazione e addizione scalare.
Prodotto Hadamard
Nell’algebra delle matrici è possibile definire la moltiplicazione di matrici elemento per elemento, che differisce dalla definizione di moltiplicazione matrice-matrice sopra. Il prodotto di Hadamard di due matrici \(\boldsymbol{A}=[a_{ij}]_{m \times n}\) e \(\boldsymbol{B}=[b_{ij}]_{m \times n}\), indicato come \(\boldsymbol{A} \odot \boldsymbol{B}\), è definito dalla seguente espressione:
\(\begin{equation}
\boldsymbol{A} \odot \boldsymbol{B} = [a_{ij} b_{ij}]_{m \times n}
\end{equation}\)
Cioè, gli elementi della nuova matrice sono calcolati semplicemente come moltiplicazione scalare di ciascuno degli elementi delle matrici. Da notare che il prodotto di Hadamard gode della proprietà commutativa, dato che è anche la moltiplicazione scalare, a differenza della normale moltiplicazione matrice-matrice.
Quando è necessario utilizzare il prodotto Hadamard? In effetti, un tale operatore ha ampie applicazioni, tra cui la correzione dei codici nelle trasmissioni satellitari e nella crittografia, l’elaborazione dei segnali e gli algoritmi di compressione con perdita di immagini in formato JPEG.
Prodotto scalare
Un particolare caso di moltiplicazione matrice-matrice da sottolineare si verifica tra due vettori ed è noto come prodotto scalare. Ha una profonda relazione con la geometria ed è utile in tutte le aree delle scienze fisiche e computazionali.
Dobbiamo essere estremamente attenti per quanto riguarda la notazione. Dobbiamo essere particolarmente precisi per questa definizione, che per alcuni di voi potrebbe essere insolita. In realtà il prodotto scalare è definito come una particolare moltiplicazione matrice-matrice, dove uno dei vettori è una “matrice” con una riga e l’altro una “matrice” con una colonna. Tuttavia, spesso si ha un leggero “abuso di notazione” per cui si definisce il prodotto scalare per due vettori qualsiasi (riga o colonna).
La definizione standard di un prodotto scalare tra due vettori \(\boldsymbol{x}, \boldsymbol{y} \in \mathbb{R}^n\) di n dimensioni è \(\boldsymbol{x} \cdot \boldsymbol{y}\), da cui deriva il nome dell’operazione. Tuttavia nei libri di testo più avanzati (in particolare i popolari testi di statistica, machine learning e deep learning) è definito come \(\boldsymbol{x}^T \boldsymbol{y}\) dove T rappresenta la trasposizione di x.
Questo perché x e y sono generalmente considerati entrambi vettori colonna. Una moltiplicazione matrice-matrice tra due vettori colonna non è definita, quindi uno dei vettori deve essere trasposto in un vettore riga in modo tale che la moltiplicazione matrice-matrice sia correttamente definita. La notazione \(\boldsymbol{x}^T \boldsymbol{y}\) è frequentemente usata nei libri accademici e articoli più avanzati. Vediamo ora i dettagli della definizione!
Dati due vettori colonna \(\boldsymbol{x}, \boldsymbol{y} \in \mathbb{R}^n\) è possibile definire il prodotto scalare tra di loro prendendo la trasposizione di uno per formare un prodotto che è definito all’interno delle regole di moltiplicazione matrice-matrice. Tale prodotto produce un valore scalare che gode della proprietà commutativa:
\(\begin{equation}
\boldsymbol{x}^T \boldsymbol{y} = \sum^n_{i=1} x_i y_i = \boldsymbol{y}^T \boldsymbol{x}
\end{equation}\)
Il prodotto scalare ha un importante significato geometrico. È il prodotto delle distanze euclidee dei due vettori e del coseno dell’angolo tra di loro. Negli articoli successivi introduciamo il concetto di norma, dove formalizziamo la definizione.
Un altro modo di pensare al prodotto scalare è considerare il prodotto scalare di un vettore con se stesso come il quadrato della distanza del vettore:
\(\begin{equation}
\boldsymbol{x}^T \boldsymbol{x} = \sum^n_{i=1} x_i x_i = \sum^n_{i=1} x_i^2
\end{equation}\)
Quindi per trovare la distanza (euclidea) di un vettore possiamo semplicemente prendere la radice quadrata del prodotto scalare del vettore, \(\sqrt{\boldsymbol{x}^T \boldsymbol{x}}\).
Il prodotto scalare è un caso particolare di un’entità matematica più generale nota come prodotto interno. In spazi vettoriali più astratti il prodotto interno consente di rendere rigorosi concetti intuitivi come la lunghezza e l’angolo di un vettore. Tuttavia, tali spazi esulano dallo scopo di questa serie di articoli.
Conclusione
Questa lezione è stata dedicata all’algebra delle matrici e alle operazioni applicate a una o più matrici. Possiamo ora sommare e moltiplicare matrici tra di loro. Ma cosa otteniamo con questo? Come possiamo usarlo?
Nella prossima lezione esaminiamo uno degli argomenti più fondamentali dell’algebra lineare: l’inversione di una matrice. L’inversione di matrice ci consente di risolvere equazioni di matrici, esattamente nello stesso modo in cui l’algebra scalare ci consente di risolvere equazioni scalari.
Questa è un’operazione molto diffusa nelle scienze fisiche e computazionali ed è indispensabile negli studi di deep learning.
Riferimenti
- [1] Blyth, T.S. and Robertson, E.F. (2002) Basic Linear Algebra, 2nd Ed., Springer
- [2] Strang, G. (2016) Introduction to Linear Algebra, 5th Ed., Wellesley-Cambridge Press
- [3] Goodfellow, I.J., Bengio, Y., Courville, A. (2016) Deep Learning, MIT Press