Uno degli aspetti più delicati nella computazione legata a modelli di deep learning è relativa al numero enorme di parametri, dati e calcoli coinvolti, organizzati in modo pratico in vettori e matrici, e al relativo calcolo del gradiente della funzione di costo rispetto a tali parametri.

E' quindi opportuno capire come impostare in modo efficiente i calcoli nel grafo computazionale del modello, applicando correttamente la chain rule e ricavando in modo elegante i gradienti anche rispetto a grandezze di tipo vettoriale e matriciale - passaggio essenziale nello sviluppo della backpropagation e della vettorizzazione del training set per processare batch di dati senza essere costretti ad iterare per ogni singolo campione.

Utilizziamo in seguito una notazione semplificata, indicando con \(\text d \boldsymbol x \) il gradiente di una nostra funzione costo \(J\) rispetto alla grandezza \(\boldsymbol x\)  della quale conserverà ovviamente le stesse dimensioni per essere utilizzata direttamente negli algoritmi della discesa del gradiente.

Proponiamo subito una pratica tabella riassuntiva di sviluppo di gradienti utili nella backprogation per modelli di reti neurali densamente connesse (Fully Connected), calcolati rispetto a un gradiente noto \(\text d \boldsymbol z\) 

Per ogni voce è sviluppato in calce il calcolo di dettaglio, sebbene quasi tutti i casi possano essere derivati dal caso generale del calcolo di \(\text d \boldsymbol W \ \) per \(\boldsymbol Z_{(n \times p)} = \boldsymbol W_{(n \times m)} \boldsymbol X_{(m \times p)} \)

 

\(\boldsymbol z_{(n \times 1)} = \boldsymbol W_{(n \times m)} \boldsymbol x_{(m \times 1)}\) \(\text d \boldsymbol x_{(m \times 1)} = {\boldsymbol W}^\top_{(m \times n)} \text d {\boldsymbol z}_{(n \times 1)}\)
\(\boldsymbol z_{(1 \times n)} = \boldsymbol x_{(1 \times m)} \boldsymbol W_{(m \times n)} \) \(\text d \boldsymbol x_{(1 \times m)} = \text d {\boldsymbol z}_{(1 \times n)} {\boldsymbol W}^\top_{(n \times m)}\)
\(\boldsymbol Z = \boldsymbol X\) \(\text d \boldsymbol X = \text d \boldsymbol Z \ \)
\(Z_{ij} = f(Z_{ij})\) \(\text d \boldsymbol X = \text d \boldsymbol Z * f'(\boldsymbol X)\)
\(\boldsymbol z_{(n \times 1)} = \boldsymbol W_{(n \times m)} \boldsymbol x_{(m \times 1)}\) \(\text d \boldsymbol W_{(n \times m)} = \text d \boldsymbol z_{(n \times 1)} \ \boldsymbol x^\top_{(1 \times m)} \)
\(\boldsymbol z_{(1 \times n)} = \boldsymbol x_{(1 \times m)} \boldsymbol W_{(m \times n)} \) \(\text d \boldsymbol W_{(m \times n)} = \boldsymbol x^\top_{(m \times 1)} \text d \boldsymbol z_{(1 \times n)} \)
\(\boldsymbol Z_{(n \times p)} = \boldsymbol W_{(n \times m)} \boldsymbol X_{(m \times p)} \) \(\text d \boldsymbol W_{(n \times m)} = \text d \boldsymbol Z_{(n \times p)} \ \boldsymbol X^\top_{(p \times m)}\)
\(\boldsymbol Z_{(n \times p)} = \boldsymbol X_{(n \times m)} \boldsymbol W_{(m \times p)} \) \(\text d \boldsymbol W_{(m \times p)} = \boldsymbol X^\top_{(m \times n)} \text d \boldsymbol Z_{(n \times p)} \ \)
\(\boldsymbol Z=\text{softmax}(\boldsymbol X) \\ J=\text CE(\boldsymbol Z, \boldsymbol Y)\) \(\text d \boldsymbol X = \boldsymbol {(Z-Y)}\)

 

Jacobiano

Partiamo dalla definizione di jacobiano, che generalizza il concetto di derivata a una funzione \(\Bbb R^n \rightarrow \Bbb R^m\) e al quale è possibile applicare la chain rule in modo assolutamente trasparente:

Sia \(\boldsymbol f : \Bbb R^n \rightarrow \Bbb R^m \ \ , \ \ \boldsymbol f (\boldsymbol {x} )= \left[ f_1(x_1 \cdots x_n), \cdots, f_m(x_1 \cdots x_n) \right]\)

Definiamo quindi il jacobiano  \(\frac{\partial \boldsymbol f}{\partial \boldsymbol x}=\begin{bmatrix} \frac{\partial f_1}{\partial x_1} & \cdots & \frac{\partial f_1}{\partial x_n} \\ \vdots & \ddots & \vdots \\ \frac{\partial f_m}{\partial x_1} & \cdots & \frac{\partial f_m}{\partial x_n} \end{bmatrix} = \begin{bmatrix} \frac{\partial \boldsymbol f}{\partial x_1} & \cdots & \frac{\partial \boldsymbol f}{\partial x_n} \end{bmatrix} = \begin{bmatrix} \nabla f_1^\top \\ \vdots \\ \nabla f_m^\top \end{bmatrix} \)

Come detto il jacobiano supporta pienamente la chain rule, per cui è facile verificare che se \(\boldsymbol f : \Bbb R^n \rightarrow \Bbb R^m\)  e  \(\boldsymbol g : \Bbb R^m \rightarrow \Bbb R^l\)  allora \(\frac{\partial \boldsymbol g(\boldsymbol f(\boldsymbol x))}{\partial \boldsymbol x} = \frac{\partial \boldsymbol g}{\partial \boldsymbol f}\frac{\partial \boldsymbol f}{\partial \boldsymbol x}\)

Notiamo che il jacobiano è la trasposta del gradiente, per cui, ogni qualvolta avremo un jacobiano esplicitamente direttamente coinvolto nel calcolo del gradiente, dovremo fare attenzione a verificare che la dimensione del gradiente sia quella effettivamente attesa e nel caso applicare la trasposizione - in particolare quando operiamo con vettori colonna.

 

\(\boldsymbol z_{(n \times 1)} = \boldsymbol W_{(n \times m)} \boldsymbol x_{(m \times 1)}\) : jacobiano \(\frac{\partial \boldsymbol z}{\partial \boldsymbol x} \) e gradiente \(\text d \boldsymbol x \)

In questo caso abbiamo che \(\displaystyle z_i=\sum_{i=1}^m W_{ij} x_j\)  e \(\frac{\partial z_i}{\partial x_j} = W_{ij}\) , pertanto avremo un jacobiano \(\displaystyle \frac{\partial \boldsymbol z}{\partial \boldsymbol x}={\boldsymbol W} \ \).

Attraverso la chain rule tra jacobiani \(\frac{\partial J}{\partial \boldsymbol x}=\frac{\partial J}{\partial \boldsymbol z}\frac{\partial \boldsymbol z}{\partial \boldsymbol x}=\frac{\partial J}{\partial \boldsymbol z}\boldsymbol W \ \)

Vediamo ora per riprova il calcolo del gradiente, che ci attendiamo essere ricavabile dalla trasposta dello jacobiano. 
 

\(\text d \boldsymbol x = \begin{bmatrix} \frac{\partial J}{\partial x_1} \\ \vdots \\ \frac{\partial J}{\partial x_m} \end{bmatrix}\) e  \(\text d \boldsymbol z = \begin{bmatrix} \frac{\partial J}{\partial z_1} \\ \vdots \\ \frac{\partial J}{\partial z_n} \end{bmatrix}\)  e per la regola della chain rule \(\frac{\partial J}{\partial x_j}=\sum_{i=1}^n \frac{\partial J}{\partial z_i}\frac{\partial z_i}{\partial x_j}=(W_{:j})^\top \text d \boldsymbol z \ \) , e quindi concludiamo esplicitando le dimensioni che:

\(\text d \boldsymbol x_{(m \times 1)} = \begin{bmatrix} (W_{:1})^\top \text d \boldsymbol z \\ \vdots \\ (W_{:m})^\top \text d \boldsymbol z \end{bmatrix} = {\boldsymbol W}^\top_{(m \times n)} \text d {\boldsymbol z}_{(n \times 1)}\)

a conferma della relazione di trasposizione tra jacobiano e gradiente.

 

\(\boldsymbol z_{(1 \times n)} = \boldsymbol x_{(1 \times m)} \boldsymbol W_{(m \times n)} \) : jacobiano \(\frac{\partial \boldsymbol z}{\partial \boldsymbol x} \) e gradiente \(\text d \boldsymbol x \)

In questo caso abbiamo che \(\displaystyle z_i=\sum_{i=1}^m W_{ji} x_j\)  e \(\frac{\partial z_i}{\partial x_j} = W_{ji}\) , pertanto avremo un jacobiano \(\displaystyle \frac{\partial \boldsymbol z}{\partial \boldsymbol x}={\boldsymbol W}^\top \ \).

Attraverso la chain rule tra jacobiani \(\frac{\partial J}{\partial \boldsymbol x}=\frac{\partial J}{\partial \boldsymbol z}\frac{\partial \boldsymbol z}{\partial \boldsymbol x}=\frac{\partial J}{\partial \boldsymbol z}\boldsymbol W^\top \ \)

Vediamo ora per riprova il calcolo del gradiente. Abbiamo:
\(\text d \boldsymbol x = \begin{bmatrix} \frac{\partial J}{\partial x_1} \ \cdots \ \frac{\partial J}{\partial x_m} \end{bmatrix}\) e  \(\text d \boldsymbol z = \begin{bmatrix} \frac{\partial J}{\partial z_1} \ \cdots \ \frac{\partial J}{\partial z_n} \end{bmatrix}\)  e per la regola della chain rule \(\displaystyle \frac{\partial J}{\partial x_j}=\sum_{i=1}^n \frac{\partial J}{\partial z_i}\frac{\partial z_i}{\partial x_j}= \text d \boldsymbol z \ (\boldsymbol W_{j:})^\top\) , e quindi concludiamo esplicitando le dimensioni che:

\(\text d \boldsymbol x_{(1 \times m)} = \begin{bmatrix} \text d \boldsymbol z \ (\boldsymbol W_{1:})^\top \ \cdots \ \text d \boldsymbol z \ (\boldsymbol W_{m:})^\top \end{bmatrix} = \text d {\boldsymbol z}_{(1 \times n)} {\boldsymbol W}^\top_{(n \times m)}\)

 

\(\boldsymbol z = \boldsymbol x\) : jacobiano \(\frac{\partial \boldsymbol z}{\partial \boldsymbol x} \) e gradiente \(\text d \boldsymbol x \)

In questo caso \(\frac{\partial z_i}{\partial x_j} = \begin{cases} 0 \ \text {se} \ i \ne j \\ 1 \ \text {se} \ i = j \end{cases}\) pertanto \(\frac { \partial \boldsymbol z}{\partial \boldsymbol x} = \bf I \ \)

Per quanto riguarda il gradiente è immediato che \(\text d \boldsymbol x = \text d \boldsymbol z \ \)

 

\(z_i = f(x_i)\) : jacobiano \(\frac{\partial \boldsymbol z}{\partial \boldsymbol x} \) e gradiente \(\text d \boldsymbol x \)

Ipotizziamo di avere una funzione \(f:\Bbb R \rightarrow \Bbb R\) applicata ad ogni componente del vettore \(\boldsymbol x\)

In questo caso \(\frac{\partial z_i}{\partial x_j} = \begin{cases} 0 \ \text {se} \ i \ne j \\ f'(x_i) \ \text {se} \ i = j \end{cases}\) pertanto \(\frac { \partial \boldsymbol z}{\partial \boldsymbol x} = \text {diag} (f'(\boldsymbol {x} ))\)

Per quanto riguarda il gradiente, ipotizzando due vettori colonna, abbiamo \(\displaystyle \frac{\partial J}{\partial x_j}=\sum_{i=1}^n \frac{\partial J}{\partial z_i}\frac{\partial z_i}{\partial x_j}= \text d z_j \ f'(x_j)\) 

e quindi \(\text d \boldsymbol x = \text d \boldsymbol z * f'(\boldsymbol x)\)  , dove l'operatore \(*\) effettua una moltiplicazione componente per componente delle due grandezze.

Il risultato relativo al gradiente è valido anche se consideriamo \(\boldsymbol {Z, X} \in \Bbb R^{n \times m}\) infatti \(\frac{\partial Z_{ij}}{\partial X_{kl}}=\begin{cases} 0 \ \text se \ i,j \ne k,l \\ f'(X_{ij})\ \text se\ i,j=k,l \end{cases}\) e quindi

\(\displaystyle \frac{\partial J}{\partial X_{kl}}=\sum_{i=1}^m \sum_{j=1}^n \frac{\partial J}{\partial Z_{ij}} \frac{\partial Z_{ij}}{\partial X_{kl}}= \text d Z_{kl} f'(X_{kl})\)   che infatti porta ad un gradiente \(\text d \boldsymbol X = \text d \boldsymbol Z * f'(\boldsymbol X )\)

 

\(\boldsymbol z_{(n \times 1)} = \boldsymbol W_{(n \times m)} \boldsymbol x_{(m \times 1)}\) : jacobiano \(\frac{\partial \boldsymbol z}{\partial \boldsymbol W} \) e gradiente \(\text d \boldsymbol W\)

In questo caso e nei successivi dove andremo a calcolare il gradiente rispetto a grandezze strutturate in matrici, andremo convenientemente a definire il ns.gradiente con la stessa dimensione della struttra originaria, cosa che ne permetterà anche l'utilizzo in modo diretto negli algoritimi di discesa del gradiente:

\(\text d \boldsymbol W = \begin{bmatrix} \text d W_{11} & \cdots & \text d W_{1n} \\ \vdots & \ddots & \vdots \\ \text d W_{m1} & \cdots & \text d W_{mn} \end{bmatrix}\). Questo tipo di organizzazione tuttavia rende problematica la definizione diretta dello jacobiano \(\frac{\partial \boldsymbol z}{\partial \boldsymbol W} \)che si attende invece un vettore di dimensione \(m n\) e non una matrice, che darebbe teoricamente origine a un jacobiano in forma di tensore.

Per tale motivo ci focalizziamo direttamente sul calcolo del gradiente \(\text d \boldsymbol W\)  e delle singole componenti \(\frac {\partial z_k}{\partial W_{ij}} \)senza entrare nella esplicitazione della struttura dello jacobiano.

Abbiamo innanzitutto che \(\displaystyle z_k=\sum_{l=1}^m W_{kl}x_l\)  e quindi  \(\displaystyle \frac {\partial z_k}{\partial W_{ij}} =\begin{cases} 0 \ \ se \ \ k \ne i \\ x_j \ se \ \ k = i \end{cases} \) che possiamo anche scrivere come

\(\frac {\partial \boldsymbol z}{\partial W_{ij}}=\begin{bmatrix} \boldsymbol 0 \\ x_j \\ \boldsymbol 0 \end{bmatrix} \leftarrow i \text {-ma riga}\)    e applicando la chain rule \(\displaystyle \frac{\partial J}{\partial W_{ij}}=\frac{\partial J}{\partial \boldsymbol z}\frac{\partial \boldsymbol z}{\partial W_{ij}}=\sum_{k=1}^n \frac{\partial J}{\partial z_k}\frac{\partial z_k}{\partial W_{ij}}=\text d z_i \ x_j\) 

e quindi abbiamo che il gradiente \(\text d \boldsymbol W_{(n \times m)} = \text d \boldsymbol z_{(n \times 1)} \ \boldsymbol x^\top_{(1 \times m)} \)

 

\(\boldsymbol z_{(1 \times n)} = \boldsymbol x_{(1 \times m)} \boldsymbol W_{(m \times n)} \) : jacobiano \(\frac{\partial \boldsymbol z}{\partial \boldsymbol W} \) e gradiente \(\text d \boldsymbol W\)

In questo caso \(\displaystyle z_k=\sum_{l=1}^m W_{lk}x_l\)  e quindi  \(\displaystyle \frac {\partial z_k}{\partial W_{ij}} =\begin{cases} 0 \ \ se \ \ k \ne j \\ x_i \ se \ \ k = j \end{cases} \) che possiamo anche scrivere come

\(\frac {\partial \boldsymbol z}{\partial W_{ij}}=\begin{bmatrix} \boldsymbol 0 \\ x_i \\ \boldsymbol 0 \end{bmatrix} \leftarrow j \text {-ma riga}\) e applicando la chain rule \(\displaystyle \frac{\partial J}{\partial W_{ij}}=\frac{\partial J}{\partial \boldsymbol z}\frac{\partial \boldsymbol z}{\partial W_{ij}}=\sum_{k=1}^n \frac{\partial J}{\partial z_k}\frac{\partial z_k}{\partial W_{ij}}=\text d z_j \ x_i\) 

e otteniamo il gradiente \(\text d \boldsymbol W_{(m \times n)} = \boldsymbol x^\top_{(m \times 1)} \text d \boldsymbol z_{(1 \times n)} \)

 

\(\boldsymbol Z_{(n \times p)} = \boldsymbol W_{(n \times m)} \boldsymbol X_{(m \times p)} \) : jacobiano \(\frac{\partial \boldsymbol Z}{\partial \boldsymbol W} \) e gradiente \(\text d \boldsymbol W\)

Questo caso e il successivo generalizzano i 2 casi precedenti con l'utilizzo di matrici al posto di vettori.

Abbiamo \(\displaystyle Z_{ij}= \sum_{h=1}^m W_{ih}X_{hj}\) e quindi \(\displaystyle \frac {\partial Z_{ij}}{\partial W_{kl}} =\begin{cases} \ 0 \ \ se \ \ k \ne i \\ X_{lj} \ se \ k = i \end{cases} \)

Applicando la chain rule \(\displaystyle \frac{\partial J}{\partial W_{kl}}=\sum_{i=1}^n \sum_{j=1}^p \frac{\partial J}{\partial Z_{ij}} \frac{\partial Z_{ij}}{\partial W_{kl}}= \sum_{j=1}^p \text d Z_{kj} X_{lj}=\text d \boldsymbol Z_{k:} (\boldsymbol X_{l:})^\top\)

E pertanto \(\text d \boldsymbol W_{(n \times m)} = \text d \boldsymbol Z_{(n \times p)} \ \boldsymbol X^\top_{(p \times m)}\)

 

\(\boldsymbol Z_{(n \times p)} = \boldsymbol X_{(n \times m)} \boldsymbol W_{(m \times p)} \) : jacobiano \(\frac{\partial \boldsymbol Z}{\partial \boldsymbol W} \) e gradiente \(\text d \boldsymbol W\)

Abbiamo \(\displaystyle Z_{ij}= \sum_{h=1}^m X_{ih}W_{hj}\) e quindi \(\displaystyle \frac {\partial Z_{ij}}{\partial W_{kl}} =\begin{cases} \ 0 \ \ se \ \ j \ne l \\ X_{ik} \ se \ j = l \end{cases} \)

Applicando la chain rule \(\displaystyle \frac{\partial J}{\partial W_{kl}}=\sum_{i=1}^n \sum_{j=1}^p \frac{\partial J}{\partial Z_{ij}} \frac{\partial Z_{ij}}{\partial W_{kl}}= \sum_{i=1}^n \text d Z_{il} X_{ik}=(\boldsymbol X_{:k})^\top \text d \boldsymbol Z_{:l} \)

E pertanto \(\text d \boldsymbol W_{(m \times p)} = \boldsymbol X^\top_{(m \times n)} \text d \boldsymbol Z_{(n \times p)} \ \)

 

\(\boldsymbol z_{(n \times 1)}= \text {softmax} (\boldsymbol x_{(n \times 1)}) \ , \ J=\text {CE} (\boldsymbol z , \boldsymbol y)\) : jacobiano \(\frac{\partial \boldsymbol z}{\partial \boldsymbol x}\) e gradiente \(\text d \boldsymbol x\)

Un caso di funzione che troviamo frequentemente nelle reti neurali e merita di essere trattata specificamente è la funzione \( \text {softmax} (\boldsymbol x_{(n \times 1)})=\begin{bmatrix} \frac{e^{x_1}}{\sum_{k=1}^n e^{x_k}} \\ \vdots \\ \frac{e^{x_n}}{\sum_{k=1}^n e^{x_k}} \\ \end{bmatrix}\) .     Iniziamo a calcolare il jacobiano:

\(\frac{\partial z_i}{\partial x_j}=\begin{cases} \text{se} \ i \ne j \Rightarrow \ -\frac{e^{x_i} e^{x_j}}{(\sum_{k=1}^n e^{x_k})^2} = -z_i z_j\\ \text{se} \ i = j \Rightarrow \ \frac{e^{x_j}}{\sum_{k=1}^n e^{x_k}} -\frac{e^{x_j} e^{x_j}}{(\sum_{k=1}^n e^{x_k})^2} = z_j(1-z_j) \end{cases}\)  e quindi \(\frac{\partial \boldsymbol z}{\partial \boldsymbol x} = \begin{bmatrix} z_1(1-z_1) & \cdots & -z_1 z_n \\ \vdots & \ddots & \vdots \\ -z_n z_1 & \cdots & z_n(1-z_n) \end{bmatrix}\)

La funzione softmax è quasi sempre presente nel livello di uscita, abbinata ad una funzione di costo entropia incrociata (Cross Entropy)   \(J=\text{CE}(\boldsymbol z, \boldsymbol y) = {-\boldsymbol y}^\top \log \boldsymbol z\)  , nella quale la somma delle componenti del vettore dato y è uguale a 1. Procederemo in questo caso a prendere a esplicitare il jacobiano \(\frac{\partial J}{\partial \boldsymbol z} = \begin{bmatrix} -\frac {y_1}{z_1} \cdots -\frac {y_n}{z_n} \end{bmatrix}\)

Applicando la chain rule agli jacobiani  abbiamo \(\frac{\partial J}{\partial \boldsymbol x}=\frac{\partial J}{\partial \boldsymbol z}\frac{\partial \boldsymbol z}{\partial \boldsymbol x}=\begin{bmatrix} \cdots -\frac{y_j}{z_j}z_j(1-z_j)+\sum_{k \ne j} \frac{y_k}{z_k}z_j z_k \cdots \end{bmatrix} = \begin{bmatrix} \cdots -y_j+z_jy_j+z_j\sum_{k \ne j} y_k \cdots \end{bmatrix}= \begin{bmatrix} \cdots z_j-y_j \cdots \end{bmatrix}=(\boldsymbol z - \boldsymbol x)^\top\)

Per cui trasponendo otteremo il gradiente  \(\text d \boldsymbol x = \boldsymbol {z-x}\)

Il risultato può essere esteso anche nel caso di matrici, dove con \(\boldsymbol Z_{(n \times m)}=\text{softmax}(\boldsymbol X_{(n \times m)})\)  applichiamo la funzione softmax colonna per colonna, ovvero \(\begin{bmatrix} \boldsymbol z_{:1} \cdots \boldsymbol z_{:m} \end{bmatrix} = \begin{bmatrix} \text{softmax}(\boldsymbol x_{:1}) \cdots \text{softmax}(\boldsymbol x_{:m}) \end{bmatrix} \) .  La funzione di costo che utilizzeremo in questo caso è estesa alla matrice come \(\displaystyle J= \sum_{i=1}^m \sum_{j=1}^n -Y_{ij} \ \log Z_{ij}\)   e   \(\frac{\partial J}{\partial Z_{ij}} = -\frac{Y_{ij}}{Z_{ij}}\)

In questo caso abbiamo:

 \(\frac{\partial Z_{ij}}{\partial X_{kl}}=\begin{cases} \text{se} \ j \ne l \Rightarrow \ 0 \\ \text{se} \ j=l \ , \ i \ne k \Rightarrow \ -\frac{e^{X_{il}} \ e^{X_{kl}}}{(\sum_{t=1}^n e^{X_{tl}})^2} = -Z_{il} Z_{kl} \\ \text{se} \ j=l \ , \ i = k \Rightarrow \ \frac{e^{X_{kl}} }{\sum_{t=1}^n e^{X_{tl}}} -\frac{e^{X_{kl}} \ e^{X_{kl}}}{(\sum_{t=1}^n e^{X_{tl}})^2} = Z_{kl}(1-Z_{kl}) \end{cases}\)

\(\displaystyle \frac{\partial J}{\partial X_{kl}}= \sum_{i=1}^m \sum_{j=1}^n \frac{\partial J}{\partial Z_{ij}} \frac{\partial Z_{ij}}{\partial X_{kl}} = \sum_{i=1}^m -\frac{Y_{il}}{Z_{il}} \frac{\partial Z_{il}}{\partial X_{kl}}= -\frac{Y_{kl}}{Z_{kl}} Z_{kl}(1-Z_{kl}) + \sum_{i \ne k} \frac{Y_{il}}{Z_{il}} Z_{il}Z_{kl}= -Y_{kl}+Y_{kl}Z_{kl}+Z_{kl}\sum_{i \ne k}Y_{il}=Z_{kl}-Y_{kl}\)

Per cui otteniamo \(\text d \boldsymbol X = \boldsymbol {(Z-Y)}\)

Nella pratica la funzione di costo viene moltiplicata per un coefficiente \(\frac{1}{m}\) per ottenere valori non legati alla numerica delle colonne/campioni in matrice.