From f52ede1f25e271185fcc078e6db1c3b68c5e43ca Mon Sep 17 00:00:00 2001 From: LucaCorra02 Date: Thu, 12 Feb 2026 16:07:14 +0100 Subject: [PATCH 01/13] add raw note --- chapters/Lezione10.typ | 196 +++++++++++++++++++++++++++++++++++++++++ main.typ | 4 +- 2 files changed, 199 insertions(+), 1 deletion(-) create mode 100644 chapters/Lezione10.typ diff --git a/chapters/Lezione10.typ b/chapters/Lezione10.typ new file mode 100644 index 0000000..221becd --- /dev/null +++ b/chapters/Lezione10.typ @@ -0,0 +1,196 @@ +#import "../template.typ": * + += PyTorch autograd + +== Cos'è un graidente + +Partiamo da funzioni definite su uno spazio $D$ (input vettori) che mappano in un reale. + +$gradient$ è un operatore che viene applicato a una funzioni $f$ (rappresnta una rete neurale): +$ + gradient f: R^D->R^D +$ +#informalmente[ + un gradiente è un vettore di derivate parziali. + Applichiamo la definizione di derivata solo che consideriamo il tasso di variazioni su una singola variabile, tenendo costanti le altri. +] +Si fa difierenziazione solo rispetto a una variabile ecc //aggiugnere formula + +#esempio()[ + $ + f: R^2 -> R + $ + Otteniamo un campo vettoriale: + $ + delta f(x) = (alpha f) / (alpha x_1) hat(i)+ (alpha f) / (alpha x_2) hat(j) + $ + Il grafico 3d ci dice che dato un vettore che parte in un punto ci dice il grado di pendenza di quella funzione. I vettori sono più o meno intesi (modulo del vettore). i vettori hanno direzioni pendenze e intesità diverse man mano che mi muovo nel dominio +] + +Aggiungee latro esempio con due variabili. + +=== Curve di livello + +Sono importanti perchè quando usiamo il gradiente per raggiungere un punto di minimo in una funzione, usiamo le curve di livello. Un passo viene fatto da una cruva di livello ad un altra curva di livello (scegliendo una certa direzioni). Posso dstinguere le curve di livello in base a quelle che mi favoriscono la discesa verso il basso. + +//aggiungere immagine campo vettoriale generato dal paraboloide + +Il gradiente in ogni punto della funzione è perpendicolare alla tangente della curva di livello. Il gradiente viene interpretato come direzione + +*Teo*: (direzione di massima discesa) //aggiungere +#informalmente()[ + Il segno serve altrimenti andre in salita +] +Lo sviluppo di taylor speiga il perchè: +$ + f(x) = f(x_0)+ gradient (f_x_0)^T dot (x-x_0) +$ +#informalmente()[ + La funzione in un punto intorno da $x_0$. Se voglio usare la funzione di taylor per approssimare l'intorno di un punto devo ricorrere al gradiente moltiolicato (prodotto scalre) + + //riguardare + Voglio valutare la funzione in x scritto come lo scostamento di x dal bho.\ + Vado a sostituire nella formula + $ + x_i - alpha gradient(f_(x_o)) + $ +] +Mi muovo verso un valore del dominio in cui la funzione ha valore minore. La migliore direzione è quella che coincide con $gradient f(X_0)$. Per il teorema se scelgo $d^*$ in questo modo ho una discesa ottimale in qualsiasi putno della funzione + +=== algoritmo + +//agiungere algoritmo +Il passo è $alpha_k$ (learning rate), potrebbe variari tutte le volte che ho un passo di iterazione tramite degli algoritmi + +Criteri di stop. Vogliamo arrivare al minimo assoluto $gradient f(x_k) = 0$. Questa equazione è soddisfatta da un minimo relativo o minimi locali,oppure in caso di grafico a sella ho una variabile che mi fa salire e l'altra scendere. + +Dobbiamo fissare una soglia $epsilon$. Se soo sotto la soglia mi fermo: + +== Jacobiano +Quando abbiamo delle funzioni vettore->vettore sono delle funzioni non banali $R^n->R^m$ (layer dei modelli deep). + +Lo jacobiano è la generalizzazione del gradiente per le matrici. Ogni componente della funzione $F(hat(x))$ è una funzione $f_x(overline(x)))$ a sua volta(composizoni di funzioni). Il gradiente viene esteso, deve differenziare rispetto alle funzioni e alle variabili: + +La prima riga è la raccolta delle derivate parziali per la prima componente della funzione $F$. L'ultima riga è la derivata parziale rispetto all'ultima componente di $F$ grande. +#esempio()[ + Date $f_1 = x^2+y$ e $f_2 = x y$, ottengo $2x = (alpha f)/x$ +] + +#esempio()[ + Se prendo la funzione $h = g(overline(f))$. La f (composizoni di funzioni) è una variabile anche se deriva dal calcolo di $f_1(overline(x)), dots, f_k (overline(x))$. + + Se devo calcolare il gradiente di $h$ devo arrivare a moltiplicare lo jacobiao della funzione $f$ per la derivata priam di $g$: + + #esempio()[ + h è la composione di g e di f, posso dire che $h$ diepende da x, $h(overline(x))=g(f(x)))$. + + Posso usare la composizione in qualche modo //riguardare + ] +] +=== regola della catena + +Se predo due funzioni f e g e la loro composizione è derivabile ottendo $f'(g(x)) = r^k$ + +Posso fare la compsizione in quanto :$f(x_0)$ produce uan cosa di dim $m$ mentre $g$ prende $m$ e restituisce $k$: +$ + g(f(x_o)) -> z in R^k +$ + +#attenzione()[ + per calcolare i gradienti bisogna fare prodotti basati sugli jacobiani +] + +== Loss + +Una Loss : +$ + R^D -> R +$ +è una funzione che mappa da $R^D$ a $R$ è l'ultimo step del procedimento visto fino adesso. L'obbiettivo è minimizzare questo funzione considerando il set di parameti $w$ come variabile. + +Apllichiamo l'algoritmo di discesa dei gradienti per minimizzare la funzione + +== Differenziazione automatica + +Implementano il calcolo *esatto* (non approssimato) delle derivate di una funzione, si tratta di un meccanisomo di calcolo dei gradienti. + +Vogliamo calcolare il gradiente della funzione loss avendo a disposizione un numero di elementi che mappano l'input sull'output (sono un numero elevato). + +Potrei prendere ogni singolo elemento e farlo transistare nel mdoello -> calcolare la predizione -> caloclare l'errore -> modificare. Si tratta dell'approccio ideale. Tuttavia è meno robusto della discesa del gradiente stocastico e computazionalmente costoso + +=== Graident stocastic + +Scelgo a caso un elemento del dominio e sulal base dell'errore che si comette $L$, modifico i pesi. Un altro approccio più funzionante è basato su batch. + +Lavora nel seguente modo: +$ + w_t+1 = w_t - n 1 / |B_t| sum_(n in B_t) gradient_w underbrace(l(f(x_n;w_t),y_n), "valore commesso medio") +$ +Prendo un batch $B$ di tot elementi (piccola rispetto al dataset) e applico la variazione dei pesi sul valor medio di tutti i batch (non sul singolo esempalre) + +Quello che succedo è che se prendo il gradiente medio calcolato sul batch è che non riesco ad avere la discesa ottimale in quel punto, tuttavia ho dei vantaggi : +- Molta velocità, meno computazioni +- Capacità di fare esapece dei minimi locali (in quanto è più rumoroso) + +== Grafo computazionale + +PyTorch implementa dietro le quinte autograd. Costuisce un grafo orientato (grafo diretto aicilico) che traccia tutte le operaizoni in tempo reale: +- I nodi sono le operaizoni ($+, -, *, "/"$) +- Gli archi sono l'interdipendenza tra questi nodi + +Le aprime chiavi `requires_grad=True` associata ai tensori e l'operazione `backward()` ci permettono di fare il forward e modificare i pesi. + +I gradienti vengono accumolati, ci sono un pool di gradienti che vengono utilizzati per modificare poi i pesi, vengono accumolati nel campo `.grad` di un tensore. La regola di Differenziazione viene applicata al grafo. + +#esempio()[ + Regressione logistica (regressione per la classificazione). + $D={x_i,y_i}$ + + Se mi fermo al modello lineare ottengo un iperpiano, commette errori. Se prendo la funzione sigmoide o logistica ci permette di dire che se prendo una soglia (ad esempio $0.5$) ci permette di dire che se la rete emette $z$ (logits) da +/-inifnito la funzione di attivazione li riposta in un dominio più semplice, posso discriminarli in due classi 0 e 1. + + La funione di loos è la cross-entropy. + + Con $y=1$ (label True) mi trovo ad avere $-y log_2 sigma(z)$ se $y=0$ ho la funzinzone $1-log_2 sigma(z)$. + + Grado delle computazioni, prendo in input la variabile $x$ e $w$ (nel caso del forward la $x$ è variabile e $w$ costante, viceversa nella differenziazione). Esse danno forma alla variabile $z$ (ad esempio prodotto). La catenza forma un grafo ad alto livello. L'ultima parte è quella di decisione, il modello esce con dei valori + + //agiungere immagini + A partre da $x$ e $w$ viene generata $u = x times w$. A questo punto lo sommo a $b$ (realizzo il livello lineare): + $ + z = u + b + $ + (Composizione di funzioni). In uscita avrò $hat(y) = theta(z)$ e infine calcolo la loss. + + Una volta ottenuto il valore di loos metto in atto la discesa del gradiente con la chain rule. La chain rule è data dalla derivata di tutte le variabili in gioco: + + - $t = (alpha l) / (alpha hat(y))$ + - $(alpha l) / a(alpha z)$ + - $(alpha z) / (alpha u)$ + - $(alpha u) / (alpha w)$ + + la deriva di $(alpha L)/(alpha w)$ è data dal prodotto di tutte le derivate. +] + +== SDG in PyTorch + +`loss.backward()` fa tutto lui + +`optimezer.step()` ci aggiunge una regola di aggiornamento. + +```py +for epoch in range (n_epochs) + for data, targat in dataloader: + output = model(data)#costruisce un grafo + loss = criteration(output, target) + optimezer.zero_grad() #pulisce i buffer + loss.backward() + optimizer.step()#aggiorna i pesi +``` + +//aggoungere confronto mini-batch e singolo elemento +La disce del graideitne su un singolo elemnto alla volta è molto più smooth, tuttavia è molto costosa a livello computazionale. + + + + + diff --git a/main.typ b/main.typ index 4b7cf32..5c0be7e 100644 --- a/main.typ +++ b/main.typ @@ -35,4 +35,6 @@ #include "chapters/Lezione1-Introduzione.typ" #include "chapters/Lezione2-Gerarchia-Thread.typ" #include "chapters/Lezione3-Warp.typ" -#include "chapters/Lezione4.typ" \ No newline at end of file +#include "chapters/Lezione4.typ" + +#include "chapters/Lezione10.typ" \ No newline at end of file From 72b085d70fa8cbc687256a81c14da6d9904bf939 Mon Sep 17 00:00:00 2001 From: LucaCorra02 Date: Sat, 14 Feb 2026 20:03:11 +0100 Subject: [PATCH 02/13] add LLM integration --- chapters/Lezione10.typ | 417 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 417 insertions(+) diff --git a/chapters/Lezione10.typ b/chapters/Lezione10.typ index 221becd..d8b3c04 100644 --- a/chapters/Lezione10.typ +++ b/chapters/Lezione10.typ @@ -2,6 +2,423 @@ = PyTorch autograd +== Fondamenti Matematici del Gradiente + +=== Definizione di Gradiente + +Il *gradiente* è un operatore differenziale che si applica a funzioni scalari definite su spazi vettoriali. Data una funzione: +$ + f: R^D -> R +$ +che mappa un vettore di $D$ dimensioni in uno scalare, il gradiente di $f$ è definito come: +$ + nabla f: R^D -> R^D +$ + +Il gradiente produce un *vettore* che contiene tutte le *derivate parziali* della funzione rispetto a ciascuna variabile: +$ + nabla f(x) = vec((partial f)/(partial x_1), (partial f)/(partial x_2), dots.v, (partial f)/(partial x_D)) +$ + +#nota()[ + Il gradiente trasforma una funzione scalare in un *campo vettoriale*: ad ogni punto $x$ dello spazio viene associato un vettore $nabla f(x)$. + + Nel contesto del deep learning: + - $f$ rappresenta la *funzione di loss* + - $x$ rappresenta i *parametri* del modello (pesi e bias) + - $nabla f(x)$ indica come modificare i parametri per ridurre la loss +] + +=== Derivate Parziali + +Una *derivata parziale* misura il tasso di variazione di una funzione rispetto a *una singola variabile*, mantenendo costanti tutte le altre. + +Data $f(x_1, x_2, dots, x_D)$, la derivata parziale rispetto a $x_i$ è: +$ + (partial f)/(partial x_i) = lim_(h -> 0) (f(x_1, dots, x_i + h, dots, x_D) - f(x_1, dots, x_i, dots, x_D))/h +$ + +#esempio()[ + Consideriamo la funzione quadratica in due variabili: + $ + f(x_1, x_2) = x_1^2 + 3x_1 x_2 + 2x_2^2 + $ + + *Derivata parziale rispetto a $x_1$*: + + Trattiamo $x_2$ come una costante: + $ + (partial f)/(partial x_1) = 2x_1 + 3x_2 + $ + + *Derivata parziale rispetto a $x_2$*: + + Trattiamo $x_1$ come una costante: + $ + (partial f)/(partial x_2) = 3x_1 + 4x_2 + $ + + *Gradiente completo*: + $ + nabla f(x_1, x_2) = vec(2x_1 + 3x_2, 3x_1 + 4x_2) + $ + + In un punto specifico, ad esempio $(x_1, x_2) = (1, 2)$: + $ + nabla f(1, 2) = vec(2(1) + 3(2), 3(1) + 4(2)) = vec(8, 11) + $ +] + +=== Interpretazione Geometrica del Gradiente + +Il gradiente ha diverse interpretazioni geometriche fondamentali: + +*1. Direzione di massima crescita* + +Il vettore $nabla f(x_0)$ punta nella direzione in cui la funzione $f$ *cresce più rapidamente* a partire dal punto $x_0$. + +*2. Vettore normale alle curve di livello* + +Il gradiente in un punto è *perpendicolare* alla curva (o superficie) di livello passante per quel punto. + +*3. Magnitudine come tasso di crescita* + +Il modulo $||nabla f(x_0)||$ rappresenta il *tasso di crescita massimo* di $f$ in $x_0$. + +#esempio()[ + Consideriamo il paraboloide: + $ + f(x, y) = x^2 + y^2 + $ + + Il gradiente è: + $ + nabla f(x, y) = vec(2x, 2y) + $ + + #figure( + cetz.canvas({ + import cetz.draw: * + + // Configurazione + let scale = 1.5 + + // Assi + line((-3, 0), (3, 0), mark: (end: ">")) + content((3.3, 0), $x$) + line((0, -3), (0, 3), mark: (end: ">")) + content((0, 3.3), $y$) + + // Curve di livello (cerchi concentrici) + for r in (0.5, 1.0, 1.5, 2.0, 2.5) { + circle((0, 0), radius: r, stroke: (paint: blue.lighten(30%), thickness: 1pt)) + } + + // Etichette curve di livello + content((0.5, 0), text(size: 7pt, $c_1$), anchor: "south", fill: blue) + content((1.5, 0), text(size: 7pt, $c_2$), anchor: "south", fill: blue) + content((2.5, 0), text(size: 7pt, $c_3$), anchor: "south", fill: blue) + + // Punti campione + let points = ((1, 0.5), (0.7, 1.5), (-1, 1), (-1.5, -0.5), (0.5, -1.5)) + + for pt in points { + let (x, y) = pt + // Punto + circle((x, y), radius: 0.08, fill: red, stroke: none) + + // Calcola gradiente: ∇f = (2x, 2y) + let grad_x = 2 * x * 0.3 // Scala per visualizzazione + let grad_y = 2 * y * 0.3 + + // Disegna vettore gradiente + line((x, y), (x + grad_x, y + grad_y), + mark: (end: ">"), + stroke: (paint: red, thickness: 1.5pt)) + } + + // Origine + circle((0, 0), radius: 0.1, fill: green, stroke: none) + content((0, -0.4), text(size: 8pt, $(0,0)$), fill: green) + + // Legenda + rect((-2.8, 2), (-1.2, 2.8), fill: white.transparentize(20%), stroke: 0.5pt) + line((-2.6, 2.6), (-2.2, 2.6), stroke: (paint: blue.lighten(30%), thickness: 1pt)) + content((-1.9, 2.6), text(size: 7pt, [Curve di livello]), anchor: "west") + line((-2.6, 2.3), (-2.2, 2.3), mark: (end: ">"), stroke: (paint: red, thickness: 1.5pt)) + content((-1.9, 2.3), text(size: 7pt, [$nabla f$]), anchor: "west") + }), + caption: [Campo vettoriale del gradiente $nabla f(x,y) = vec(2x, 2y)$ per il paraboloide $f(x,y) = x^2 + y^2$. I vettori rossi (gradienti) sono perpendicolari alle curve di livello blu e puntano verso l'esterno (crescita).] + ) + + *Osservazioni*: + - All'origine $(0, 0)$, il gradiente è nullo: $nabla f(0,0) = vec(0,0)$ (punto di minimo) + - Nei punti lontani dall'origine, i vettori gradiente sono più lunghi (crescita più rapida) + - I gradienti puntano *radialmente verso l'esterno* (direzione di massima crescita) + - Sono tutti *perpendicolari* ai cerchi (curve di livello) +] + +=== Curve di Livello (Level Sets) + +Le *curve di livello* (o superfici di livello in dimensioni superiori) sono l'insieme dei punti dove la funzione assume un *valore costante*: +$ + cal(L)_c = {x in R^D : f(x) = c} +$ + +#nota()[ + *Proprietà fondamentale*: Il gradiente $nabla f(x_0)$ in un punto $x_0$ è *ortogonale* alla curva di livello passante per $x_0$. + + Questo significa che il gradiente punta nella direzione che *esce* dalla curva di livello, verso valori crescenti di $f$. +] + +#esempio()[ + Per la funzione $f(x, y) = x^2 + 2y^2$, le curve di livello sono ellissi: + $ + x^2 + 2y^2 = c + $ + + #figure( + cetz.canvas({ + import cetz.draw: * + + // Assi + line((-3, 0), (3, 0), mark: (end: ">")) + content((3.3, 0), $x$) + line((0, -2.5), (0, 2.5), mark: (end: ">")) + content((0, 2.8), $y$) + + // Curve di livello (ellissi) + for c in (0.5, 1.0, 2.0, 3.0) { + let a = calc.sqrt(c) + let b = calc.sqrt(c / 2) + + // Disegna ellisse parametrica + let points = () + for i in range(0, 101) { + let t = i * 2 * calc.pi / 100 + points.push((a * calc.cos(t), b * calc.sin(t))) + } + line(..points, stroke: (paint: blue.lighten(40%), thickness: 1pt), close: true) + } + + // Etichette + content((calc.sqrt(0.5), 0.1), text(size: 7pt, $c=0.5$), anchor: "south", fill: blue) + content((calc.sqrt(2), 0.1), text(size: 7pt, $c=2$), anchor: "south", fill: blue) + + // Punti e gradienti + let test_points = ((1, 0.5), (-1, 0.7), (0.5, -1)) + + for pt in test_points { + let (x, y) = pt + circle((x, y), radius: 0.08, fill: red, stroke: none) + + // Gradiente: ∇f = (2x, 4y) + let grad_x = 2 * x * 0.25 + let grad_y = 4 * y * 0.25 + + line((x, y), (x + grad_x, y + grad_y), + mark: (end: ">"), + stroke: (paint: red, thickness: 1.5pt)) + } + + // Origine + circle((0, 0), radius: 0.1, fill: green, stroke: none) + }), + caption: [Curve di livello ellittiche per $f(x,y) = x^2 + 2y^2$. Il gradiente $nabla f = vec(2x, 4y)$ è perpendicolare alle ellissi.] + ) +] + +#attenzione()[ + Le curve di livello sono fondamentali nell'ottimizzazione: + + - Un *passo di gradient descent* ci sposta da una curva di livello a un'altra con valore inferiore + - La direzione *perpendicolare* alla curva (il gradiente) è la direzione di *massimo cambiamento* + - Seguire il gradiente negativo ci porta verso valori decrescenti di $f$ (verso il minimo) +] + +=== Teorema della Direzione di Massima Discesa + +Il teorema fondamentale che giustifica l'uso del gradiente nell'ottimizzazione: + +*Teorema*: Dato un punto $x_0 in R^D$ e una funzione differenziabile $f: R^D -> R$, la direzione di *massima discesa* (che minimizza $f$ localmente) è data da: +$ + d^* = -nabla f(x_0) +$ + +Ovvero, il *negativo del gradiente* indica la direzione in cui la funzione decresce più rapidamente. + +==== Dimostrazione tramite Sviluppo di Taylor + +Consideriamo lo sviluppo di Taylor al primo ordine di $f$ intorno a $x_0$: +$ + f(x_0 + alpha d) approx f(x_0) + alpha nabla f(x_0)^T d +$ + +dove: +- $d$ è una direzione unitaria ($||d|| = 1$) +- $alpha > 0$ è uno step size piccolo + +#nota()[ + Lo sviluppo di Taylor ci dice che per piccoli spostamenti $alpha d$ da $x_0$, la funzione cambia approssimativamente di: + $ + Delta f approx alpha nabla f(x_0)^T d + $ +] + +Vogliamo trovare la direzione $d^*$ che *minimizza* $f(x_0 + alpha d)$, ovvero che rende $Delta f$ il più negativo possibile: +$ + d^* = arg min_(||d||=1) nabla f(x_0)^T d +$ + +Per il *teorema di Cauchy-Schwarz*: +$ + nabla f(x_0)^T d <= ||nabla f(x_0)|| dot ||d|| = ||nabla f(x_0)|| +$ + +L'uguaglianza si ottiene quando $d$ è *allineato* con $nabla f(x_0)$. Il minimo si ottiene quando: +$ + d^* = -(nabla f(x_0))/(||nabla f(x_0)||) +$ + +Ovvero, la direzione *opposta* al gradiente (normalizzato). + +#nota()[ + *Conclusione*: Muoversi nella direzione $-nabla f(x_0)$ garantisce la *massima riduzione* della funzione $f$ in un intorno di $x_0$. + + Questo è il principio alla base del *Gradient Descent*! +] + +=== Gradient Descent: Algoritmo di Base + +L'algoritmo di *gradient descent* per minimizzare una funzione $f(x)$ è: + +$ + x_(k+1) = x_k - alpha_k nabla f(x_k) +$ + +dove: +- $x_k$: valore dei parametri all'iterazione $k$ +- $alpha_k > 0$: *learning rate* (passo di discesa) +- $nabla f(x_k)$: gradiente calcolato in $x_k$ + +*Algoritmo iterativo*: +1. Inizializza $x_0$ (casualmente o con euristica) +2. Per $k = 0, 1, 2, dots$ fino a convergenza: + - Calcola il gradiente: $g_k = nabla f(x_k)$ + - Aggiorna i parametri: $x_(k+1) = x_k - alpha_k g_k$ + - Controlla convergenza: se $||g_k|| < epsilon$, termina + +#nota()[ + *Criteri di convergenza*: + + - *Condizione ideale*: $nabla f(x_k) = bold(0)$ (punto stazionario) + - *Condizione pratica*: $||nabla f(x_k)|| < epsilon$ per una soglia piccola $epsilon > 0$ + + #attenzione()[ + Un gradiente nullo può indicare: + - Un *minimo locale* (desiderato) + - Un *massimo locale* (indesiderato) + - Un *punto di sella* (né minimo né massimo) + + In deep learning, i *punti di sella* sono molto più comuni dei minimi locali in alta dimensione. + ] +] + +#esempio()[ + Minimizziamo $f(x, y) = x^2 + 4y^2$ partendo da $(x_0, y_0) = (3, 2)$. + + *Gradiente*: + $ + nabla f(x, y) = vec(2x, 8y) + $ + + *Iterazioni con $alpha = 0.1$*: + + - $k=0$: + - $x_0 = vec(3, 2)$ + - $nabla f(x_0) = vec(6, 16)$ + - $x_1 = vec(3, 2) - 0.1 vec(6, 16) = vec(2.4, 0.4)$ + + - $k=1$: + - $nabla f(x_1) = vec(4.8, 3.2)$ + - $x_2 = vec(2.4, 0.4) - 0.1 vec(4.8, 3.2) = vec(1.92, 0.08)$ + + - $k=2$: + - $nabla f(x_2) = vec(3.84, 0.64)$ + - $x_3 = vec(1.92, 0.08) - 0.1 vec(3.84, 0.64) = vec(1.536, 0.016)$ + + Convergenza verso il minimo $(0, 0)$ dove $f(0,0) = 0$. +] + +#attenzione()[ + *Scelta del Learning Rate $alpha$*: + + - $alpha$ troppo *piccolo*: convergenza molto lenta, molte iterazioni + - $alpha$ troppo *grande*: oscillazioni, possibile divergenza + - $alpha$ *ottimale*: bilanciamento tra velocità e stabilità + + In pratica si usano tecniche di *learning rate scheduling* (decay, adaptive methods come Adam). +] + +=== Visualizzazione del Processo di Ottimizzazione + +#figure()[ + #cetz.canvas({ + import cetz.draw: * + + // Assi + line((-3, 0), (3, 0), mark: (end: ">")) + content((3.3, 0), $x$) + line((0, -0.5), (0, 3.5), mark: (end: ">")) + content((0, 3.8), $f(x)$) + + // Funzione quadratica + let points = () + for i in range(-30, 31) { + let x = i / 10.0 + let y = x * x * 0.3 + 0.2 + points.push((x, y)) + } + line(..points, stroke: (paint: blue, thickness: 2pt)) + + // Traiettoria gradient descent + let trajectory = ( + (2.2, 1.65), + (1.5, 0.875), + (0.9, 0.443), + (0.5, 0.275), + (0.2, 0.212), + (0.05, 0.2075), + ) + + // Disegna traiettoria + for i in range(trajectory.len() - 1) { + let pt1 = trajectory.at(i) + let pt2 = trajectory.at(i + 1) + line(pt1, pt2, mark: (end: ">"), stroke: (paint: red, thickness: 1.5pt)) + } + + // Punti sulla traiettoria + for (i, pt) in trajectory.enumerate() { + circle(pt, radius: 0.08, fill: red, stroke: none) + if i == 0 { + content((pt.at(0), pt.at(1) + 0.3), text(size: 8pt, $x_0$), fill: red) + } else if i == trajectory.len() - 1 { + content((pt.at(0) - 0.3, pt.at(1)), text(size: 8pt, $x^*$), fill: red) + } + } + + // Minimo + circle((0, 0.2), radius: 0.1, fill: green, stroke: (paint: green, thickness: 2pt)) + + // Etichette + content((1.5, 3), text(size: 10pt, $f(x) = x^2$), fill: blue) + content((2, 2.3), text(size: 9pt, [Gradient Descent]), fill: red) + }) + + Visualizzazione del gradient descent su una funzione unidimensionale. La traiettoria rossa mostra i passi iterativi che convergono al minimo (punto verde). +] + == Cos'è un graidente Partiamo da funzioni definite su uno spazio $D$ (input vettori) che mappano in un reale. From ad52a657f743e0fb6b18dfddca1100a7a4e4d68c Mon Sep 17 00:00:00 2001 From: LucaCorra02 Date: Sun, 15 Feb 2026 11:07:22 +0100 Subject: [PATCH 03/13] add gradient --- assets/DerivateParziali2d.png | Bin 0 -> 263293 bytes chapters/Lezione10.typ | 660 +++++++++++++++++++++++++++++++++- 2 files changed, 653 insertions(+), 7 deletions(-) create mode 100644 assets/DerivateParziali2d.png diff --git a/assets/DerivateParziali2d.png b/assets/DerivateParziali2d.png new file mode 100644 index 0000000000000000000000000000000000000000..ead4288e82ba4c7c1840435b520653c0a0baa3b8 GIT binary patch literal 263293 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 >`uw)B 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 z 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�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 J`HQ`_{RN~m_gDY` literal 0 HcmV?d00001 diff --git a/chapters/Lezione10.typ b/chapters/Lezione10.typ index d8b3c04..f7c963c 100644 --- a/chapters/Lezione10.typ +++ b/chapters/Lezione10.typ @@ -3,10 +3,7 @@ = PyTorch autograd == Fondamenti Matematici del Gradiente - -=== Definizione di Gradiente - -Il *gradiente* è un operatore differenziale che si applica a funzioni scalari definite su spazi vettoriali. Data una funzione: +Il *gradiente* è un operatore differenziale che si applica a funzioni scalari definite su *spazi vettoriali*. Data una funzione: $ f: R^D -> R $ @@ -15,13 +12,13 @@ $ nabla f: R^D -> R^D $ -Il gradiente produce un *vettore* che contiene tutte le *derivate parziali* della funzione rispetto a ciascuna variabile: +Il gradiente produce un *vettore* che contiene tutte le *derivate parziali* della funzione rispetto a ciascuna variabile (si deriva rispetto a una varianbile alla volta, tenendo le altre costanti): $ nabla f(x) = vec((partial f)/(partial x_1), (partial f)/(partial x_2), dots.v, (partial f)/(partial x_D)) $ #nota()[ - Il gradiente trasforma una funzione scalare in un *campo vettoriale*: ad ogni punto $x$ dello spazio viene associato un vettore $nabla f(x)$. + Il gradiente trasforma una funzione scalare in un *campo vettoriale*: *ad ogni punto $x$* dello spazio viene associato un vettore *$nabla f(x)$*. Nel contesto del deep learning: - $f$ rappresenta la *funzione di loss* @@ -38,6 +35,121 @@ $ (partial f)/(partial x_i) = lim_(h -> 0) (f(x_1, dots, x_i + h, dots, x_D) - f(x_1, dots, x_i, dots, x_D))/h $ +Supponendo di lavorare in uno spazio vettoriale a *due dimensioni* ($R^2$, con $D = 2$), possiamo dare un'interpretazione geometrica alle derivate parziali: + +#figure[ + #image("/assets/Code_Generated_Image.png",width: 80%) + + Visualizzazione 3D di una funzione $f(x,y)$ con le derivate parziali nel punto rosso $(1,1)$. +] + +In particolare, nell'immagine possiamo oservare che: +- *spazio vettoriale*: rappresentato dagli assi $(x,y)$. Ogni punto $(x,y)$ rappresenta una coppia di valori per le variabili $x$ e $y$. + +- funzione *$f(x,y)$*: per ogni punto $(x,y)$, la funzione associa un valore scalare $f(x,y)$. Questo valore rappresenta l'*altitudine* ($z$) della superficie sopra quel punto. + +Consideriamo ora il punto $mr("rosso")$ di coordinate $(1,1)$. Se volessimo _quanto è ripida la salita_, potremo utilizzare la *derivata parziale*. Essa indica lo spostamento rispette alle due direzioni principali $(x,y)$. Nell'immagine: + + +- $mb("Linea Blu")$ (Derivata rispetto a $x$): La curva viene tagliata lungo l'asse $x$ (linea blu tratteggiata). La linea blu spessa è la pendenza esatta in quel punto muovendosi solo lungo $x$, indica il *tasso di variazione di $f$* se facciamo un piccolo passo verso Est (aumentando $x$). Se la linea blu è inclinata verso l'alto, significa che aumentando $x$ aumenta anche $f$ (salita). + +- $mg("Linea Verde")$ (Derivata rispetto a $y$): È la stessa cosa, ma nell'altra direzione (asse $Y$). La linea verde spessa indica il tasso di variazione di $f$ se facciamo un piccolo passo verso Nord (aumentando $y$). Se la linea verde è inclinata verso l'alto, significa che aumentando $y$ aumenta anche $f$ (salita). + +=== Il Gradiente: Combinazione delle Derivate Parziali + +Il *gradiente* $nabla f(x, y)$ è un *vettore* che combina entrambe le derivate parziali: +$ + nabla f(x, y) = vec((partial f)/(partial x), (partial f)/(partial y)) +$ + +Nel contesto della visualizzazione 3D: +- Le derivate parziali (linee blu e verde) misurano la pendenza lungo le *direzioni degli assi* +- Il gradiente combina queste informazioni in un *unico vettore 2D* nel piano $(x, y)$ +- Questo vettore indica la *direzione di massima salita* sulla superficie + +#figure( + cetz.canvas({ + import cetz.draw: * + + // Assi cartesiani + line((-0.5, 0), (4.5, 0), mark: (end: ">"), stroke: 1pt) + content((4.7, 0), $x$, anchor: "west") + line((0, -0.5), (0, 3.5), mark: (end: ">"), stroke: 1pt) + content((0, 3.7), $y$, anchor: "south") + + // Punto di interesse + let px = 1.8 + let py = 1.5 + circle((px, py), radius: 0.1, fill: red, stroke: none) + content((px - 0.4, py - .4), text(size: 8pt, $(x_0, y_0)$), fill: red) + + // Derivata parziale rispetto a x (componente orizzontale) + let dx = 1.0 // lunghezza proporzionale a ∂f/∂x + line((px, py), (px + dx, py), + mark: (end: ">"), + stroke: (paint: blue, thickness: 2pt, dash: "dashed")) + content((px + dx/2, py - 0.3), text(size: 8pt, $(partial f)/(partial x)$), fill: blue) + + // Derivata parziale rispetto a y (componente verticale) + let dy = 0.75 // lunghezza proporzionale a ∂f/∂y + line((px, py), (px, py + dy), + mark: (end: ">"), + stroke: (paint: green.darken(20%), thickness: 2pt, dash: "dashed")) + content((px - 0.5, py + dy/2), text(size: 8pt, $(partial f)/(partial y)$), fill: green.darken(20%)) + + // Gradiente (vettore risultante) + line((px, py), (px + dx, py + dy), + mark: (end: ">"), + stroke: (paint: red.darken(20%), thickness: 2.5pt)) + content((px + dx/2 + 0.3, py + dy/2 + 0.6), + text(size: 9pt, weight: "bold", $nabla f$), + fill: red.darken(20%)) + + // Rettangolo tratteggiato per visualizzare la composizione + line((px + dx, py), (px + dx, py + dy), stroke: (dash: "dotted", paint: gray)) + line((px, py + dy), (px + dx, py + dy), stroke: (dash: "dotted", paint: gray)) + + // Origine + content((-0.3, -0.3), text(size: 8pt, $O$)) + + // Legenda (spostata in basso a destra) + rect((3.2, 0.2), (rel: (1.4, 0.9)), fill: white.transparentize(10%), stroke: 0.8pt) + line((3.3, 0.9), (3.6, 0.9), mark: (end: ">"), stroke: (paint: blue, thickness: 1.5pt, dash: "dashed")) + content((3.65, 0.9), text(size: 7pt, [Comp. $x$]), anchor: "west") + line((3.3, 0.65), (3.6, 0.65), mark: (end: ">"), stroke: (paint: green.darken(20%), thickness: 1.5pt, dash: "dashed")) + content((3.65, 0.65), text(size: 7pt, [Comp. $y$]), anchor: "west") + line((3.3, 0.4), (3.6, 0.4), mark: (end: ">"), stroke: (paint: red.darken(20%), thickness: 2pt)) + content((3.65, 0.4), text(size: 7pt, weight: "bold", [Gradiente]), anchor: "west") + }), + caption: [Il gradiente $nabla f$ ($mr("rosso")$) è il vettore che si ottiene combinando le due derivate parziali: la componente $mb("blu")$ $(partial f)/(partial x)$ (orizzontale) e la componente $mg("verde")$ $(partial f)/(partial y)$ (verticale). Nel piano 2D $(x,y)$, il gradiente indica la direzione di massima crescita di $f$.] +) + +#nota()[ + *Interpretazione geometrica del gradiente*: + + - *Direzione*: Il gradiente punta nella direzione in cui la funzione cresce più rapidamente + - *Magnitudine*: La lunghezza del vettore gradiente indica quanto ripida è la salita + - *Posizione nel piano*: Il gradiente "vive" nel piano $(x, y)$ (piano di base), non nello spazio 3D della superficie +] + +=== Perpendicolarità alle Curve di Livello + +Un concetto fondamentale è che il gradiente è *perpendicolare* alle curve di livello: + +*Curve di livello*: Se proiettiamo la superficie 3D sul piano $(x, y)$ e colleghiamo tutti i punti che hanno la *stessa altitudine* $f(x, y) = c$, otteniamo delle curve chiamate "curve di livello" + +*Perpendicolarità*: In ogni punto, il vettore gradiente $nabla f$ è *perpendicolare* (ortogonale, a 90°) alla curva di livello che passa per quel punto. + +#attenzione()[ + *Importante*: La perpendicolarità è nel *piano $(x, y)$*, non nello spazio 3D! + + - Il gradiente è un vettore 2D: $nabla f(x, y) = vec((partial f)/(partial x), (partial f)/(partial y))$ + - Le curve di livello sono curve 2D nel piano $(x, y)$ + - La perpendicolarità si riferisce a queste entità 2D + + Quando visualizziamo la superficie 3D, "proiettiamo" mentalmente il gradiente sul piano di base per vedere la sua perpendicolarità alle curve di livello. +] + #esempio()[ Consideriamo la funzione quadratica in due variabili: $ @@ -58,11 +170,87 @@ $ (partial f)/(partial x_2) = 3x_1 + 4x_2 $ - *Gradiente completo*: + *Gradiente completo*: Crea uno spazio vettoriale con entrambe le derivate: $ nabla f(x_1, x_2) = vec(2x_1 + 3x_2, 3x_1 + 4x_2) $ + #figure( + cetz.canvas({ + import cetz.draw: * + + // Assi + line((-3, 0), (3, 0), mark: (end: ">")) + content((3.3, 0), $x_1$) + line((0, -2.5), (0, 2.5), mark: (end: ">")) + content((0, 2.8), $x_2$) + + // Curve di livello per la funzione f(x1,x2) = x1² + 3x1*x2 + 2x2² + // Questa è una forma quadratica, le curve di livello sono ellissi ruotate + for level in (1, 3, 6, 10) { + let points = () + for i in range(0, 101) { + let angle = i * 2 * calc.pi / 100 + // Uso parametrizzazione approssimata per le curve di livello + let r = calc.sqrt(level) / calc.sqrt(1 + 0.5 * calc.sin(2 * angle)) + let x1 = r * calc.cos(angle) + let x2 = r * calc.sin(angle) + // Verifica approssimata che soddisfi l'equazione + points.push((x1 * 0.8, x2 * 0.7)) + } + line(..points, stroke: (paint: blue.lighten(40%), thickness: 1pt), close: true) + } + + // Etichette per le curve di livello + content((0.8, 0.1), text(size: 7pt, $c_1$), anchor: "south", fill: blue) + content((1.5, 0.1), text(size: 7pt, $c_2$), anchor: "south", fill: blue) + + // Punti campione e vettori gradiente + let sample_points = ( + (1, 0.5), + (0.5, 1), + (-0.5, 0.8), + (-1, -0.5), + (0.8, -0.6), + (1.5, 0), + (0, 1.2), + (-1.2, 0.3) + ) + + for pt in sample_points { + let (x1, x2) = pt + // Punto + circle((x1, x2), radius: 0.06, fill: red, stroke: none) + + // Calcola gradiente: ∇f = (2x₁ + 3x₂, 3x₁ + 4x₂) + let grad_x1 = 2 * x1 + 3 * x2 + let grad_x2 = 3 * x1 + 4 * x2 + + // Scala per visualizzazione + let scale = 0.15 + let gx = grad_x1 * scale + let gy = grad_x2 * scale + + // Disegna vettore gradiente + line((x1, x2), (x1 + gx, x2 + gy), + mark: (end: ">"), + stroke: (paint: red, thickness: 1.3pt)) + } + + // Origine + circle((0, 0), radius: 0.08, fill: green, stroke: none) + content((0.3, -0.2), text(size: 8pt, $(0,0)$), fill: green) + + // Legenda + rect((-2.8, 1.8), (-1, 2.6), fill: white.transparentize(20%), stroke: 0.5pt) + line((-2.6, 2.4), (-2.2, 2.4), stroke: (paint: blue.lighten(40%), thickness: 1pt)) + content((-1.4, 2.4), text(size: 7pt, [Curve di livello]), anchor: "west") + line((-2.6, 2.1), (-2.2, 2.1), mark: (end: ">"), stroke: (paint: red, thickness: 1.3pt)) + content((-1.4, 2.1), text(size: 7pt, [$nabla f$]), anchor: "west") + }), + caption: [Campo vettoriale del gradiente per $f(x_1, x_2) = x_1^2 + 3x_1 x_2 + 2x_2^2$. I vettori rossi rappresentano $nabla f(x_1, x_2) = vec(2x_1 + 3x_2, 3x_1 + 4x_2)$ in vari punti, e sono sempre perpendicolari alle curve di livello blu.] + ) + In un punto specifico, ad esempio $(x_1, x_2) = (1, 2)$: $ nabla f(1, 2) = vec(2(1) + 3(2), 3(1) + 4(2)) = vec(8, 11) @@ -419,6 +607,464 @@ dove: Visualizzazione del gradient descent su una funzione unidimensionale. La traiettoria rossa mostra i passi iterativi che convergono al minimo (punto verde). ] +== Composizione di Funzioni e Chain Rule + +Nel deep learning, i modelli sono costruiti attraverso la *composizione di funzioni*. Ogni layer della rete applica una trasformazione, e l'output di un layer diventa l'input del successivo. Per calcolare i gradienti in questi modelli complessi, è fondamentale la *regola della catena* (chain rule). + +=== La Regola della Catena (Chain Rule) + +La *chain rule* è una regola fondamentale del calcolo differenziale che permette di calcolare la derivata di funzioni composte. + +*Caso unidimensionale*: + +Date due funzioni $g: R -> R$ e $f: R -> R$, la derivata della composizione $h(x) = f(g(x))$ è: +$ + (d h)/(d x) = (d f)/(d g) dot (d g)/(d x) +$ + +oppure, in notazione più esplicita: +$ + h'(x) = f'(g(x)) dot g'(x) +$ + +#esempio()[ + Consideriamo $h(x) = (x^2 + 1)^3$. + + Possiamo vedere questa funzione come composizione: + - $g(x) = x^2 + 1$ + - $f(g) = g^3$ + - $h(x) = f(g(x))$ + + Applicando la chain rule: + $ + h'(x) &= f'(g(x)) dot g'(x) \ + &= 3g^2 dot 2x \ + &= 3(x^2 + 1)^2 dot 2x \ + &= 6x(x^2 + 1)^2 + $ +] + +*Caso multivariato*: + +Per funzioni $g: R^n -> R^m$ e $f: R^m -> R^k$, la derivata della composizione $h(x) = f(g(x))$ è data dal prodotto delle matrici Jacobiane: +$ + J_h (x) = J_f (g(x)) dot J_g (x) +$ + +dove: +- $J_h (x) in R^(k times n)$: Jacobiano di $h$ +- $J_f (g(x)) in R^(k times m)$: Jacobiano di $f$ valutato in $g(x)$ +- $J_g (x) in R^(m times n)$: Jacobiano di $g$ valutato in $x$ + +#nota()[ + *Interpretazione per il Deep Learning*: + + In una rete neurale con $L$ layer, l'output finale è una composizione di funzioni: + $ + y = f_L (f_(L-1)(dots f_2(f_1(x)))) + $ + + Per calcolare il gradiente della loss rispetto ai parametri del primo layer, dobbiamo applicare ripetutamente la chain rule, moltiplicando i gradienti di tutti i layer attraversati. + + Questo è il principio alla base della *backpropagation*! +] + +#esempio()[ + Consideriamo una rete neurale minima con due layer: + + - Layer 1: $z = w_1 x + b_1$ (trasformazione lineare) + - Activation: $a = sigma(z)$ (funzione sigmoide) + - Layer 2: $hat(y) = w_2 a + b_2$ (output) + - Loss: $L = 1/2 (hat(y) - y)^2$ (errore quadratico) + + Per calcolare $(partial L)/(partial w_1)$ (gradiente rispetto al peso del primo layer), applichiamo la chain rule: + $ + (partial L)/(partial w_1) = (partial L)/(partial hat(y)) dot (partial hat(y))/(partial a) dot (partial a)/(partial z) dot (partial z)/(partial w_1) + $ + + dove: + - $(partial L)/(partial hat(y)) = hat(y) - y$ + - $(partial hat(y))/(partial a) = w_2$ + - $(partial a)/(partial z) = sigma(z)(1 - sigma(z))$ + - $(partial z)/(partial w_1) = x$ + + Il gradiente finale è: + $ + (partial L)/(partial w_1) = (hat(y) - y) dot w_2 dot sigma(z)(1 - sigma(z)) dot x + $ +] + +#attenzione()[ + La chain rule è il meccanismo fondamentale che permette al *backpropagation* di propagare i gradienti all'indietro attraverso tutti i layer della rete, partendo dalla loss fino ai primi parametri. +] + +== Lo Jacobiano: Gradiente Generalizzato + +Quando lavoriamo con funzioni che mappano vettori in vettori (come i layer delle reti neurali), il gradiente non è sufficiente. Abbiamo bisogno dello *Jacobiano*. + +=== Definizione dello Jacobiano + +Data una funzione vettoriale $F: R^n -> R^m$: +$ + F(x) = vec(f_1(x), f_2(x), dots.v, f_m(x)) +$ + +dove $x = vec(x_1, x_2, dots, x_n) in R^n$, lo *Jacobiano* di $F$ è la matrice delle derivate parziali: +$ + J_F (x) = mat( + (partial f_1)/(partial x_1), (partial f_1)/(partial x_2), dots, (partial f_1)/(partial x_n); + (partial f_2)/(partial x_1), (partial f_2)/(partial x_2), dots, (partial f_2)/(partial x_n); + dots.v, dots.v, dots.down, dots.v; + (partial f_m)/(partial x_1), (partial f_m)/(partial x_2), dots, (partial f_m)/(partial x_n) + ) in R^(m times n) +$ + +Ogni *riga* $i$ contiene il gradiente della componente $f_i$: +$ + "Riga" i: nabla f_i (x) = vec((partial f_i)/(partial x_1), (partial f_i)/(partial x_2), dots, (partial f_i)/(partial x_n)) +$ + +#nota()[ + *Confronto con il Gradiente*: + + - Il *gradiente* $nabla f$ si applica a funzioni scalari: $f: R^n -> R$ (produce un vettore $in R^n$) + - Lo *Jacobiano* $J_F$ si applica a funzioni vettoriali: $F: R^n -> R^m$ (produce una matrice $in R^(m times n)$) + + In particolare, se $m=1$ (funzione scalare), lo Jacobiano coincide con il gradiente trasposto: + $ + J_f = nabla f^T + $ +] + +=== Esempio: Jacobiano di una Trasformazione Lineare + +Consideriamo $F: R^2 -> R^2$ definita da: +$ + F(x, y) = vec(f_1(x, y), f_2(x, y)) = vec(x^2 + y, x y) +$ + +*Calcoliamo lo Jacobiano*: + +Le componenti sono: +- $f_1(x, y) = x^2 + y$ +- $f_2(x, y) = x y$ + +Le derivate parziali sono: +- $(partial f_1)/(partial x) = 2x$, $(partial f_1)/(partial y) = 1$ +- $(partial f_2)/(partial x) = y$, $(partial f_2)/(partial y) = x$ + +Lo Jacobiano è: +$ + J_F (x, y) = mat( + 2x, 1; + y, x + ) +$ + +In un punto specifico, ad esempio $(x, y) = (2, 3)$: +$ + J_F (2, 3) = mat( + 4, 1; + 3, 2 + ) +$ + +#esempio()[ + *Jacobiano di un layer fully-connected*: + + Un layer lineare in una rete neurale è definito da: + $ + z = W x + b + $ + + dove: + - $x in R^n$: input + - $W in R^(m times n)$: matrice dei pesi + - $b in R^m$: bias + - $z in R^m$: output + + Lo Jacobiano di questa trasformazione rispetto all'input $x$ è: + $ + J_z (x) = (partial z)/(partial x) = W in R^(m times n) + $ + + Ogni elemento della matrice è: + $ + (J_z)_(i j) = (partial z_i)/(partial x_j) = W_(i j) + $ + + Lo Jacobiano rispetto ai pesi $W$ è più complesso, ma segue lo stesso principio. +] + +=== Jacobiano e Chain Rule + +Lo Jacobiano è essenziale per applicare la chain rule in dimensione superiore. Data la composizione $h = g compose f$: +$ + h: R^n ->^f R^m ->^g R^k +$ + +Lo Jacobiano di $h$ è dato dal *prodotto* degli Jacobiani: +$ + J_h (x) = J_g (f(x)) dot J_f (x) +$ + +dove: +- $J_f (x) in R^(m times n)$ +- $J_g (f(x)) in R^(k times m)$ +- $J_h (x) in R^(k times n)$ + +#nota()[ + *Dimensioni nel prodotto*: + $ + underbrace(R^(k times m), J_g) dot underbrace(R^(m times n), J_f) = underbrace(R^(k times n), J_h) + $ + + Le dimensioni intermedie $m$ si cancellano nel prodotto matriciale, come richiesto dalla composizione di funzioni. +] + +#esempio()[ + Consideriamo una rete neurale con due layer lineari: + + - Layer 1: $z = W_1 x in R^m$ (con $x in R^n$) + - Layer 2: $y = W_2 z in R^k$ (con $z in R^m$) + + Per calcolare $(partial y)/(partial x)$, usiamo la chain rule: + $ + (partial y)/(partial x) = (partial y)/(partial z) dot (partial z)/(partial x) = W_2 dot W_1 + $ + + Lo Jacobiano della composizione è il prodotto delle matrici dei pesi: + $ + J_(y,x) = W_2 W_1 in R^(k times n) + $ +] + +#attenzione()[ + *Importanza per la Backpropagation*: + + Durante la backpropagation, il gradiente della loss viene propagato all'indietro attraverso la rete moltiplicando ripetutamente gli Jacobiani dei vari layer. Questo è computazionalmente efficiente grazie alla struttura matriciale degli Jacobiani. +] + +== Grafi Computazionali e Differenziazione Automatica + +I framework moderni di deep learning (PyTorch, TensorFlow) implementano la *differenziazione automatica* (automatic differentiation, o *autograd*) attraverso *grafi computazionali*. + +=== Cos'è un Grafo Computazionale + +Un *grafo computazionale* è un grafo orientato aciclico (DAG - Directed Acyclic Graph) che rappresenta la sequenza di operazioni matematiche eseguite durante il calcolo di una funzione. + +*Componenti del grafo*: +- *Nodi*: rappresentano *valori* (input, parametri, risultati intermedi, output) +- *Archi*: rappresentano *operazioni* matematiche ($+, -, times, div, "exp", "log"$, ecc.) + +#nota()[ + Il grafo cattura la *struttura della funzione* e le *dipendenze* tra le variabili. Questo permette di calcolare automaticamente i gradienti usando la chain rule. +] + +=== Come si Costruisce il Grafo + +Il grafo viene costruito *dinamicamente* durante l'esecuzione del codice (*dynamic computational graph* in PyTorch) o *staticamente* prima dell'esecuzione (*static computational graph* in TensorFlow 1.x). + +*Costruzione in PyTorch* (dinamica): + +1. *Definizione dei tensori*: I tensori con `requires_grad=True` diventano *nodi foglia* del grafo +2. *Esecuzione delle operazioni*: Ogni operazione aritmetica crea un nuovo nodo nel grafo +3. *Registrazione delle dipendenze*: PyTorch registra quale operazione ha generato quale tensore +4. *Tracciamento automatico*: Il grafo viene costruito man mano che il codice viene eseguito + +#esempio()[ + Consideriamo il seguente codice PyTorch: + + ```python + import torch + + # Input e parametri + x = torch.tensor([2.0], requires_grad=True) # Nodo foglia + w = torch.tensor([3.0], requires_grad=True) # Nodo foglia + b = torch.tensor([1.0], requires_grad=True) # Nodo foglia + + # Forward pass: costruzione del grafo + u = x * w # Operazione di moltiplicazione + z = u + b # Operazione di addizione + y = z ** 2 # Operazione di potenza + ``` + + PyTorch costruisce automaticamente il seguente grafo: + + #figure( + cetz.canvas({ + import cetz.draw: * + + // Configurazione + let node-style = (stroke: black, fill: blue.lighten(80%)) + let op-style = (stroke: black, fill: orange.lighten(70%)) + let param-style = (stroke: black, fill: green.lighten(70%)) + + // Nodi input/parametri (foglie) + circle((-2, 0), radius: 0.4, ..param-style, name: "x") + content("x", text(size: 10pt, $x$)) + + circle((0, 0), radius: 0.4, ..param-style, name: "w") + content("w", text(size: 10pt, $w$)) + + circle((2, 0), radius: 0.4, ..param-style, name: "b") + content("b", text(size: 10pt, $b$)) + + // Operazione moltiplicazione + rect((-1, 1.5), (rel: (1, 0.6)), ..op-style, name: "mul") + content((-0.5, 1.8), text(size: 9pt, $times$)) + + // Nodo u + circle((-0.5, 3), radius: 0.4, ..node-style, name: "u") + content("u", text(size: 10pt, $u$)) + + // Operazione addizione + rect((0.5, 3.5), (rel: (1, 0.6)), ..op-style, name: "add") + content((1, 3.8), text(size: 9pt, $+$)) + + // Nodo z + circle((1, 5), radius: 0.4, ..node-style, name: "z") + content("z", text(size: 10pt, $z$)) + + // Operazione potenza + rect((0.5, 5.5), (rel: (1, 0.6)), ..op-style, name: "pow") + content((1, 5.8), text(size: 9pt, $x^2$)) + + // Nodo output y + circle((1, 7), radius: 0.4, ..node-style, name: "y") + content("y", text(size: 10pt, $y$)) + + // Archi + line("x", "mul", mark: (end: ">"), stroke: 1.5pt) + line("w", "mul", mark: (end: ">"), stroke: 1.5pt) + line("mul", "u", mark: (end: ">"), stroke: 1.5pt) + line("u", "add", mark: (end: ">"), stroke: 1.5pt) + line("b", "add", mark: (end: ">"), stroke: 1.5pt) + line("add", "z", mark: (end: ">"), stroke: 1.5pt) + line("z", "pow", mark: (end: ">"), stroke: 1.5pt) + line("pow", "y", mark: (end: ">"), stroke: 1.5pt) + + // Legenda + rect((3, 6), (rel: (2.5, 1.8)), stroke: 1pt) + content((4.25, 7.5), text(size: 9pt, weight: "bold", [Legenda])) + circle((3.3, 7), radius: 0.2, ..param-style) + content((4, 7), text(size: 8pt, [Parametri/Input]), anchor: "west") + circle((3.3, 6.5), radius: 0.2, ..node-style) + content((4, 6.5), text(size: 8pt, [Nodi intermedi]), anchor: "west") + rect((3.2, 6.1), (rel: (0.3, 0.2)), ..op-style) + content((4, 6.2), text(size: 8pt, [Operazioni]), anchor: "west") + }), + caption: [Grafo computazionale per $y = (x times w + b)^2$. I nodi verdi sono parametri con `requires_grad=True`, i nodi blu sono valori intermedi, e i nodi arancioni sono operazioni.] + ) + + *Valori concreti*: + Con $x=2$, $w=3$, $b=1$: + $ + u &= 2 times 3 = 6 \ + z &= 6 + 1 = 7 \ + y &= 7^2 = 49 + $ +] + +=== Forward Pass e Backward Pass + +Il grafo computazionale supporta due modalità di attraversamento: + +*1. Forward Pass* (Propagazione in avanti): +- Si parte dai nodi *foglia* (input e parametri) +- Si attraversa il grafo seguendo la direzione degli archi +- Si calcolano i valori intermedi fino ad arrivare all'output +- *Risultato*: calcolo del valore della funzione + +*2. Backward Pass* (Backpropagation): +- Si parte dal nodo *output* (loss) +- Si attraversa il grafo in direzione *opposta* agli archi +- Si applicano le regole di derivazione usando la chain rule +- *Risultato*: calcolo dei gradienti rispetto a tutti i parametri + +#esempio()[ + Continuando l'esempio precedente, calcoliamo i gradienti con `y.backward()`: + + ```python + # Backward pass + y.backward() # Calcola automaticamente i gradienti + + print(f"dy/dx = {x.grad}") # Gradiente rispetto a x + print(f"dy/dw = {w.grad}") # Gradiente rispetto a w + print(f"dy/db = {b.grad}") # Gradiente rispetto a b + ``` + + *Applicazione manuale della chain rule*: + + $ + y &= z^2 quad &=> quad (d y)/(d z) &= 2z = 2(7) = 14 \ + z &= u + b quad &=> quad (d z)/(d u) &= 1, quad (d z)/(d b) &= 1 \ + u &= x times w quad &=> quad (d u)/(d x) &= w = 3, quad (d u)/(d w) &= x = 2 + $ + + *Gradienti finali* (applicando la chain rule): + $ + (d y)/(d x) &= (d y)/(d z) dot (d z)/(d u) dot (d u)/(d x) = 14 dot 1 dot 3 = 42 \ + (d y)/(d w) &= (d y)/(d z) dot (d z)/(d u) dot (d u)/(d w) = 14 dot 1 dot 2 = 28 \ + (d y)/(d b) &= (d y)/(d z) dot (d z)/(d b) = 14 dot 1 = 14 + $ + + PyTorch calcola automaticamente questi valori esplorando il grafo all'indietro! +] + +=== Accumulazione dei Gradienti + +Un aspetto importante della differenziazione automatica in PyTorch è l'*accumulazione dei gradienti*. + +#attenzione()[ + Per default, PyTorch *accumula* i gradienti nel campo `.grad` di ogni tensore. Questo significa che chiamare `.backward()` multiple volte *somma* i nuovi gradienti a quelli esistenti. + + *Conseguenza pratica*: Nel training loop è necessario chiamare `optimizer.zero_grad()` o `tensor.grad.zero_()` prima di ogni backward pass per pulire i gradienti dell'iterazione precedente. +] + +#esempio()[ + ```python + x = torch.tensor([1.0], requires_grad=True) + + # Prima backward + y1 = x ** 2 + y1.backward() + print(x.grad) # tensor([2.]) (dy1/dx = 2x = 2) + + # Seconda backward SENZA azzerare + y2 = x ** 3 + y2.backward() + print(x.grad) # tensor([5.]) (2 + 3 = 5, accumula!) + + # Terza backward CON azzeramento + x.grad.zero_() + y3 = x ** 4 + y3.backward() + print(x.grad) # tensor([4.]) (corretto, gradiente pulito) + ``` +] + +=== Vantaggi della Differenziazione Automatica + +La differenziazione automatica attraverso grafi computazionali offre numerosi vantaggi: + +*1. Precisione*: I gradienti sono calcolati in modo *esatto*, non approssimato (come avverrebbe con differenze finite) + +*2. Efficienza*: La backpropagation calcola tutti i gradienti in un singolo attraversamento del grafo + +*3. Flessibilità*: Supporta *qualsiasi* funzione differenziabile composta dalle operazioni primitive + +*4. Automaticità*: Il programmatore non deve derivare manualmente le formule dei gradienti + +#nota()[ + *Complessità computazionale*: + + - *Forward pass*: $O(n)$ dove $n$ è il numero di operazioni + - *Backward pass*: $O(n)$ (stesso ordine di grandezza del forward!) + + Questo è un risultato notevole: calcolare *tutti* i gradienti costa circa quanto calcolare la funzione stessa. +] + == Cos'è un graidente Partiamo da funzioni definite su uno spazio $D$ (input vettori) che mappano in un reale. From 4136209964a95aafe4d1afc3fbffef52eb9c54e5 Mon Sep 17 00:00:00 2001 From: LucaCorra02 Date: Sun, 15 Feb 2026 12:25:57 +0100 Subject: [PATCH 04/13] add teo --- chapters/Lezione10.typ | 158 ++++++++++++++--------------------------- 1 file changed, 52 insertions(+), 106 deletions(-) diff --git a/chapters/Lezione10.typ b/chapters/Lezione10.typ index f7c963c..ed65677 100644 --- a/chapters/Lezione10.typ +++ b/chapters/Lezione10.typ @@ -55,7 +55,7 @@ Consideriamo ora il punto $mr("rosso")$ di coordinate $(1,1)$. Se volessimo _qua - $mg("Linea Verde")$ (Derivata rispetto a $y$): È la stessa cosa, ma nell'altra direzione (asse $Y$). La linea verde spessa indica il tasso di variazione di $f$ se facciamo un piccolo passo verso Nord (aumentando $y$). Se la linea verde è inclinata verso l'alto, significa che aumentando $y$ aumenta anche $f$ (salita). -=== Il Gradiente: Combinazione delle Derivate Parziali +==== Il Gradiente: Combinazione delle Derivate Parziali Il *gradiente* $nabla f(x, y)$ è un *vettore* che combina entrambe le derivate parziali: $ @@ -132,11 +132,13 @@ Nel contesto della visualizzazione 3D: - *Posizione nel piano*: Il gradiente "vive" nel piano $(x, y)$ (piano di base), non nello spazio 3D della superficie ] -=== Perpendicolarità alle Curve di Livello +==== Perpendicolarità alle Curve di Livello Un concetto fondamentale è che il gradiente è *perpendicolare* alle curve di livello: -*Curve di livello*: Se proiettiamo la superficie 3D sul piano $(x, y)$ e colleghiamo tutti i punti che hanno la *stessa altitudine* $f(x, y) = c$, otteniamo delle curve chiamate "curve di livello" +*Curve di livello*: Se proiettiamo la superficie 3D sul piano $(x, y)$ e colleghiamo tutti i punti che hanno la *stessa altitudine* $f(x, y) = c$, otteniamo delle curve chiamate _curve di livello_: + - Se le curve di livello sono vicine tra loro, la salita è ripida (il gradiente sarebbe una freccia lunga). + - Se le curve sono lontane, il terreno è dolce/quasi piatto. *Perpendicolarità*: In ogni punto, il vettore gradiente $nabla f$ è *perpendicolare* (ortogonale, a 90°) alla curva di livello che passa per quel punto. @@ -242,11 +244,11 @@ Un concetto fondamentale è che il gradiente è *perpendicolare* alle curve di l content((0.3, -0.2), text(size: 8pt, $(0,0)$), fill: green) // Legenda - rect((-2.8, 1.8), (-1, 2.6), fill: white.transparentize(20%), stroke: 0.5pt) - line((-2.6, 2.4), (-2.2, 2.4), stroke: (paint: blue.lighten(40%), thickness: 1pt)) - content((-1.4, 2.4), text(size: 7pt, [Curve di livello]), anchor: "west") - line((-2.6, 2.1), (-2.2, 2.1), mark: (end: ">"), stroke: (paint: red, thickness: 1.3pt)) - content((-1.4, 2.1), text(size: 7pt, [$nabla f$]), anchor: "west") + rect((-3.8, 1.8), (-1, 2.6), fill: white.transparentize(20%), stroke: 0.5pt) + line((-3.6, 2.4), (-3.2, 2.4), stroke: (paint: blue.lighten(40%), thickness: 1pt)) + content((-3.0, 2.4), text(size: 7pt, [Curve di livello]), anchor: "west") + line((-3.6, 2.1), (-3.2, 2.1), mark: (end: ">"), stroke: (paint: red, thickness: 1.3pt)) + content((-3, 2.1), text(size: 7pt, [$nabla f$]), anchor: "west") }), caption: [Campo vettoriale del gradiente per $f(x_1, x_2) = x_1^2 + 3x_1 x_2 + 2x_2^2$. I vettori rossi rappresentano $nabla f(x_1, x_2) = vec(2x_1 + 3x_2, 3x_1 + 4x_2)$ in vari punti, e sono sempre perpendicolari alle curve di livello blu.] ) @@ -257,21 +259,15 @@ Un concetto fondamentale è che il gradiente è *perpendicolare* alle curve di l $ ] -=== Interpretazione Geometrica del Gradiente +=== Formalizzazione geometrica del gradiente Il gradiente ha diverse interpretazioni geometriche fondamentali: -*1. Direzione di massima crescita* +1. * Direzione di massima crescita*: Il vettore $nabla f(x_0)$ punta nella direzione in cui la funzione $f$ *cresce più rapidamente* a partire dal punto $x_0$. -Il vettore $nabla f(x_0)$ punta nella direzione in cui la funzione $f$ *cresce più rapidamente* a partire dal punto $x_0$. +2. *Vettore normale alle curve di livello*: Il gradiente in un punto è *perpendicolare* alla curva (o superficie) di livello passante per quel punto. -*2. Vettore normale alle curve di livello* - -Il gradiente in un punto è *perpendicolare* alla curva (o superficie) di livello passante per quel punto. - -*3. Magnitudine come tasso di crescita* - -Il modulo $||nabla f(x_0)||$ rappresenta il *tasso di crescita massimo* di $f$ in $x_0$. +3. * Magnitudine come tasso di crescita*: Il modulo $||nabla f(x_0)||$ rappresenta il *tasso di crescita massimo* di $f$ in $x_0$. #esempio()[ Consideriamo il paraboloide: @@ -359,63 +355,6 @@ $ Questo significa che il gradiente punta nella direzione che *esce* dalla curva di livello, verso valori crescenti di $f$. ] -#esempio()[ - Per la funzione $f(x, y) = x^2 + 2y^2$, le curve di livello sono ellissi: - $ - x^2 + 2y^2 = c - $ - - #figure( - cetz.canvas({ - import cetz.draw: * - - // Assi - line((-3, 0), (3, 0), mark: (end: ">")) - content((3.3, 0), $x$) - line((0, -2.5), (0, 2.5), mark: (end: ">")) - content((0, 2.8), $y$) - - // Curve di livello (ellissi) - for c in (0.5, 1.0, 2.0, 3.0) { - let a = calc.sqrt(c) - let b = calc.sqrt(c / 2) - - // Disegna ellisse parametrica - let points = () - for i in range(0, 101) { - let t = i * 2 * calc.pi / 100 - points.push((a * calc.cos(t), b * calc.sin(t))) - } - line(..points, stroke: (paint: blue.lighten(40%), thickness: 1pt), close: true) - } - - // Etichette - content((calc.sqrt(0.5), 0.1), text(size: 7pt, $c=0.5$), anchor: "south", fill: blue) - content((calc.sqrt(2), 0.1), text(size: 7pt, $c=2$), anchor: "south", fill: blue) - - // Punti e gradienti - let test_points = ((1, 0.5), (-1, 0.7), (0.5, -1)) - - for pt in test_points { - let (x, y) = pt - circle((x, y), radius: 0.08, fill: red, stroke: none) - - // Gradiente: ∇f = (2x, 4y) - let grad_x = 2 * x * 0.25 - let grad_y = 4 * y * 0.25 - - line((x, y), (x + grad_x, y + grad_y), - mark: (end: ">"), - stroke: (paint: red, thickness: 1.5pt)) - } - - // Origine - circle((0, 0), radius: 0.1, fill: green, stroke: none) - }), - caption: [Curve di livello ellittiche per $f(x,y) = x^2 + 2y^2$. Il gradiente $nabla f = vec(2x, 4y)$ è perpendicolare alle ellissi.] - ) -] - #attenzione()[ Le curve di livello sono fondamentali nell'ottimizzazione: @@ -426,49 +365,56 @@ $ === Teorema della Direzione di Massima Discesa -Il teorema fondamentale che giustifica l'uso del gradiente nell'ottimizzazione: +Si tratta del teorema fondamentale che giustifica l'uso del gradiente nell'ottimizzazione. -*Teorema*: Dato un punto $x_0 in R^D$ e una funzione differenziabile $f: R^D -> R$, la direzione di *massima discesa* (che minimizza $f$ localmente) è data da: -$ - d^* = -nabla f(x_0) -$ +#teorema("Massima Discesa")[ + Dato un punto $x_0 in R^D$ e una funzione differenziabile $f: R^D -> R$, tra tutte le direzioni unitarie $d$ (con $||d|| = 1$), la direzione di *massima discesa* (che minimizza $f$ localmente) è data da: + $ + d^* = -(nabla f(x_0)) / (||nabla f(x_0)||) + $ + Ovvero, il *negativo del gradiente* indica la direzione in cui la funzione *decresce più rapidamente*. +] -Ovvero, il *negativo del gradiente* indica la direzione in cui la funzione decresce più rapidamente. +#dimostrazione()[ + Per la dimostrazione è necessario considerare lo *sviluppo di Taylor* al primo ordine di $f$ intorno a $x_0$: + $ + f(x_0 + alpha d) approx f(x_0) + alpha nabla f(x_0)^T d + $ -==== Dimostrazione tramite Sviluppo di Taylor + dove: + - $d$ è una direzione unitaria ($||d|| = 1$) + - $alpha > 0$ è uno step size piccolo + + #nota()[ + Lo sviluppo di Taylor ci dice che per piccoli spostamenti $alpha d$ da $x_0$, la funzione cambia approssimativamente di: + $ + Delta f approx alpha nabla f(x_0)^T d + $ + ] -Consideriamo lo sviluppo di Taylor al primo ordine di $f$ intorno a $x_0$: -$ - f(x_0 + alpha d) approx f(x_0) + alpha nabla f(x_0)^T d -$ + Vogliamo trovare la direzione $d^*$ che *minimizza* $f(x_0 + alpha d)$, ovvero che rende $Delta f$ il più negativo possibile: + $ + d^* = arg min_(||d||=1) nabla f(x_0)^T d + $ -dove: -- $d$ è una direzione unitaria ($||d|| = 1$) -- $alpha > 0$ è uno step size piccolo + Per il *teorema di Cauchy-Schwarz*: + $ + nabla f(x_0)^T d <= ||nabla f(x_0)|| dot ||d|| = ||nabla f(x_0)|| + $ -#nota()[ - Lo sviluppo di Taylor ci dice che per piccoli spostamenti $alpha d$ da $x_0$, la funzione cambia approssimativamente di: + L'uguaglianza si ottiene quando $d$ è *allineato* con $nabla f(x_0)$. Il minimo si ottiene quando: $ - Delta f approx alpha nabla f(x_0)^T d + d^* = -(nabla f(x_0))/(||nabla f(x_0)||) $ -] -Vogliamo trovare la direzione $d^*$ che *minimizza* $f(x_0 + alpha d)$, ovvero che rende $Delta f$ il più negativo possibile: -$ - d^* = arg min_(||d||=1) nabla f(x_0)^T d -$ + Ovvero, la direzione *opposta* al gradiente (normalizzato). -Per il *teorema di Cauchy-Schwarz*: -$ - nabla f(x_0)^T d <= ||nabla f(x_0)|| dot ||d|| = ||nabla f(x_0)|| -$ -L'uguaglianza si ottiene quando $d$ è *allineato* con $nabla f(x_0)$. Il minimo si ottiene quando: -$ - d^* = -(nabla f(x_0))/(||nabla f(x_0)||) -$ -Ovvero, la direzione *opposta* al gradiente (normalizzato). + +] + + #nota()[ *Conclusione*: Muoversi nella direzione $-nabla f(x_0)$ garantisce la *massima riduzione* della funzione $f$ in un intorno di $x_0$. From 46f472998389f7f7d5de8e654e2d5dcc7981f65d Mon Sep 17 00:00:00 2001 From: LucaCorra02 Date: Sun, 15 Feb 2026 12:43:19 +0100 Subject: [PATCH 05/13] update dim --- chapters/Lezione10.typ | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/chapters/Lezione10.typ b/chapters/Lezione10.typ index ed65677..959e5b9 100644 --- a/chapters/Lezione10.typ +++ b/chapters/Lezione10.typ @@ -376,42 +376,47 @@ Si tratta del teorema fondamentale che giustifica l'uso del gradiente nell'ottim ] #dimostrazione()[ + L'obbiettivo della dimostrazione è trovare una direzione unitaria $d$ che minimizza la funzione $f$ localmente intorno a $x_0$. + Per la dimostrazione è necessario considerare lo *sviluppo di Taylor* al primo ordine di $f$ intorno a $x_0$: $ f(x_0 + alpha d) approx f(x_0) + alpha nabla f(x_0)^T d $ - dove: - $d$ è una direzione unitaria ($||d|| = 1$) - $alpha > 0$ è uno step size piccolo + + La nuova _altezza_ della funzione dopo il passo ($f(x_0 + alpha d)$) è data dalla vecchia altezza ($f(x_0)$) più un termine di variazione ($alpha nabla f(x_0)^T d$). + #nota()[ Lo sviluppo di Taylor ci dice che per piccoli spostamenti $alpha d$ da $x_0$, la funzione cambia approssimativamente di: $ Delta f approx alpha nabla f(x_0)^T d $ ] - - Vogliamo trovare la direzione $d^*$ che *minimizza* $f(x_0 + alpha d)$, ovvero che rende $Delta f$ il più negativo possibile: + Per scendere al massimo nella funzione, vogliamo che questo _cambiamento_ sia il numero più negativo possibile. Siccome $alpha$ è positivo e fisso, tutto dipende dal Prodotto Scalare tra il gradiente e la tua direzione: $ - d^* = arg min_(||d||=1) nabla f(x_0)^T d + nabla f(x_0)^T d $ - - Per il *teorema di Cauchy-Schwarz*: + Il prodotto scalare tra due vettori geometricamente può essere calcolato come. $ - nabla f(x_0)^T d <= ||nabla f(x_0)|| dot ||d|| = ||nabla f(x_0)|| + u dot v = ||u|| dot ||v|| dot cos(theta) $ - - L'uguaglianza si ottiene quando $d$ è *allineato* con $nabla f(x_0)$. Il minimo si ottiene quando: + Applicando la proprietà del prodotto scalare al nostro caso: $ - d^* = -(nabla f(x_0))/(||nabla f(x_0)||) + nabla f(x_0)^T d = ||nabla f(x_0)|| dot ||d|| dot cos(theta) $ + Dove: + - $||d|| = 1$ (direzione unitaria) + - $||nabla f(x_0)||$ è un numero fisso. - Ovvero, la direzione *opposta* al gradiente (normalizzato). - - - + L'unica variabile è $cos(theta)$, che dipende dall'angolo tra il gradiente e la direzione $d$. Siccome il valore minimo del coseno vale $-1$ quando l'angolo $theta$ vale $180$ gradi, significa che i due vettori sono opposti (puntano in *direzioni esattamente opposte*): + $ + d^* = -(nabla f(x_0))/(||nabla f(x_0)||) + $ + ] From 97366d065a883fd644f4e08037d3befdbdd6c903 Mon Sep 17 00:00:00 2001 From: LucaCorra02 Date: Sun, 15 Feb 2026 12:50:31 +0100 Subject: [PATCH 06/13] update --- chapters/Lezione10.typ | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/chapters/Lezione10.typ b/chapters/Lezione10.typ index 959e5b9..6824030 100644 --- a/chapters/Lezione10.typ +++ b/chapters/Lezione10.typ @@ -416,10 +416,8 @@ Si tratta del teorema fondamentale che giustifica l'uso del gradiente nell'ottim $ d^* = -(nabla f(x_0))/(||nabla f(x_0)||) $ - -] - +] #nota()[ *Conclusione*: Muoversi nella direzione $-nabla f(x_0)$ garantisce la *massima riduzione* della funzione $f$ in un intorno di $x_0$. From 3d4347fcb5931cafd31fba4702e09ffa078e20d5 Mon Sep 17 00:00:00 2001 From: LucaCorra02 Date: Mon, 16 Feb 2026 17:30:06 +0100 Subject: [PATCH 07/13] update path --- chapters/Lezione10.typ | 185 ++++++++++++++++++++--------------------- 1 file changed, 89 insertions(+), 96 deletions(-) diff --git a/chapters/Lezione10.typ b/chapters/Lezione10.typ index 6824030..0cd67a5 100644 --- a/chapters/Lezione10.typ +++ b/chapters/Lezione10.typ @@ -19,7 +19,7 @@ $ #nota()[ Il gradiente trasforma una funzione scalare in un *campo vettoriale*: *ad ogni punto $x$* dello spazio viene associato un vettore *$nabla f(x)$*. - + Nel contesto del deep learning: - $f$ rappresenta la *funzione di loss* - $x$ rappresenta i *parametri* del modello (pesi e bias) @@ -38,15 +38,15 @@ $ Supponendo di lavorare in uno spazio vettoriale a *due dimensioni* ($R^2$, con $D = 2$), possiamo dare un'interpretazione geometrica alle derivate parziali: #figure[ - #image("/assets/Code_Generated_Image.png",width: 80%) - + #image("../assets/DerivateParziali2d.png", width: 80%) + Visualizzazione 3D di una funzione $f(x,y)$ con le derivate parziali nel punto rosso $(1,1)$. ] In particolare, nell'immagine possiamo oservare che: -- *spazio vettoriale*: rappresentato dagli assi $(x,y)$. Ogni punto $(x,y)$ rappresenta una coppia di valori per le variabili $x$ e $y$. +- *spazio vettoriale*: rappresentato dagli assi $(x,y)$. Ogni punto $(x,y)$ rappresenta una coppia di valori per le variabili $x$ e $y$. -- funzione *$f(x,y)$*: per ogni punto $(x,y)$, la funzione associa un valore scalare $f(x,y)$. Questo valore rappresenta l'*altitudine* ($z$) della superficie sopra quel punto. +- funzione *$f(x,y)$*: per ogni punto $(x,y)$, la funzione associa un valore scalare $f(x,y)$. Questo valore rappresenta l'*altitudine* ($z$) della superficie sopra quel punto. Consideriamo ora il punto $mr("rosso")$ di coordinate $(1,1)$. Se volessimo _quanto è ripida la salita_, potremo utilizzare la *derivata parziale*. Essa indica lo spostamento rispette alle due direzioni principali $(x,y)$. Nell'immagine: @@ -84,26 +84,18 @@ Nel contesto della visualizzazione 3D: content((px - 0.4, py - .4), text(size: 8pt, $(x_0, y_0)$), fill: red) // Derivata parziale rispetto a x (componente orizzontale) - let dx = 1.0 // lunghezza proporzionale a ∂f/∂x - line((px, py), (px + dx, py), - mark: (end: ">"), - stroke: (paint: blue, thickness: 2pt, dash: "dashed")) - content((px + dx/2, py - 0.3), text(size: 8pt, $(partial f)/(partial x)$), fill: blue) + let dx = 1.0 // lunghezza proporzionale a ∂f/∂x + line((px, py), (px + dx, py), mark: (end: ">"), stroke: (paint: blue, thickness: 2pt, dash: "dashed")) + content((px + dx / 2, py - 0.3), text(size: 8pt, $(partial f)/(partial x)$), fill: blue) // Derivata parziale rispetto a y (componente verticale) - let dy = 0.75 // lunghezza proporzionale a ∂f/∂y - line((px, py), (px, py + dy), - mark: (end: ">"), - stroke: (paint: green.darken(20%), thickness: 2pt, dash: "dashed")) - content((px - 0.5, py + dy/2), text(size: 8pt, $(partial f)/(partial y)$), fill: green.darken(20%)) + let dy = 0.75 // lunghezza proporzionale a ∂f/∂y + line((px, py), (px, py + dy), mark: (end: ">"), stroke: (paint: green.darken(20%), thickness: 2pt, dash: "dashed")) + content((px - 0.5, py + dy / 2), text(size: 8pt, $(partial f)/(partial y)$), fill: green.darken(20%)) // Gradiente (vettore risultante) - line((px, py), (px + dx, py + dy), - mark: (end: ">"), - stroke: (paint: red.darken(20%), thickness: 2.5pt)) - content((px + dx/2 + 0.3, py + dy/2 + 0.6), - text(size: 9pt, weight: "bold", $nabla f$), - fill: red.darken(20%)) + line((px, py), (px + dx, py + dy), mark: (end: ">"), stroke: (paint: red.darken(20%), thickness: 2.5pt)) + content((px + dx / 2 + 0.3, py + dy / 2 + 0.6), text(size: 9pt, weight: "bold", $nabla f$), fill: red.darken(20%)) // Rettangolo tratteggiato per visualizzare la composizione line((px + dx, py), (px + dx, py + dy), stroke: (dash: "dotted", paint: gray)) @@ -116,17 +108,22 @@ Nel contesto della visualizzazione 3D: rect((3.2, 0.2), (rel: (1.4, 0.9)), fill: white.transparentize(10%), stroke: 0.8pt) line((3.3, 0.9), (3.6, 0.9), mark: (end: ">"), stroke: (paint: blue, thickness: 1.5pt, dash: "dashed")) content((3.65, 0.9), text(size: 7pt, [Comp. $x$]), anchor: "west") - line((3.3, 0.65), (3.6, 0.65), mark: (end: ">"), stroke: (paint: green.darken(20%), thickness: 1.5pt, dash: "dashed")) + line( + (3.3, 0.65), + (3.6, 0.65), + mark: (end: ">"), + stroke: (paint: green.darken(20%), thickness: 1.5pt, dash: "dashed"), + ) content((3.65, 0.65), text(size: 7pt, [Comp. $y$]), anchor: "west") line((3.3, 0.4), (3.6, 0.4), mark: (end: ">"), stroke: (paint: red.darken(20%), thickness: 2pt)) content((3.65, 0.4), text(size: 7pt, weight: "bold", [Gradiente]), anchor: "west") }), - caption: [Il gradiente $nabla f$ ($mr("rosso")$) è il vettore che si ottiene combinando le due derivate parziali: la componente $mb("blu")$ $(partial f)/(partial x)$ (orizzontale) e la componente $mg("verde")$ $(partial f)/(partial y)$ (verticale). Nel piano 2D $(x,y)$, il gradiente indica la direzione di massima crescita di $f$.] + caption: [Il gradiente $nabla f$ ($mr("rosso")$) è il vettore che si ottiene combinando le due derivate parziali: la componente $mb("blu")$ $(partial f)/(partial x)$ (orizzontale) e la componente $mg("verde")$ $(partial f)/(partial y)$ (verticale). Nel piano 2D $(x,y)$, il gradiente indica la direzione di massima crescita di $f$.], ) #nota()[ *Interpretazione geometrica del gradiente*: - + - *Direzione*: Il gradiente punta nella direzione in cui la funzione cresce più rapidamente - *Magnitudine*: La lunghezza del vettore gradiente indica quanto ripida è la salita - *Posizione nel piano*: Il gradiente "vive" nel piano $(x, y)$ (piano di base), non nello spazio 3D della superficie @@ -137,18 +134,18 @@ Nel contesto della visualizzazione 3D: Un concetto fondamentale è che il gradiente è *perpendicolare* alle curve di livello: *Curve di livello*: Se proiettiamo la superficie 3D sul piano $(x, y)$ e colleghiamo tutti i punti che hanno la *stessa altitudine* $f(x, y) = c$, otteniamo delle curve chiamate _curve di livello_: - - Se le curve di livello sono vicine tra loro, la salita è ripida (il gradiente sarebbe una freccia lunga). - - Se le curve sono lontane, il terreno è dolce/quasi piatto. +- Se le curve di livello sono vicine tra loro, la salita è ripida (il gradiente sarebbe una freccia lunga). +- Se le curve sono lontane, il terreno è dolce/quasi piatto. *Perpendicolarità*: In ogni punto, il vettore gradiente $nabla f$ è *perpendicolare* (ortogonale, a 90°) alla curva di livello che passa per quel punto. #attenzione()[ *Importante*: La perpendicolarità è nel *piano $(x, y)$*, non nello spazio 3D! - + - Il gradiente è un vettore 2D: $nabla f(x, y) = vec((partial f)/(partial x), (partial f)/(partial y))$ - Le curve di livello sono curve 2D nel piano $(x, y)$ - La perpendicolarità si riferisce a queste entità 2D - + Quando visualizziamo la superficie 3D, "proiettiamo" mentalmente il gradiente sul piano di base per vedere la sua perpendicolarità alle curve di livello. ] @@ -209,34 +206,32 @@ Un concetto fondamentale è che il gradiente è *perpendicolare* alle curve di l // Punti campione e vettori gradiente let sample_points = ( - (1, 0.5), - (0.5, 1), - (-0.5, 0.8), + (1, 0.5), + (0.5, 1), + (-0.5, 0.8), (-1, -0.5), (0.8, -0.6), (1.5, 0), (0, 1.2), - (-1.2, 0.3) + (-1.2, 0.3), ) - + for pt in sample_points { let (x1, x2) = pt // Punto circle((x1, x2), radius: 0.06, fill: red, stroke: none) - + // Calcola gradiente: ∇f = (2x₁ + 3x₂, 3x₁ + 4x₂) let grad_x1 = 2 * x1 + 3 * x2 let grad_x2 = 3 * x1 + 4 * x2 - + // Scala per visualizzazione let scale = 0.15 let gx = grad_x1 * scale let gy = grad_x2 * scale - + // Disegna vettore gradiente - line((x1, x2), (x1 + gx, x2 + gy), - mark: (end: ">"), - stroke: (paint: red, thickness: 1.3pt)) + line((x1, x2), (x1 + gx, x2 + gy), mark: (end: ">"), stroke: (paint: red, thickness: 1.3pt)) } // Origine @@ -250,7 +245,7 @@ Un concetto fondamentale è che il gradiente è *perpendicolare* alle curve di l line((-3.6, 2.1), (-3.2, 2.1), mark: (end: ">"), stroke: (paint: red, thickness: 1.3pt)) content((-3, 2.1), text(size: 7pt, [$nabla f$]), anchor: "west") }), - caption: [Campo vettoriale del gradiente per $f(x_1, x_2) = x_1^2 + 3x_1 x_2 + 2x_2^2$. I vettori rossi rappresentano $nabla f(x_1, x_2) = vec(2x_1 + 3x_2, 3x_1 + 4x_2)$ in vari punti, e sono sempre perpendicolari alle curve di livello blu.] + caption: [Campo vettoriale del gradiente per $f(x_1, x_2) = x_1^2 + 3x_1 x_2 + 2x_2^2$. I vettori rossi rappresentano $nabla f(x_1, x_2) = vec(2x_1 + 3x_2, 3x_1 + 4x_2)$ in vari punti, e sono sempre perpendicolari alle curve di livello blu.], ) In un punto specifico, ad esempio $(x_1, x_2) = (1, 2)$: @@ -286,7 +281,7 @@ Il gradiente ha diverse interpretazioni geometriche fondamentali: // Configurazione let scale = 1.5 - + // Assi line((-3, 0), (3, 0), mark: (end: ">")) content((3.3, 0), $x$) @@ -305,20 +300,18 @@ Il gradiente ha diverse interpretazioni geometriche fondamentali: // Punti campione let points = ((1, 0.5), (0.7, 1.5), (-1, 1), (-1.5, -0.5), (0.5, -1.5)) - + for pt in points { let (x, y) = pt // Punto circle((x, y), radius: 0.08, fill: red, stroke: none) - + // Calcola gradiente: ∇f = (2x, 2y) - let grad_x = 2 * x * 0.3 // Scala per visualizzazione + let grad_x = 2 * x * 0.3 // Scala per visualizzazione let grad_y = 2 * y * 0.3 - + // Disegna vettore gradiente - line((x, y), (x + grad_x, y + grad_y), - mark: (end: ">"), - stroke: (paint: red, thickness: 1.5pt)) + line((x, y), (x + grad_x, y + grad_y), mark: (end: ">"), stroke: (paint: red, thickness: 1.5pt)) } // Origine @@ -332,11 +325,11 @@ Il gradiente ha diverse interpretazioni geometriche fondamentali: line((-2.6, 2.3), (-2.2, 2.3), mark: (end: ">"), stroke: (paint: red, thickness: 1.5pt)) content((-1.9, 2.3), text(size: 7pt, [$nabla f$]), anchor: "west") }), - caption: [Campo vettoriale del gradiente $nabla f(x,y) = vec(2x, 2y)$ per il paraboloide $f(x,y) = x^2 + y^2$. I vettori rossi (gradienti) sono perpendicolari alle curve di livello blu e puntano verso l'esterno (crescita).] + caption: [Campo vettoriale del gradiente $nabla f(x,y) = vec(2x, 2y)$ per il paraboloide $f(x,y) = x^2 + y^2$. I vettori rossi (gradienti) sono perpendicolari alle curve di livello blu e puntano verso l'esterno (crescita).], ) *Osservazioni*: - - All'origine $(0, 0)$, il gradiente è nullo: $nabla f(0,0) = vec(0,0)$ (punto di minimo) + - All'origine $(0, 0)$, il gradiente è nullo: $nabla f(0,0) = vec(0, 0)$ (punto di minimo) - Nei punti lontani dall'origine, i vettori gradiente sono più lunghi (crescita più rapida) - I gradienti puntano *radialmente verso l'esterno* (direzione di massima crescita) - Sono tutti *perpendicolari* ai cerchi (curve di livello) @@ -351,13 +344,13 @@ $ #nota()[ *Proprietà fondamentale*: Il gradiente $nabla f(x_0)$ in un punto $x_0$ è *ortogonale* alla curva di livello passante per $x_0$. - + Questo significa che il gradiente punta nella direzione che *esce* dalla curva di livello, verso valori crescenti di $f$. ] #attenzione()[ Le curve di livello sono fondamentali nell'ottimizzazione: - + - Un *passo di gradient descent* ci sposta da una curva di livello a un'altra con valore inferiore - La direzione *perpendicolare* alla curva (il gradiente) è la direzione di *massimo cambiamento* - Seguire il gradiente negativo ci porta verso valori decrescenti di $f$ (verso il minimo) @@ -421,7 +414,7 @@ Si tratta del teorema fondamentale che giustifica l'uso del gradiente nell'ottim #nota()[ *Conclusione*: Muoversi nella direzione $-nabla f(x_0)$ garantisce la *massima riduzione* della funzione $f$ in un intorno di $x_0$. - + Questo è il principio alla base del *Gradient Descent*! ] @@ -441,22 +434,22 @@ dove: *Algoritmo iterativo*: 1. Inizializza $x_0$ (casualmente o con euristica) 2. Per $k = 0, 1, 2, dots$ fino a convergenza: - - Calcola il gradiente: $g_k = nabla f(x_k)$ - - Aggiorna i parametri: $x_(k+1) = x_k - alpha_k g_k$ - - Controlla convergenza: se $||g_k|| < epsilon$, termina + - Calcola il gradiente: $g_k = nabla f(x_k)$ + - Aggiorna i parametri: $x_(k+1) = x_k - alpha_k g_k$ + - Controlla convergenza: se $||g_k|| < epsilon$, termina #nota()[ *Criteri di convergenza*: - + - *Condizione ideale*: $nabla f(x_k) = bold(0)$ (punto stazionario) - *Condizione pratica*: $||nabla f(x_k)|| < epsilon$ per una soglia piccola $epsilon > 0$ - + #attenzione()[ Un gradiente nullo può indicare: - Un *minimo locale* (desiderato) - Un *massimo locale* (indesiderato) - Un *punto di sella* (né minimo né massimo) - + In deep learning, i *punti di sella* sono molto più comuni dei minimi locali in alta dimensione. ] ] @@ -471,15 +464,15 @@ dove: *Iterazioni con $alpha = 0.1$*: - - $k=0$: + - $k=0$: - $x_0 = vec(3, 2)$ - $nabla f(x_0) = vec(6, 16)$ - $x_1 = vec(3, 2) - 0.1 vec(6, 16) = vec(2.4, 0.4)$ - + - $k=1$: - $nabla f(x_1) = vec(4.8, 3.2)$ - $x_2 = vec(2.4, 0.4) - 0.1 vec(4.8, 3.2) = vec(1.92, 0.08)$ - + - $k=2$: - $nabla f(x_2) = vec(3.84, 0.64)$ - $x_3 = vec(1.92, 0.08) - 0.1 vec(3.84, 0.64) = vec(1.536, 0.016)$ @@ -489,11 +482,11 @@ dove: #attenzione()[ *Scelta del Learning Rate $alpha$*: - + - $alpha$ troppo *piccolo*: convergenza molto lenta, molte iterazioni - $alpha$ troppo *grande*: oscillazioni, possibile divergenza - $alpha$ *ottimale*: bilanciamento tra velocità e stabilità - + In pratica si usano tecniche di *learning rate scheduling* (decay, adaptive methods come Adam). ] @@ -552,7 +545,7 @@ dove: content((1.5, 3), text(size: 10pt, $f(x) = x^2$), fill: blue) content((2, 2.3), text(size: 9pt, [Gradient Descent]), fill: red) }) - + Visualizzazione del gradient descent su una funzione unidimensionale. La traiettoria rossa mostra i passi iterativi che convergono al minimo (punto verde). ] @@ -586,10 +579,10 @@ $ Applicando la chain rule: $ - h'(x) &= f'(g(x)) dot g'(x) \ - &= 3g^2 dot 2x \ - &= 3(x^2 + 1)^2 dot 2x \ - &= 6x(x^2 + 1)^2 + h'(x) & = f'(g(x)) dot g'(x) \ + & = 3g^2 dot 2x \ + & = 3(x^2 + 1)^2 dot 2x \ + & = 6x(x^2 + 1)^2 $ ] @@ -607,7 +600,7 @@ dove: #nota()[ *Interpretazione per il Deep Learning*: - + In una rete neurale con $L$ layer, l'output finale è una composizione di funzioni: $ y = f_L (f_(L-1)(dots f_2(f_1(x)))) @@ -620,7 +613,7 @@ dove: #esempio()[ Consideriamo una rete neurale minima con due layer: - + - Layer 1: $z = w_1 x + b_1$ (trasformazione lineare) - Activation: $a = sigma(z)$ (funzione sigmoide) - Layer 2: $hat(y) = w_2 a + b_2$ (output) @@ -675,10 +668,10 @@ $ #nota()[ *Confronto con il Gradiente*: - + - Il *gradiente* $nabla f$ si applica a funzioni scalari: $f: R^n -> R$ (produce un vettore $in R^n$) - Lo *Jacobiano* $J_F$ si applica a funzioni vettoriali: $F: R^n -> R^m$ (produce una matrice $in R^(m times n)$) - + In particolare, se $m=1$ (funzione scalare), lo Jacobiano coincide con il gradiente trasposto: $ J_f = nabla f^T @@ -773,7 +766,7 @@ dove: #esempio()[ Consideriamo una rete neurale con due layer lineari: - + - Layer 1: $z = W_1 x in R^m$ (con $x in R^n$) - Layer 2: $y = W_2 z in R^k$ (con $z in R^m$) @@ -790,7 +783,7 @@ dove: #attenzione()[ *Importanza per la Backpropagation*: - + Durante la backpropagation, il gradiente della loss viene propagato all'indietro attraverso la rete moltiplicando ripetutamente gli Jacobiani dei vari layer. Questo è computazionalmente efficiente grazie alla struttura matriciale degli Jacobiani. ] @@ -826,12 +819,12 @@ Il grafo viene costruito *dinamicamente* durante l'esecuzione del codice (*dynam ```python import torch - + # Input e parametri x = torch.tensor([2.0], requires_grad=True) # Nodo foglia w = torch.tensor([3.0], requires_grad=True) # Nodo foglia b = torch.tensor([1.0], requires_grad=True) # Nodo foglia - + # Forward pass: costruzione del grafo u = x * w # Operazione di moltiplicazione z = u + b # Operazione di addizione @@ -852,17 +845,17 @@ Il grafo viene costruito *dinamicamente* durante l'esecuzione del codice (*dynam // Nodi input/parametri (foglie) circle((-2, 0), radius: 0.4, ..param-style, name: "x") content("x", text(size: 10pt, $x$)) - + circle((0, 0), radius: 0.4, ..param-style, name: "w") content("w", text(size: 10pt, $w$)) - + circle((2, 0), radius: 0.4, ..param-style, name: "b") content("b", text(size: 10pt, $b$)) // Operazione moltiplicazione rect((-1, 1.5), (rel: (1, 0.6)), ..op-style, name: "mul") content((-0.5, 1.8), text(size: 9pt, $times$)) - + // Nodo u circle((-0.5, 3), radius: 0.4, ..node-style, name: "u") content("u", text(size: 10pt, $u$)) @@ -903,15 +896,15 @@ Il grafo viene costruito *dinamicamente* durante l'esecuzione del codice (*dynam rect((3.2, 6.1), (rel: (0.3, 0.2)), ..op-style) content((4, 6.2), text(size: 8pt, [Operazioni]), anchor: "west") }), - caption: [Grafo computazionale per $y = (x times w + b)^2$. I nodi verdi sono parametri con `requires_grad=True`, i nodi blu sono valori intermedi, e i nodi arancioni sono operazioni.] + caption: [Grafo computazionale per $y = (x times w + b)^2$. I nodi verdi sono parametri con `requires_grad=True`, i nodi blu sono valori intermedi, e i nodi arancioni sono operazioni.], ) *Valori concreti*: Con $x=2$, $w=3$, $b=1$: $ - u &= 2 times 3 = 6 \ - z &= 6 + 1 = 7 \ - y &= 7^2 = 49 + u & = 2 times 3 = 6 \ + z & = 6 + 1 = 7 \ + y & = 7^2 = 49 $ ] @@ -937,7 +930,7 @@ Il grafo computazionale supporta due modalità di attraversamento: ```python # Backward pass y.backward() # Calcola automaticamente i gradienti - + print(f"dy/dx = {x.grad}") # Gradiente rispetto a x print(f"dy/dw = {w.grad}") # Gradiente rispetto a w print(f"dy/db = {b.grad}") # Gradiente rispetto a b @@ -946,16 +939,16 @@ Il grafo computazionale supporta due modalità di attraversamento: *Applicazione manuale della chain rule*: $ - y &= z^2 quad &=> quad (d y)/(d z) &= 2z = 2(7) = 14 \ - z &= u + b quad &=> quad (d z)/(d u) &= 1, quad (d z)/(d b) &= 1 \ - u &= x times w quad &=> quad (d u)/(d x) &= w = 3, quad (d u)/(d w) &= x = 2 + y & = z^2 quad & => quad (d y)/(d z) & = 2z = 2(7) = 14 \ + z & = u + b quad & => quad (d z)/(d u) & = 1, quad (d z)/(d b) & = 1 \ + u & = x times w quad & => quad (d u)/(d x) & = w = 3, quad (d u)/(d w) & = x = 2 $ *Gradienti finali* (applicando la chain rule): $ - (d y)/(d x) &= (d y)/(d z) dot (d z)/(d u) dot (d u)/(d x) = 14 dot 1 dot 3 = 42 \ - (d y)/(d w) &= (d y)/(d z) dot (d z)/(d u) dot (d u)/(d w) = 14 dot 1 dot 2 = 28 \ - (d y)/(d b) &= (d y)/(d z) dot (d z)/(d b) = 14 dot 1 = 14 + (d y)/(d x) & = (d y)/(d z) dot (d z)/(d u) dot (d u)/(d x) = 14 dot 1 dot 3 = 42 \ + (d y)/(d w) & = (d y)/(d z) dot (d z)/(d u) dot (d u)/(d w) = 14 dot 1 dot 2 = 28 \ + (d y)/(d b) & = (d y)/(d z) dot (d z)/(d b) = 14 dot 1 = 14 $ PyTorch calcola automaticamente questi valori esplorando il grafo all'indietro! @@ -974,17 +967,17 @@ Un aspetto importante della differenziazione automatica in PyTorch è l'*accumul #esempio()[ ```python x = torch.tensor([1.0], requires_grad=True) - + # Prima backward y1 = x ** 2 y1.backward() print(x.grad) # tensor([2.]) (dy1/dx = 2x = 2) - + # Seconda backward SENZA azzerare y2 = x ** 3 y2.backward() print(x.grad) # tensor([5.]) (2 + 3 = 5, accumula!) - + # Terza backward CON azzeramento x.grad.zero_() y3 = x ** 4 @@ -1007,10 +1000,10 @@ La differenziazione automatica attraverso grafi computazionali offre numerosi va #nota()[ *Complessità computazionale*: - + - *Forward pass*: $O(n)$ dove $n$ è il numero di operazioni - *Backward pass*: $O(n)$ (stesso ordine di grandezza del forward!) - + Questo è un risultato notevole: calcolare *tutti* i gradienti costa circa quanto calcolare la funzione stessa. ] From 6406f530d6ddd1840e9cefda2248a91e021f03c7 Mon Sep 17 00:00:00 2001 From: LucaCorra02 Date: Mon, 16 Feb 2026 18:07:25 +0100 Subject: [PATCH 08/13] update --- chapters/Lezione10.typ | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/chapters/Lezione10.typ b/chapters/Lezione10.typ index 0cd67a5..8cb7947 100644 --- a/chapters/Lezione10.typ +++ b/chapters/Lezione10.typ @@ -420,27 +420,24 @@ Si tratta del teorema fondamentale che giustifica l'uso del gradiente nell'ottim === Gradient Descent: Algoritmo di Base -L'algoritmo di *gradient descent* per minimizzare una funzione $f(x)$ è: - +Dato un punto iniziale $x_0 in R^n$ e una funzione obbiettivo $f: R^n -> R$ l'algoritmo di *discesa del gradiente* procede iterativamente. In particolare ad ogni passo: $ x_(k+1) = x_k - alpha_k nabla f(x_k) $ - dove: -- $x_k$: valore dei parametri all'iterazione $k$ -- $alpha_k > 0$: *learning rate* (passo di discesa) +- *$x_k$*: valore dei parametri all'iterazione $k$ +- *$alpha_k > 0$*: *learning rate* (passo di discesa) - $nabla f(x_k)$: gradiente calcolato in $x_k$ *Algoritmo iterativo*: 1. Inizializza $x_0$ (casualmente o con euristica) -2. Per $k = 0, 1, 2, dots$ fino a convergenza: +2. Per $k = 0, 1, 2, dots$ fino a *convergenza*: - Calcola il gradiente: $g_k = nabla f(x_k)$ - Aggiorna i parametri: $x_(k+1) = x_k - alpha_k g_k$ - Controlla convergenza: se $||g_k|| < epsilon$, termina #nota()[ *Criteri di convergenza*: - - *Condizione ideale*: $nabla f(x_k) = bold(0)$ (punto stazionario) - *Condizione pratica*: $||nabla f(x_k)|| < epsilon$ per una soglia piccola $epsilon > 0$ @@ -557,9 +554,8 @@ Nel deep learning, i modelli sono costruiti attraverso la *composizione di funzi La *chain rule* è una regola fondamentale del calcolo differenziale che permette di calcolare la derivata di funzioni composte. -*Caso unidimensionale*: - -Date due funzioni $g: R -> R$ e $f: R -> R$, la derivata della composizione $h(x) = f(g(x))$ è: +==== Caso unidimensionale +Date due funzioni $g: R -> R$ e $f: R -> R$ (derivabili), la derivata della composizione $h(x) = f(g(x))$ è: $ (d h)/(d x) = (d f)/(d g) dot (d g)/(d x) $ @@ -586,17 +582,17 @@ $ $ ] -*Caso multivariato*: +=== Caso multivariato -Per funzioni $g: R^n -> R^m$ e $f: R^m -> R^k$, la derivata della composizione $h(x) = f(g(x))$ è data dal prodotto delle matrici Jacobiane: +Siano $f: R^n -> R^m$ e $g: R^m -> R^k$ due funzioni differenziabili. Allora per ogni punto $x_0 in R^n$, lo *jacobiano* della funzione composta $h(x) = f(g(x))$ ($R^n -> R^k$) è data dal prodotto delle matrici Jacobiane: $ - J_h (x) = J_f (g(x)) dot J_g (x) + underbrace(J_h (x_0),k times n) = underbrace(J_g (f(x)), k times m) dot underbrace(J_f (x), m times n) $ dove: - $J_h (x) in R^(k times n)$: Jacobiano di $h$ -- $J_f (g(x)) in R^(k times m)$: Jacobiano di $f$ valutato in $g(x)$ -- $J_g (x) in R^(m times n)$: Jacobiano di $g$ valutato in $x$ +- $J_g (f(x)) in R^(k times m)$: Jacobiano di $f$ valutato in $g(x)$ +- $J_f (x) in R^(m times n)$: Jacobiano di $g$ valutato in $x$ #nota()[ *Interpretazione per il Deep Learning*: @@ -608,7 +604,7 @@ dove: Per calcolare il gradiente della loss rispetto ai parametri del primo layer, dobbiamo applicare ripetutamente la chain rule, moltiplicando i gradienti di tutti i layer attraversati. - Questo è il principio alla base della *backpropagation*! + Questo è il principio alla base della *backpropagation* ] #esempio()[ From e60d0108436bf6071da5a1b2de1a700b6a3c5a82 Mon Sep 17 00:00:00 2001 From: LucaCorra02 Date: Mon, 16 Feb 2026 22:24:35 +0100 Subject: [PATCH 09/13] update jacob --- chapters/Lezione10.typ | 133 ++++++++++++++++++++++++++--------------- 1 file changed, 86 insertions(+), 47 deletions(-) diff --git a/chapters/Lezione10.typ b/chapters/Lezione10.typ index 8cb7947..8895141 100644 --- a/chapters/Lezione10.typ +++ b/chapters/Lezione10.typ @@ -608,7 +608,7 @@ dove: ] #esempio()[ - Consideriamo una rete neurale minima con due layer: + Consideriamo una rete neurale minima con due layer (input e output scalari, un solo neurone nascosto, dimensone $1$): - Layer 1: $z = w_1 x + b_1$ (trasformazione lineare) - Activation: $a = sigma(z)$ (funzione sigmoide) @@ -617,19 +617,35 @@ dove: Per calcolare $(partial L)/(partial w_1)$ (gradiente rispetto al peso del primo layer), applichiamo la chain rule: $ - (partial L)/(partial w_1) = (partial L)/(partial hat(y)) dot (partial hat(y))/(partial a) dot (partial a)/(partial z) dot (partial z)/(partial w_1) + (partial L)/(partial w_1) = underbrace((partial L)/(partial hat(y)),"Step"1) dot (partial hat(y))/(partial a) dot (partial a)/(partial z) dot underbrace((partial z)/(partial w_1),"Step"4) $ dove: - - $(partial L)/(partial hat(y)) = hat(y) - y$ - - $(partial hat(y))/(partial a) = w_2$ - - $(partial a)/(partial z) = sigma(z)(1 - sigma(z))$ - - $(partial z)/(partial w_1) = x$ + - $(partial L)/(partial hat(y)) = 2 dot 1/2 (hat(y)-y) =hat(y) - y$ + - $(partial hat(y))/(partial a) = w_2$ (in quanto sto derivando in $a$, rimane solo il coefficiente $w_2$) + - $(partial a)/(partial z) = sigma(z)(1 - sigma(z))$ (derivata della sigmoide) + - $(partial z)/(partial w_1) = x$ (sto derivando rispetto a $w_1$, quindi rimane solo il coefficiente $x$) Il gradiente finale è: $ (partial L)/(partial w_1) = (hat(y) - y) dot w_2 dot sigma(z)(1 - sigma(z)) dot x $ + + Calcolando il gradiente rispetto al peso $b_1$: + $ + (partial L)/(partial b_1) = (partial L)/partial(hat(y)) dot partial(hat(y))/partial(a) dot partial(a)/partial(z) dot partial(z)/partial(b_1) \ + (hat(y)-y) dot w_2 dot sigma (z) (1 - sigma(z)) dot 1 + $ + Calcolando il gradiente rispetto al peso $w_2$: + $ + partial(L)/partial(w_2) = partial(L)/partial(hat(y)) dot partial(hat(y))/partial(w_2)\ + + (hat(y)-y) dot a + + $ + + + ] #attenzione()[ @@ -638,18 +654,16 @@ dove: == Lo Jacobiano: Gradiente Generalizzato -Quando lavoriamo con funzioni che mappano vettori in vettori (come i layer delle reti neurali), il gradiente non è sufficiente. Abbiamo bisogno dello *Jacobiano*. - -=== Definizione dello Jacobiano +Quando lavoriamo con funzioni che mappano vettori in vettori (come i layer delle reti neurali), il gradiente non è sufficiente. Abbiamo bisogno dello *Jacobiano*. Si tratta dunque di una generalizzazione del gradiente per funzioni vettoriali. -Data una funzione vettoriale $F: R^n -> R^m$: +Data una funzione *vettoriale* $F: R^n -> R^m$: $ - F(x) = vec(f_1(x), f_2(x), dots.v, f_m(x)) + F(overline(x)) = vec(f_1(overline(x)), f_2(overline(x)), dots.v, f_m(overline(x))) $ -dove $x = vec(x_1, x_2, dots, x_n) in R^n$, lo *Jacobiano* di $F$ è la matrice delle derivate parziali: +dove $overline(x) = vec(x_1, x_2, dots, x_n) in R^n$, lo *Jacobiano* di $F$ è la matrice delle derivate parziali: $ - J_F (x) = mat( + J_F = mat( (partial f_1)/(partial x_1), (partial f_1)/(partial x_2), dots, (partial f_1)/(partial x_n); (partial f_2)/(partial x_1), (partial f_2)/(partial x_2), dots, (partial f_2)/(partial x_n); dots.v, dots.v, dots.down, dots.v; @@ -674,38 +688,42 @@ $ $ ] -=== Esempio: Jacobiano di una Trasformazione Lineare +#esempio()[ + + Consideriamo $F: R^2 -> R^2$ definita da: + $ + F(x, y) = vec(f_1(x, y), f_2(x, y)) = vec(x^2 + y, x y) + $ -Consideriamo $F: R^2 -> R^2$ definita da: -$ - F(x, y) = vec(f_1(x, y), f_2(x, y)) = vec(x^2 + y, x y) -$ + *Calcoliamo lo Jacobiano*: -*Calcoliamo lo Jacobiano*: + Le componenti sono: + - $f_1(x, y) = x^2 + y$ + - $f_2(x, y) = x y$ -Le componenti sono: -- $f_1(x, y) = x^2 + y$ -- $f_2(x, y) = x y$ + Le derivate parziali sono: + - $(partial f_1)/(partial x) = 2x$, $(partial f_1)/(partial y) = 1$ + - $(partial f_2)/(partial x) = y$, $(partial f_2)/(partial y) = x$ -Le derivate parziali sono: -- $(partial f_1)/(partial x) = 2x$, $(partial f_1)/(partial y) = 1$ -- $(partial f_2)/(partial x) = y$, $(partial f_2)/(partial y) = x$ + Lo Jacobiano è una matrice $2 times 2$: + $ + J_F (x, y) = mat( + 2x, 1; + y, x + ) + $ + + In un punto specifico, ad esempio $(x, y) = (2, 3)$: + $ + J_F (2, 3) = mat( + 4, 1; + 3, 2 + ) + $ + +] -Lo Jacobiano è: -$ - J_F (x, y) = mat( - 2x, 1; - y, x - ) -$ -In un punto specifico, ad esempio $(x, y) = (2, 3)$: -$ - J_F (2, 3) = mat( - 4, 1; - 3, 2 - ) -$ #esempio()[ *Jacobiano di un layer fully-connected*: @@ -736,20 +754,41 @@ $ === Jacobiano e Chain Rule -Lo Jacobiano è essenziale per applicare la chain rule in dimensione superiore. Data la composizione $h = g compose f$: +Lo Jacobiano è essenziale per applicare la chain rule in dimensione superiore. Supponiamo di avere una funzione $f: R^n -> R^m$ (layer che prende un input di dim $n$) e una funzione $g: R^m -> R$. Consideriamo la composizione $h(x) = g compose f$: $ - h: R^n ->^f R^m ->^g R^k + h: R^n ->^f R^m ->^g R $ -Lo Jacobiano di $h$ è dato dal *prodotto* degli Jacobiani: +Il gradiente di $h$ (rispetto all'input $x$, ovvero $h^'$) è dato dal prodotto dello Jacobiano di $f$ e del gradiente di $g$: $ - J_h (x) = J_g (f(x)) dot J_f (x) + h^' = gradient_x (g)= ((partial g)/(partial f_1) dot, dots, dot (partial g)/(partial f_m))^T\ + + underbrace(J_f^T, n times m) dot underbrace(h^',m times 1) = mat( + (partial f_1)/(partial x_1), (partial f_2)/(partial x_1), dots, (partial f_m)/(partial x_1); + (partial f_1)/(partial x_2), (partial f_2)/(partial x_2), dots, (partial f_m)/(partial x_2); + dots.v, dots.v, dots.down, dots.v; + (partial f_1)/(partial x_n), (partial f_2)/(partial x_n), dots, (partial f_m)/(partial x_n) + ) dot vec((partial g)/(partial f_1), (partial g)/(partial f_2), dots, (partial g)/(partial f_m)) = vec( + (partial g)/(partial x_1), (partial g)/(partial x_2), dots, (partial g)/(partial x_n) + ) $ -dove: -- $J_f (x) in R^(m times n)$ -- $J_g (f(x)) in R^(k times m)$ -- $J_h (x) in R^(k times n)$ +#informalmente()[ + - $f$ è l'output di un layer con $m$ neuroni (un vettore). + + - $g$ è la funzione di Loss finale che prende tutti questi output e calcola un numero unico (l'errore scalare $h$). + + - Il gradiente $gradient(g)$, è un vettore di dimensione $m$ che contiene l'errore per ciascuno degli $m$ neuroni di output. + + - Lo Jacobiano $J_f$ è una matrice che descrive come ogni input $x_j$ influenza ogni output $f_i$. + +il vettore risultante $J_f^T dot gradient(g)$ ci dice come ogni input $x_j$ contribuisce all'errore totale, permettendoci di aggiornare i pesi del layer precedente in modo efficace durante la backpropagation. +] + + + + + #nota()[ *Dimensioni nel prodotto*: From a3e467d002a7e5b0d46c71cc595d695e8dee51c4 Mon Sep 17 00:00:00 2001 From: LucaCorra02 Date: Mon, 16 Feb 2026 22:31:56 +0100 Subject: [PATCH 10/13] update --- chapters/Lezione10.typ | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/chapters/Lezione10.typ b/chapters/Lezione10.typ index 8895141..f0c12a1 100644 --- a/chapters/Lezione10.typ +++ b/chapters/Lezione10.typ @@ -783,8 +783,23 @@ $ - Lo Jacobiano $J_f$ è una matrice che descrive come ogni input $x_j$ influenza ogni output $f_i$. il vettore risultante $J_f^T dot gradient(g)$ ci dice come ogni input $x_j$ contribuisce all'errore totale, permettendoci di aggiornare i pesi del layer precedente in modo efficace durante la backpropagation. + +In questo caso, la chain rule serve a raccogliere tutti i pezzetti di errore che provengono da tanti neuroni successivi diversi ($m$) e sommarli correttamente per capire come aggiornare un singolo neurone precedente ($n$). Senza la matrice jacobiana, il neurone $x_1$ non saprebbe quale segnale di errore ascoltare, perché è collegato a mille cose diverse contemporaneamente. ] +Se si avessero ad esempio $3$ layer: +- Input $x$ entra nel Layer 1 $->$ produce $f$ +- $f$ entra nel Layer 2 $->$ produce $g$ +- $g$ entra nel Layer 3 $->$ produce $h$ + + +La loss finale (errore) viene calcolata da $h$. Per sapere come aggiornare l'input iniziale $x$ (o i pesi del primo layer), applichiamo la *Chain Rule a cascata*. Invece di avere una sola matrice Jacobiana, moltiplichiamo tra loro le *matrici Jacobiane di ogni layer*: +$ + "Errore su" x = J_(f) dot J_(g) dot J_(h) dot underbrace(gradient(h), "vettore degli"\ "errori" in R^m) +$ + +Ogni matrice fa fare all'errore un _salto_ all'indietro di un layer. + From eb35f787df8edc4030b520bc01627f054c54a123 Mon Sep 17 00:00:00 2001 From: LucaCorra02 Date: Tue, 17 Feb 2026 11:00:59 +0100 Subject: [PATCH 11/13] add example --- chapters/Lezione10.typ | 395 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 374 insertions(+), 21 deletions(-) diff --git a/chapters/Lezione10.typ b/chapters/Lezione10.typ index f0c12a1..71eb6cd 100644 --- a/chapters/Lezione10.typ +++ b/chapters/Lezione10.typ @@ -586,7 +586,7 @@ $ Siano $f: R^n -> R^m$ e $g: R^m -> R^k$ due funzioni differenziabili. Allora per ogni punto $x_0 in R^n$, lo *jacobiano* della funzione composta $h(x) = f(g(x))$ ($R^n -> R^k$) è data dal prodotto delle matrici Jacobiane: $ - underbrace(J_h (x_0),k times n) = underbrace(J_g (f(x)), k times m) dot underbrace(J_f (x), m times n) + underbrace(J_h (x_0), k times n) = underbrace(J_g (f(x)), k times m) dot underbrace(J_f (x), m times n) $ dove: @@ -617,7 +617,7 @@ dove: Per calcolare $(partial L)/(partial w_1)$ (gradiente rispetto al peso del primo layer), applichiamo la chain rule: $ - (partial L)/(partial w_1) = underbrace((partial L)/(partial hat(y)),"Step"1) dot (partial hat(y))/(partial a) dot (partial a)/(partial z) dot underbrace((partial z)/(partial w_1),"Step"4) + (partial L)/(partial w_1) = underbrace((partial L)/(partial hat(y)), "Step"1) dot (partial hat(y))/(partial a) dot (partial a)/(partial z) dot underbrace((partial z)/(partial w_1), "Step"4) $ dove: @@ -639,9 +639,7 @@ dove: Calcolando il gradiente rispetto al peso $w_2$: $ partial(L)/partial(w_2) = partial(L)/partial(hat(y)) dot partial(hat(y))/partial(w_2)\ - (hat(y)-y) dot a - $ @@ -689,7 +687,7 @@ $ ] #esempio()[ - + Consideriamo $F: R^2 -> R^2$ definita da: $ F(x, y) = vec(f_1(x, y), f_2(x, y)) = vec(x^2 + y, x y) @@ -762,8 +760,7 @@ $ Il gradiente di $h$ (rispetto all'input $x$, ovvero $h^'$) è dato dal prodotto dello Jacobiano di $f$ e del gradiente di $g$: $ h^' = gradient_x (g)= ((partial g)/(partial f_1) dot, dots, dot (partial g)/(partial f_m))^T\ - - underbrace(J_f^T, n times m) dot underbrace(h^',m times 1) = mat( + underbrace(J_f^T, n times m) dot underbrace(h^', m times 1) = mat( (partial f_1)/(partial x_1), (partial f_2)/(partial x_1), dots, (partial f_m)/(partial x_1); (partial f_1)/(partial x_2), (partial f_2)/(partial x_2), dots, (partial f_m)/(partial x_2); dots.v, dots.v, dots.down, dots.v; @@ -775,16 +772,16 @@ $ #informalmente()[ - $f$ è l'output di un layer con $m$ neuroni (un vettore). - + - $g$ è la funzione di Loss finale che prende tutti questi output e calcola un numero unico (l'errore scalare $h$). - Il gradiente $gradient(g)$, è un vettore di dimensione $m$ che contiene l'errore per ciascuno degli $m$ neuroni di output. - Lo Jacobiano $J_f$ è una matrice che descrive come ogni input $x_j$ influenza ogni output $f_i$. -il vettore risultante $J_f^T dot gradient(g)$ ci dice come ogni input $x_j$ contribuisce all'errore totale, permettendoci di aggiornare i pesi del layer precedente in modo efficace durante la backpropagation. + il vettore risultante $J_f^T dot gradient(g)$ ci dice come ogni input $x_j$ contribuisce all'errore totale, permettendoci di aggiornare i pesi del layer precedente in modo efficace durante la backpropagation. -In questo caso, la chain rule serve a raccogliere tutti i pezzetti di errore che provengono da tanti neuroni successivi diversi ($m$) e sommarli correttamente per capire come aggiornare un singolo neurone precedente ($n$). Senza la matrice jacobiana, il neurone $x_1$ non saprebbe quale segnale di errore ascoltare, perché è collegato a mille cose diverse contemporaneamente. + In questo caso, la chain rule serve a raccogliere tutti i pezzetti di errore che provengono da tanti neuroni successivi diversi ($m$) e sommarli correttamente per capire come aggiornare un singolo neurone precedente ($n$). Senza la matrice jacobiana, il neurone $x_1$ non saprebbe quale segnale di errore ascoltare, perché è collegato a mille cose diverse contemporaneamente. ] Se si avessero ad esempio $3$ layer: @@ -815,28 +812,384 @@ Ogni matrice fa fare all'errore un _salto_ all'indietro di un layer. ] #esempio()[ - Consideriamo una rete neurale con due layer lineari: + Dato un vettore di input $overline(x) = (x_1, x_2) in R^2$ e due funzioni $f$ e $g$, dove: + $ + f: R^2 -> R^2 \ + f(overline(x)) = vec(x_1^2+x_2, x_1 x_2) = vec(u, v)\ + g: R^2 -> R \ + g(u,v) = u^2 - 2v + $ + Calcoliamo la funzione $h(overline(x)) = g(f(overline(x)))$: + $ + J_f = mat( + (partial f_1) / (partial x_1), (partial f_1) / (partial x_2); + (partial f_2) / (partial x_1), (partial f_2) / (partial x_2); + ) = mat( + 2x_1, 1; + x_2, x_1 + )\ + gradient g= vec((partial g)/ (partial u), (partial g)/ (partial v)) = vec(2u, -2)\ + J_f^T dot gradient g = mat( + 2x_1, x_1; + 1, x_1 + ) dot vec(2u, -2) = vec( + 4x_1^3 - 2x_2 + 4x_1^2x_2, + 2x_1^2-2x_1+2x_2 + ) + $ +] - - Layer 1: $z = W_1 x in R^m$ (con $x in R^n$) - - Layer 2: $y = W_2 z in R^k$ (con $z in R^m$) +#attenzione()[ + Durante la backpropagation, il gradiente della loss viene propagato all'indietro attraverso la rete moltiplicando ripetutamente gli Jacobiani dei vari layer. Questo è computazionalmente efficiente grazie alla *struttura matriciale degli Jacobiani*. +] - Per calcolare $(partial y)/(partial x)$, usiamo la chain rule: +== Esempio completo + +#esempio()[ + Supponiamo di avere un modello di *classificazione binaria* (comunemente chiamato *regressione logistica*) dove il dataset è dato da: $ - (partial y)/(partial x) = (partial y)/(partial z) dot (partial z)/(partial x) = W_2 dot W_1 + D = {(x_i, y_i)}_(i=1)^N\ + "dove" x_i in R^D, y_i in {0,1} $ - Lo Jacobiano della composizione è il prodotto delle matrici dei pesi: + #nota()[ + *Terminologia*: Nonostante il nome "regressione logistica", si tratta di un algoritmo di *classificazione*, non di regressione! + + - *Input*: features $x_i in R^D$ (vettori continui) + - *Output*: etichette $y_i in {0, 1}$ (classi discrete) + - Il termine "regressione" deriva dal fatto che si usa una combinazione lineare (regressione) seguita dalla funzione logistica (sigmoide) + - L'obiettivo è *classificare* gli esempi in due categorie, non predire valori continui + ] + + Il modello $z$ è dunque la funzione: $ - J_(y,x) = W_2 W_1 in R^(k times n) + z = mr(W)^T mb(x) + mr(b) $ -] + Dove $mr(W) in R^D$ e $mr(b) in R$ sono i parametri che il modello deve apprendere. In particolare vogliamo il separatore che massimizzi la distanza tra le due classi. -#attenzione()[ - *Importanza per la Backpropagation*: + #figure( + cetz.canvas({ + import cetz.draw: * + + // Griglia di sfondo + for i in range(-4, 6) { + line((i, -4), (i, 5), stroke: (paint: gray.lighten(60%), thickness: 0.5pt)) + } + for i in range(-4, 6) { + line((-4, i), (5, i), stroke: (paint: gray.lighten(60%), thickness: 0.5pt)) + } + + // Assi cartesiani + line((-4, 0), (5, 0), stroke: (paint: rgb("#00bfff"), thickness: 2pt), mark: (end: ">")) + line((0, -4), (0, 5), stroke: (paint: rgb("#00bfff"), thickness: 2pt), mark: (end: ">")) + + // Label assi + content((5.3, 0), text(size: 12pt, fill: rgb("#00bfff"), weight: "bold", $z_1$)) + content((0, 5.3), text(size: 12pt, fill: rgb("#4ade80"), weight: "bold", $z_2$)) + + // Iperpiano separatore (linea viola) + line((-3.5, 4), (4.5, -3), stroke: (paint: rgb("#a855f7"), thickness: 3pt)) + + // Equazione dell'iperpiano + content((-1.8, 3.8), text( + size: 11pt, + fill: rgb("#a855f7"), + weight: "bold", + $w^T z + b = 0$, + )) + + + // Etichetta "separatore lineare" + content((3.5, -3.2), text( + size: 10pt, + fill: rgb("#fbbf24"), + weight: "bold", + [separatore\ lineare!], + )) + + // Punti classe 1 (gialli) - parte superiore destra + let class1_points = ( + (1, 2), + (1.5, 2.5), + (2, 3), + (2.5, 2.8), + (3, 3.5), + (3.5, 3), + (4, 4), + (1.8, 1.8), + (2.8, 2.5), + (3.2, 4.2), + (1.2, 1.5), + (2.3, 3.8), + (3.8, 3.8), + (4.2, 3.2), + (1.6, 2.2), + ) - Durante la backpropagation, il gradiente della loss viene propagato all'indietro attraverso la rete moltiplicando ripetutamente gli Jacobiani dei vari layer. Questo è computazionalmente efficiente grazie alla struttura matriciale degli Jacobiani. + for pt in class1_points { + circle(pt, radius: 0.12, fill: rgb("#fbbf24"), stroke: none) + } + + // Punti classe 0 (rossi) - parte inferiore sinistra + let class0_points = ( + (-2, -1), + (-2.5, -1.5), + (-3, -2), + (-1.5, -0.5), + (-3.5, -2.5), + (-2.8, -3), + (-1.8, -1.2), + (-3.2, -1.8), + (-2.2, -2.5), + (-1.2, -0.8), + (-3.8, -3.2), + (-2.6, -0.8), + (-1.6, -1.8), + (-3.4, -1.2), + (-2, -2.8), + ) + + for pt in class0_points { + circle(pt, radius: 0.12, fill: rgb("#f87171"), stroke: none) + } + + // Punti erroneamente classificati (cerchiati) + // Errore classe 1 (giallo sotto la linea) + let errors_class1 = ((1.2, -0.5), (1.8, 0.2), (2.5, -0.8)) + for pt in errors_class1 { + circle(pt, radius: 0.12, fill: rgb("#fbbf24"), stroke: none) + circle(pt, radius: 0.35, stroke: (paint: rgb("#fbbf24"), thickness: 1.5pt, dash: "dashed"), fill: none) + } + + // Errore classe 0 (rosso sopra la linea) + let errors_class0 = ((2.8, 2), (3.5, 1.2)) + for pt in errors_class0 { + circle(pt, radius: 0.12, fill: rgb("#f87171"), stroke: none) + circle(pt, radius: 0.35, stroke: (paint: rgb("#f87171"), thickness: 1.5pt, dash: "dashed"), fill: none) + } + + // Freccia ERRORE che punta a un punto sbagliato + line((-2.5, -3), (1.0, -0.7), mark: (end: ">"), stroke: (paint: rgb("#fbbf24"), thickness: 2pt, dash: "dashed")) + content((-2.8, -3.3), text( + size: 11pt, + fill: rgb("#fbbf24"), + weight: "bold", + [ERRORE!], + )) + }), + caption: [Regressione logistica binaria: classificazione di punti in due classi (gialli e rossi) tramite un iperpiano separatore $w^T z + b = 0$. I punti cerchiati rappresentano esempi classificati erroneamente dal modello lineare.], + ) + + L'*iperpiano separatore* è definito dall'equazione: + $ + w_1 z_1 + w_2 z_2 = -b + $ + che nel piano 2D rappresenta una retta. I punti vengono classificati in base a quale lato dell'iperpiano si trovano: + - Se $w^T z + b > 0$: classe 1 (giallo) + - Se $w^T z + b < 0$: classe 0 (rosso) + + #attenzione()[ + Un modello *puramente lineare* può commettere errori quando i dati non sono linearmente separabili, come mostrato dai punti cerchiati nel grafico. La funzione *sigmoide* $sigma(z)$ trasforma l'output lineare in una probabilità, permettendo al modello di gestire meglio l'incertezza nelle zone di confine. + ] + + La funzione di *loss* utilizzata può essere la cross-entropy o NLL (Negative Log Likehood). Chiamo con $p$ e $q$ le seguenti probabilità: + $ + P(mr(y=1) | x) = mr(p)\ + P(mb(y=0)| x) = 1-p = mb(q) + $ + La funzione di loss è calcolata nel seguente modo (le predizioni del modello $hat(y) = z$ vengono passati alla funzione $sigma$): + $ + L(y, hat(y)) & = -[y log hat(y) + (1-y)(1-log hat(y))] \ + & = - y log sigma(z) - (1-y)(1-log sigma(z)) + $ + La training loss è data dalla somma delle loss per tutti i dati del dataset ($N$): + $ + L = -1/N sum_(i=1)^n [y_i log sigma(z) - (1-y_i)(1-log sigma(z))] + $ + + === Computation Graph (ad alto livello) + + Il grafo computazionale rappresenta la sequenza di operazioni dal calcolo del modello fino alla loss: + + #figure( + cetz.canvas({ + import cetz.draw: * + + // Stili + let input-style = (stroke: black, fill: green.lighten(70%), radius: 0.4) + let param-style = (stroke: black, fill: purple.lighten(70%), radius: 0.4) + let op-style = (stroke: black, fill: red.lighten(70%)) + let node-style = (stroke: black, fill: yellow.lighten(80%), radius: 0.4) + let output-style = (stroke: black, fill: green.lighten(60%), radius: 0.4) + + // Nodi input + circle((-5, 0), ..input-style, name: "x") + content("x", text(size: 11pt, weight: "bold", $x$), fill: green.darken(40%)) + + circle((-3, -1), ..param-style, name: "w") + content("w", text(size: 11pt, weight: "bold", $w$), fill: purple.darken(20%)) + + // Operazione z = wx + b + rect((-2, -0.5), (rel: (1.2, 0.8)), ..op-style, name: "z-op") + content((-1.4, -0.1), text(size: 10pt, weight: "bold", $z$), fill: white) + + // Nodo z + circle((0, 0), ..node-style, name: "z") + content("z", text(size: 11pt, weight: "bold", $z$), fill: orange.darken(20%)) + + // Operazione theta(z) + rect((1.2, -0.5), (rel: (1.2, 0.8)), ..op-style, name: "theta") + content((1.8, -0.1), text(size: 10pt, weight: "bold", $theta(z)$), fill: white) + + // Nodo predizione + circle((3.5, 0), ..node-style, name: "pred") + content("pred", text(size: 11pt, weight: "bold", $hat(y)$), fill: orange.darken(20%)) + + // Nodo target y + circle((3.5, 1.5), ..input-style, name: "y") + content("y", text(size: 11pt, weight: "bold", $y$), fill: green.darken(40%)) + + // Operazione Loss L(ŷ,y) + rect((4.7, 0.3), (rel: (1.5, 0.8)), ..op-style, name: "loss") + content((5.45, 0.7), text(size: 9pt, weight: "bold", $L(hat(y), y)$), fill: white) + + // Nodo loss finale + circle((7.5, 0.5), ..output-style, name: "L") + content("L", text(size: 11pt, weight: "bold", $L$), fill: green.darken(40%)) + + // Archi + line("x", "z-op", mark: (end: ">"), stroke: 1.5pt) + line("w", "z-op", mark: (end: ">"), stroke: 1.5pt) + line("z-op", "z", mark: (end: ">"), stroke: 1.5pt) + line("z", "theta", mark: (end: ">"), stroke: 1.5pt) + line("theta", "pred", mark: (end: ">"), stroke: 1.5pt) + line("pred", "loss", mark: (end: ">"), stroke: 1.5pt) + line("y", "loss", mark: (end: ">"), stroke: 1.5pt) + line("loss", "L", mark: (end: ">"), stroke: 1.5pt) + + // Annotazioni + content((0, -2), text(size: 9pt, style: "italic", fill: purple.darken(20%), [modello da apprendere])) + line((0, -1.8), (-3, -1.4), stroke: (paint: purple.darken(20%), dash: "dashed")) + + + // Titolo + content( + (-5, 2.5), + text( + size: 11pt, + weight: "bold", + fill: yellow.darken(50%), + [], + ), + anchor: "west", + ) + }), + caption: [Grafo computazionale ad alto livello per la classificazione binaria. Il modello da apprendere (parametri $w$) produce una predizione $hat(y)$ che viene confrontata con il target $y$ tramite la loss $L$.], + ) + + === Elementi Computazionali (singole operazioni) + + Espandendo il grafo precedente, ogni operazione viene scomposta nelle sue parti elementari con le relative *derivate parziali* per la backpropagation: + + #figure( + cetz.canvas({ + import cetz.draw: * + + // Nodo u = w × x + rect((-4.8, -0.6), (rel: (1.6, 1.2)), stroke: black) + content((-4, 0.1), text(size: 9pt, weight: "bold", $u = w times x$)) + + // Input x e w + line((-5.5, 0.2), (-4.8, 0.1), mark: (end: ">"), stroke: 1pt) + content((-5.8, 0.2), text(size: 12pt, $x$), fill: purple.darken(20%)) + + line((-5.5, -0.2), (-4.8, -0.1), mark: (end: ">"), stroke: 1pt) + content((-5.8, -0.2), text(size: 12pt, $w$), fill: purple.darken(20%)) + + + // Nodo z = u + b + rect((-2.3, -0.6), (rel: (1.6, 1.2)), stroke: black) + content((-1.5, 0.1), text(size: 10pt, weight: "bold", $z = u + b$)) + + // Input u e b + line((-3.2, 0), (-2.3, 0), mark: (end: ">"), stroke: 1pt) + content((-2.8, 0.3), text(size: 12pt, $u$)) + + line((-1.5, -1.4), (-1.5, -0.5), mark: (end: ">"), stroke: 1pt) + content((-1.2, -1.4), text(size: 12pt, $b$), fill: purple.darken(20%)) + + + // Nodo ŷ = θ(z) + rect((0.2, -0.6), (rel: (1.6, 1.2)), stroke: black) + content((1, 0.1), text(size: 10pt, weight: "bold", $hat(y) = theta(z)$)) + + // Input z + line((-0.7, 0), (0.2, 0), mark: (end: ">"), stroke: 1pt) + content((-0.3, 0.3), text(size: 12pt, $z$)) + + + // Nodo L + rect((2.7, -0.6), (rel: (1.6, 1.2)), stroke: black) + content((3.5, 0.), text(size: 10pt, weight: "bold", $L(hat(y), y)$)) + + // Input ŷ e y + line((1.8, 0), (2.7, 0), mark: (end: ">"), stroke: 1pt) + content((2.3, 0.3), text(size: 12pt, $hat(y)$)) + + line((3.5, 1), (3.5, 0.5), mark: (end: ">"), stroke: 1pt) + content((3.8, 1.2), text(size: 12pt, $y$), fill: green.darken(30%)) + + // Chain rule evidenziata + rect((-5, -3.5), (rel: (8.8, 1)), stroke: (paint: rgb("#f39c12"), thickness: 2pt)) + content((-0.6, -3.1), text( + size: 14pt, + weight: "bold", + $(partial L)/(partial mr(w)) = (partial u)/(partial w) dot (partial z)/(partial u) dot (partial hat(y))/(partial z) dot (partial L)/(partial hat(y))$, + )) + + rect((-5, -4.8), (rel: (8.8, 1)), stroke: (paint: rgb("#f39c12"), thickness: 2pt)) + content((-0.6, -4.4), text( + size: 14pt, + weight: "bold", + $(partial L)/(partial mr(b)) = (partial z)/(partial b) dot (partial hat(y))/(partial z) dot (partial L)/(partial hat(y))$, + )) + + // Titolo + content( + (-5, 2), + text( + size: 11pt, + weight: "bold", + fill: yellow.darken(50%), + [Elementi computazionali (singola ops):], + ), + anchor: "west", + ) + }), + caption: [Grafo computazionale dettagliato mostrando le singole operazioni elementari e le rispettive derivate parziali. La chain rule permette di calcolare i gradienti rispetto ai parametri $w$ e $b$ moltiplicando le derivate parziali lungo il percorso.], + ) + + #nota()[ + *Backpropagation tramite Chain Rule*: + + Per calcolare il gradiente della loss rispetto ai parametri, moltiplichiamo le derivate parziali lungo il percorso nel grafo (dalla loss verso i parametri): + + $ + (partial L)/(partial w) = underbrace((partial u)/(partial w), "locale") dot underbrace((partial z)/(partial u) dot (partial hat(y))/(partial z) dot (partial L)/(partial hat(y)), "upstream") + $ + + Ogni nodo del grafo: + - *Forward pass*: calcola l'output dato l'input + - *Backward pass*: calcola la derivata locale e la propaga all'indietro + ] ] + + + + + + == Grafi Computazionali e Differenziazione Automatica I framework moderni di deep learning (PyTorch, TensorFlow) implementano la *differenziazione automatica* (automatic differentiation, o *autograd*) attraverso *grafi computazionali*. From bc9d364f30f48e238291b1d611f6811cc188ca6c Mon Sep 17 00:00:00 2001 From: LucaCorra02 Date: Tue, 17 Feb 2026 12:09:24 +0100 Subject: [PATCH 12/13] update --- chapters/Lezione10.typ | 486 +++++++++++++++++++++++++++-------------- 1 file changed, 323 insertions(+), 163 deletions(-) diff --git a/chapters/Lezione10.typ b/chapters/Lezione10.typ index 71eb6cd..6c4019a 100644 --- a/chapters/Lezione10.typ +++ b/chapters/Lezione10.typ @@ -1194,6 +1194,183 @@ Ogni matrice fa fare all'errore un _salto_ all'indietro di un layer. I framework moderni di deep learning (PyTorch, TensorFlow) implementano la *differenziazione automatica* (automatic differentiation, o *autograd*) attraverso *grafi computazionali*. +Proprietà dell'autograd: +- Le *derivate* calcolate sono *esatte* (non delle approsimazioni) +- Funziona per funzioni implementabili attraverso programmi + +=== SGD Stocastic Gradient Descent + +Attraverso l'algoritmo *SGD*, il gradiente *non* viene computato per ogni elemento del dataset ma viene calcolato su un *batch* (sottoinsieme) di sample estratti casualmente. + +Il batch è estratto random dagli esempi di training. L'aggiornamento dei pesi adotta la seguente regola: +$ + w_(t+1) = w_t - underbrace(eta, "learning"\ "rate") gradient L (w_t; x_i, y_i) +$ +Dove $(x_i, y_i)$ si riferiscono a un singolo sample random. L'update dei pesi nel caso di *mini-batch* segue la seguente regola: ad ogni iterazione $t$ viene estratto un mini-batch $Beta_t$: +$ + w_(t+1) = w_t - eta 1/(|Beta_t|) sum_(n in B_t) gradient_w mr(l)(f(x_n;w_t),y_n) +$ + +#nota()[ + L'algoritmo è stocastic in quanto ogni aggiornamento dei pesi usa un sample random, viene introdotto del *rumore* nel calcolo del gradiente +] + +La discesa del gradiente calcolata sull'*intero dataset* (Batch Gradient Descent) è molto più lineare e *smooth*, ma è computazionalmente costosa. La SGD introduce *rumore* nel processo di ottimizzazione, con vantaggi significativi: +- L'update dei pesi è molto più *veloce* (calcolo su pochi sample) +- Il *rumore stocastico* offre proprietà benefiche: + - Capacità di _uscire_ dai minimi locali + - Capacità di _uscire_ dai saddle points +- Fornisce una *generalizzazione migliore* del modello + +#figure( + grid( + columns: 2, + column-gutter: 1em, + // Batch Gradient Descent + cetz.canvas({ + import cetz.draw: * + + // Titolo + content((0, 4.2), text(size: 11pt, weight: "bold", [Batch Gradient Descent]), anchor: "center") + + // Curve di livello (come contour) + let levels = (0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2) + for lev in levels { + let r = lev * 1.2 + // Forma ellittica (minimo al centro) + bezier( + (-r * 0.7, -r * 0.3), + (r * 0.7, -r * 0.3), + (-r * 0.5, r * 0.4), + (r * 0.5, r * 0.4), + stroke: (paint: blue.lighten(60%), thickness: 0.8pt), + ) + bezier( + (r * 0.7, -r * 0.3), + (-r * 0.7, -r * 0.3), + (r * 0.5, -r * 0.4), + (-r * 0.5, -r * 0.4), + stroke: (paint: blue.lighten(60%), thickness: 0.8pt), + ) + } + + // Percorso smooth verso il minimo + let path-points = ( + (-2.5, 1.8), + (-2.2, 1.3), + (-1.9, 0.9), + (-1.6, 0.5), + (-1.3, 0.3), + (-1.0, 0.15), + (-0.7, 0.08), + (-0.4, 0.04), + (-0.2, 0.02), + (0, 0), + ) + + for i in range(path-points.len() - 1) { + line(path-points.at(i), path-points.at(i + 1), mark: (end: ">"), stroke: (paint: blue, thickness: 2pt)) + } + + // Punto iniziale (Start) + circle((-2.5, 1.8), radius: 0.12, fill: red, stroke: red) + content((-2.5, 2.1), text(size: 9pt, fill: red, weight: "bold", [Start])) + + // Minimo + circle((0, 0), radius: 0.12, fill: green, stroke: green) + content((0, -0.35), text(size: 9pt, fill: green.darken(20%), weight: "bold", [Minimum])) + + // Etichetta percorso + content((1.8, 0.5), text(size: 8pt, fill: blue.darken(20%), style: "italic", [Consistent]), anchor: "west") + content((1.8, 0.15), text(size: 8pt, fill: blue.darken(20%), style: "italic", [Update]), anchor: "west") + + // Descrizione sotto + content((0, -2.8), text(size: 8pt, fill: rgb("#8B0000"), weight: "bold", [Whole Dataset]), anchor: "center") + content( + (0, -3.1), + text(size: 7pt, fill: gray.darken(30%), [Smooth but computationally expensive.]), + anchor: "center", + ) + }), + + // Stochastic Gradient Descent + cetz.canvas({ + import cetz.draw: * + + // Titolo + content((0, 4.2), text(size: 11pt, weight: "bold", [Stochastic Gradient Descent (SGD)]), anchor: "center") + + // Curve di livello (identiche) + let levels = (0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2) + for lev in levels { + let r = lev * 1.2 + bezier( + (-r * 0.7, -r * 0.3), + (r * 0.7, -r * 0.3), + (-r * 0.5, r * 0.4), + (r * 0.5, r * 0.4), + stroke: (paint: blue.lighten(60%), thickness: 0.8pt), + ) + bezier( + (r * 0.7, -r * 0.3), + (-r * 0.7, -r * 0.3), + (r * 0.5, -r * 0.4), + (-r * 0.5, -r * 0.4), + stroke: (paint: blue.lighten(60%), thickness: 0.8pt), + ) + } + + // Percorso noisy (zigzag) verso il minimo + let noisy-path = ( + (-2.5, 1.8), + (-2.1, 1.5), + (-2.3, 1.1), + (-1.8, 0.9), + (-1.9, 0.6), + (-1.5, 0.7), + (-1.3, 0.4), + (-1.5, 0.3), + (-1.1, 0.25), + (-0.9, 0.35), + (-0.7, 0.15), + (-0.8, 0.1), + (-0.5, 0.12), + (-0.3, 0.08), + (-0.35, 0.05), + (-0.15, 0.06), + (-0.05, 0.03), + (0.05, 0.01), + (0, 0), + ) + + for i in range(noisy-path.len() - 1) { + line(noisy-path.at(i), noisy-path.at(i + 1), mark: (end: ">"), stroke: (paint: blue, thickness: 2pt)) + } + + // Punto iniziale (Start) + circle((-2.5, 1.8), radius: 0.12, fill: red, stroke: red) + content((-2.5, 2.1), text(size: 9pt, fill: red, weight: "bold", [Start])) + + // Minimo + circle((0, 0), radius: 0.12, fill: green, stroke: green) + content((0, -0.35), text(size: 9pt, fill: green.darken(20%), weight: "bold", [Minimum])) + + // Etichetta percorso + content((1.8, 0.5), text(size: 8pt, fill: blue.darken(20%), style: "italic", [Noisy]), anchor: "west") + content((1.8, 0.15), text(size: 8pt, fill: blue.darken(20%), style: "italic", [Updates]), anchor: "west") + + // Descrizione sotto + content((0, -2.8), text(size: 8pt, fill: rgb("#8B0000"), weight: "bold", [Minibatches]), anchor: "center") + content( + (0, -3.1), + text(size: 7pt, fill: gray.darken(30%), [Noisy but efficient and generalizes better.]), + anchor: "center", + ) + }), + ), + caption: [Confronto tra *Batch Gradient Descent* (sinistra) e *Stochastic Gradient Descent* (destra). Il Batch GD segue un percorso smooth calcolando il gradiente sull'intero dataset, mentre SGD introduce rumore usando mini-batch casuali, permettendo di uscire da minimi locali e convergere più velocemente.], +) + === Cos'è un Grafo Computazionale Un *grafo computazionale* è un grafo orientato aciclico (DAG - Directed Acyclic Graph) che rappresenta la sequenza di operazioni matematiche eseguite durante il calcolo di una funzione. @@ -1202,6 +1379,8 @@ Un *grafo computazionale* è un grafo orientato aciclico (DAG - Directed Acyclic - *Nodi*: rappresentano *valori* (input, parametri, risultati intermedi, output) - *Archi*: rappresentano *operazioni* matematiche ($+, -, times, div, "exp", "log"$, ecc.) +I gradienti vengono *accumulati* nell'attributo `.grad` dei tensori. La funzione di `backward()` permette di attraversare il grafo per calcolare i gradienti. + #nota()[ Il grafo cattura la *struttura della funzione* e le *dipendenze* tra le variabili. Questo permette di calcolare automaticamente i gradienti usando la chain rule. ] @@ -1290,14 +1469,14 @@ Il grafo viene costruito *dinamicamente* durante l'esecuzione del codice (*dynam line("pow", "y", mark: (end: ">"), stroke: 1.5pt) // Legenda - rect((3, 6), (rel: (2.5, 1.8)), stroke: 1pt) + rect((3, 6.), (rel: (2.5, 1.9)), stroke: 1pt) content((4.25, 7.5), text(size: 9pt, weight: "bold", [Legenda])) - circle((3.3, 7), radius: 0.2, ..param-style) - content((4, 7), text(size: 8pt, [Parametri/Input]), anchor: "west") - circle((3.3, 6.5), radius: 0.2, ..node-style) - content((4, 6.5), text(size: 8pt, [Nodi intermedi]), anchor: "west") + circle((3.3, 7.2), radius: 0.2, ..param-style) + content((3.6, 7.2), text(size: 8pt, [Parametri/Input]), anchor: "west") + circle((3.3, 6.7), radius: 0.2, ..node-style) + content((3.6, 6.7), text(size: 8pt, [Nodi intermedi]), anchor: "west") rect((3.2, 6.1), (rel: (0.3, 0.2)), ..op-style) - content((4, 6.2), text(size: 8pt, [Operazioni]), anchor: "west") + content((3.6, 6.2), text(size: 8pt, [Operazioni]), anchor: "west") }), caption: [Grafo computazionale per $y = (x times w + b)^2$. I nodi verdi sono parametri con `requires_grad=True`, i nodi blu sono valori intermedi, e i nodi arancioni sono operazioni.], ) @@ -1354,7 +1533,7 @@ Il grafo computazionale supporta due modalità di attraversamento: (d y)/(d b) & = (d y)/(d z) dot (d z)/(d b) = 14 dot 1 = 14 $ - PyTorch calcola automaticamente questi valori esplorando il grafo all'indietro! + PyTorch calcola automaticamente questi valori esplorando il grafo all'indietro ] === Accumulazione dei Gradienti @@ -1367,28 +1546,6 @@ Un aspetto importante della differenziazione automatica in PyTorch è l'*accumul *Conseguenza pratica*: Nel training loop è necessario chiamare `optimizer.zero_grad()` o `tensor.grad.zero_()` prima di ogni backward pass per pulire i gradienti dell'iterazione precedente. ] -#esempio()[ - ```python - x = torch.tensor([1.0], requires_grad=True) - - # Prima backward - y1 = x ** 2 - y1.backward() - print(x.grad) # tensor([2.]) (dy1/dx = 2x = 2) - - # Seconda backward SENZA azzerare - y2 = x ** 3 - y2.backward() - print(x.grad) # tensor([5.]) (2 + 3 = 5, accumula!) - - # Terza backward CON azzeramento - x.grad.zero_() - y3 = x ** 4 - y3.backward() - print(x.grad) # tensor([4.]) (corretto, gradiente pulito) - ``` -] - === Vantaggi della Differenziazione Automatica La differenziazione automatica attraverso grafi computazionali offre numerosi vantaggi: @@ -1410,195 +1567,198 @@ La differenziazione automatica attraverso grafi computazionali offre numerosi va Questo è un risultato notevole: calcolare *tutti* i gradienti costa circa quanto calcolare la funzione stessa. ] -== Cos'è un graidente +== Training Loop in PyTorch -Partiamo da funzioni definite su uno spazio $D$ (input vettori) che mappano in un reale. +Il training di una rete neurale in PyTorch segue un pattern standard che combina tutti i concetti visti finora: forward pass, calcolo della loss, backpropagation e aggiornamento dei parametri. -$gradient$ è un operatore che viene applicato a una funzioni $f$ (rappresnta una rete neurale): -$ - gradient f: R^D->R^D -$ -#informalmente[ - un gradiente è un vettore di derivate parziali. - Applichiamo la definizione di derivata solo che consideriamo il tasso di variazioni su una singola variabile, tenendo costanti le altri. -] -Si fa difierenziazione solo rispetto a una variabile ecc //aggiugnere formula +=== Template Standard -#esempio()[ - $ - f: R^2 -> R - $ - Otteniamo un campo vettoriale: - $ - delta f(x) = (alpha f) / (alpha x_1) hat(i)+ (alpha f) / (alpha x_2) hat(j) - $ - Il grafico 3d ci dice che dato un vettore che parte in un punto ci dice il grado di pendenza di quella funzione. I vettori sono più o meno intesi (modulo del vettore). i vettori hanno direzioni pendenze e intesità diverse man mano che mi muovo nel dominio -] - -Aggiungee latro esempio con due variabili. +Solitamente viene utilizzato il seguente *template* per il training loop: +```python +criterion = loss_func() +optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate) -=== Curve di livello +for epoch in range(n_epochs): + for data, target in dataloader: # data è un batch + # 1. Forward Pass + output = model(data) -Sono importanti perchè quando usiamo il gradiente per raggiungere un punto di minimo in una funzione, usiamo le curve di livello. Un passo viene fatto da una cruva di livello ad un altra curva di livello (scegliendo una certa direzioni). Posso dstinguere le curve di livello in base a quelle che mi favoriscono la discesa verso il basso. + # 2. Calcolo Loss + loss = criterion(output, target) -//aggiungere immagine campo vettoriale generato dal paraboloide + # 3. Azzeramento Gradienti + optimizer.zero_grad() # Pulisce i buffer dei gradienti -Il gradiente in ogni punto della funzione è perpendicolare alla tangente della curva di livello. Il gradiente viene interpretato come direzione + # 4. Backward Pass (Backpropagation) + loss.backward() # Calcola i gradienti automaticamente -*Teo*: (direzione di massima discesa) //aggiungere -#informalmente()[ - Il segno serve altrimenti andre in salita -] -Lo sviluppo di taylor speiga il perchè: -$ - f(x) = f(x_0)+ gradient (f_x_0)^T dot (x-x_0) -$ -#informalmente()[ - La funzione in un punto intorno da $x_0$. Se voglio usare la funzione di taylor per approssimare l'intorno di un punto devo ricorrere al gradiente moltiolicato (prodotto scalre) - - //riguardare - Voglio valutare la funzione in x scritto come lo scostamento di x dal bho.\ - Vado a sostituire nella formula - $ - x_i - alpha gradient(f_(x_o)) - $ -] -Mi muovo verso un valore del dominio in cui la funzione ha valore minore. La migliore direzione è quella che coincide con $gradient f(X_0)$. Per il teorema se scelgo $d^*$ in questo modo ho una discesa ottimale in qualsiasi putno della funzione + # 5. Aggiornamento Parametri + optimizer.step() # Aggiorna i pesi usando i gradienti +``` -=== algoritmo +#nota()[ + *Perché `optimizer.zero_grad()`?* -//agiungere algoritmo -Il passo è $alpha_k$ (learning rate), potrebbe variari tutte le volte che ho un passo di iterazione tramite degli algoritmi + PyTorch *accumula* i gradienti per default. Senza azzerarli ad ogni iterazione, i gradienti si sommerebbero a quelli delle iterazioni precedenti, portando a risultati errati. -Criteri di stop. Vogliamo arrivare al minimo assoluto $gradient f(x_k) = 0$. Questa equazione è soddisfatta da un minimo relativo o minimi locali,oppure in caso di grafico a sella ho una variabile che mi fa salire e l'altra scendere. + Questa scelta di design è utile in scenari avanzati (es. gradient accumulation per batch grandi), ma richiede attenzione nel training standard. +] -Dobbiamo fissare una soglia $epsilon$. Se soo sotto la soglia mi fermo: -== Jacobiano -Quando abbiamo delle funzioni vettore->vettore sono delle funzioni non banali $R^n->R^m$ (layer dei modelli deep). +== Normalizzazione -Lo jacobiano è la generalizzazione del gradiente per le matrici. Ogni componente della funzione $F(hat(x))$ è una funzione $f_x(overline(x)))$ a sua volta(composizoni di funzioni). Il gradiente viene esteso, deve differenziare rispetto alle funzioni e alle variabili: +La normalizzazione è una tecnica fondamentale per stabilizzare e accelerare il training delle reti neurali. -La prima riga è la raccolta delle derivate parziali per la prima componente della funzione $F$. L'ultima riga è la derivata parziale rispetto all'ultima componente di $F$ grande. -#esempio()[ - Date $f_1 = x^2+y$ e $f_2 = x y$, ottengo $2x = (alpha f)/x$ -] - -#esempio()[ - Se prendo la funzione $h = g(overline(f))$. La f (composizoni di funzioni) è una variabile anche se deriva dal calcolo di $f_1(overline(x)), dots, f_k (overline(x))$. +=== Perché Normalizzare? - Se devo calcolare il gradiente di $h$ devo arrivare a moltiplicare lo jacobiao della funzione $f$ per la derivata priam di $g$: +Le reti neurali si allenano *più velocemente* e in modo *più stabile* quando: +- Gli input e le attivazioni hanno *media zero* +- Hanno *varianza comparabile* +- Evitano *differenze di scala elevate* - #esempio()[ - h è la composione di g e di f, posso dire che $h$ diepende da x, $h(overline(x))=g(f(x)))$. +*Vantaggi della normalizzazione*: +- Migliora il *condizionamento dei gradienti* +- Riduce l'*internal covariate shift* +- Stabilizza il training +- Permette learning rate più elevati - Posso usare la composizione in qualche modo //riguardare - ] -] -=== regola della catena +=== Input Normalization (Standardizzazione dei Dati) -Se predo due funzioni f e g e la loro composizione è derivabile ottendo $f'(g(x)) = r^k$ +Data una matrice di input $X in RR^(N times D)$ dove: +- $N$ = numero di sample +- $D$ = numero di feature +- $x_n^i$ = valore della feature $i$ per il sample $n$ -Posso fare la compsizione in quanto :$f(x_0)$ produce uan cosa di dim $m$ mentre $g$ prende $m$ e restituisce $k$: +*Normalizzazione per feature*: $ - g(f(x_o)) -> z in R^k + x_n^i <- (x_n^i - mu_i)/(sigma_i) $ -#attenzione()[ - per calcolare i gradienti bisogna fare prodotti basati sugli jacobiani -] - -== Loss - -Una Loss : +dove: $ - R^D -> R + mu_i = 1/N sum_(n=1)^N x_n^i, quad sigma_i = sqrt(1/N sum_(n=1)^N (x_n^i - mu_i)^2) $ -è una funzione che mappa da $R^D$ a $R$ è l'ultimo step del procedimento visto fino adesso. L'obbiettivo è minimizzare questo funzione considerando il set di parameti $w$ come variabile. -Apllichiamo l'algoritmo di discesa dei gradienti per minimizzare la funzione +*Effetto*: +- Ogni feature ha *media 0* +- Ogni feature ha *varianza 1* -== Differenziazione automatica - -Implementano il calcolo *esatto* (non approssimato) delle derivate di una funzione, si tratta di un meccanisomo di calcolo dei gradienti. +```python +# Normalizzazione in PyTorch +mean = X.mean(dim=0) # Media per feature +std = X.std(dim=0) # Deviazione standard per feature +X_normalized = (X - mean) / std +``` -Vogliamo calcolare il gradiente della funzione loss avendo a disposizione un numero di elementi che mappano l'input sull'output (sono un numero elevato). +#nota()[ + In fase di *inferenza*, si usano media e varianza calcolate sul *training set*, non sui nuovi dati. +] -Potrei prendere ogni singolo elemento e farlo transistare nel mdoello -> calcolare la predizione -> caloclare l'errore -> modificare. Si tratta dell'approccio ideale. Tuttavia è meno robusto della discesa del gradiente stocastico e computazionalmente costoso +=== Batch Normalization (BatchNorm) -=== Graident stocastic +La *Batch Normalization* normalizza le attivazioni *intermedie* della rete durante il training. -Scelgo a caso un elemento del dominio e sulal base dell'errore che si comette $L$, modifico i pesi. Un altro approccio più funzionante è basato su batch. +*Algoritmo* (per ogni feature $i$ in un layer): -Lavora nel seguente modo: +*Step 1: Normalizzazione sul mini-batch* $ - w_t+1 = w_t - n 1 / |B_t| sum_(n in B_t) gradient_w underbrace(l(f(x_n;w_t),y_n), "valore commesso medio") + hat(a)_n^i = (a_n^i - mu_i)/(sqrt(sigma_i^2 + epsilon)) $ -Prendo un batch $B$ di tot elementi (piccola rispetto al dataset) e applico la variazione dei pesi sul valor medio di tutti i batch (non sul singolo esempalre) -Quello che succedo è che se prendo il gradiente medio calcolato sul batch è che non riesco ad avere la discesa ottimale in quel punto, tuttavia ho dei vantaggi : -- Molta velocità, meno computazioni -- Capacità di fare esapece dei minimi locali (in quanto è più rumoroso) - -== Grafo computazionale +dove: +- $mu_i, sigma_i^2$ sono calcolati *sul batch corrente* +- $epsilon$ è una costante piccola per stabilità numerica (es. $10^(-5)$) -PyTorch implementa dietro le quinte autograd. Costuisce un grafo orientato (grafo diretto aicilico) che traccia tutte le operaizoni in tempo reale: -- I nodi sono le operaizoni ($+, -, *, "/"$) -- Gli archi sono l'interdipendenza tra questi nodi +*Step 2: Scala e shift apprendibili* +$ + tilde(a)_n^i = gamma_i hat(a)_n^i + beta_i +$ -Le aprime chiavi `requires_grad=True` associata ai tensori e l'operazione `backward()` ci permettono di fare il forward e modificare i pesi. +dove $gamma_i, beta_i$ sono *parametri appresi* durante il training. -I gradienti vengono accumolati, ci sono un pool di gradienti che vengono utilizzati per modificare poi i pesi, vengono accumolati nel campo `.grad` di un tensore. La regola di Differenziazione viene applicata al grafo. +```python +import torch.nn as nn -#esempio()[ - Regressione logistica (regressione per la classificazione). - $D={x_i,y_i}$ +# BatchNorm1d per layer fully-connected +bn = nn.BatchNorm1d(num_features=128) - Se mi fermo al modello lineare ottengo un iperpiano, commette errori. Se prendo la funzione sigmoide o logistica ci permette di dire che se prendo una soglia (ad esempio $0.5$) ci permette di dire che se la rete emette $z$ (logits) da +/-inifnito la funzione di attivazione li riposta in un dominio più semplice, posso discriminarli in due classi 0 e 1. +# Durante il training +x = layer(input) # Attivazioni prima di BN +x = bn(x) # Normalizzazione +x = activation(x) # Funzione di attivazione +``` - La funione di loos è la cross-entropy. +#attenzione()[ + *Comportamento Train vs Eval*: - Con $y=1$ (label True) mi trovo ad avere $-y log_2 sigma(z)$ se $y=0$ ho la funzinzone $1-log_2 sigma(z)$. + - *Training*: statistiche ($mu, sigma^2$) calcolate sul batch corrente + - *Inference*: si usano *running averages* accumulate durante il training - Grado delle computazioni, prendo in input la variabile $x$ e $w$ (nel caso del forward la $x$ è variabile e $w$ costante, viceversa nella differenziazione). Esse danno forma alla variabile $z$ (ad esempio prodotto). La catenza forma un grafo ad alto livello. L'ultima parte è quella di decisione, il modello esce con dei valori + Importante chiamare `model.eval()` in fase di test! +] - //agiungere immagini - A partre da $x$ e $w$ viene generata $u = x times w$. A questo punto lo sommo a $b$ (realizzo il livello lineare): - $ - z = u + b - $ - (Composizione di funzioni). In uscita avrò $hat(y) = theta(z)$ e infine calcolo la loss. +*Perché BatchNorm funziona?* +- Riduce l'*internal covariate shift* (cambio di distribuzione delle attivazioni tra layer) +- Permette *learning rate più alti* +- Migliora il *flusso dei gradienti* +- Ha un effetto *regolarizzante* (simile al dropout) - Una volta ottenuto il valore di loos metto in atto la discesa del gradiente con la chain rule. La chain rule è data dalla derivata di tutte le variabili in gioco: +=== Layer Normalization (LayerNorm) - - $t = (alpha l) / (alpha hat(y))$ - - $(alpha l) / a(alpha z)$ - - $(alpha z) / (alpha u)$ - - $(alpha u) / (alpha w)$ +Invece di normalizzare *tra i sample del batch*, LayerNorm normalizza *tra le feature di ogni sample*. - la deriva di $(alpha L)/(alpha w)$ è data dal prodotto di tutte le derivate. -] +*Per ogni sample $n$*: +$ + hat(a)_n^i = (a_n^i - mu_n)/(sqrt(sigma_n^2 + epsilon)) +$ -== SDG in PyTorch +dove: +$ + mu_n = 1/d sum_(i=1)^d a_n^i, quad sigma_n^2 = 1/d sum_(i=1)^d (a_n^i - mu_n)^2 +$ -`loss.backward()` fa tutto lui +*Differenza chiave*: +- BatchNorm: normalizza lungo la dimensione del *batch* (dipende dagli altri sample) +- LayerNorm: normalizza lungo la dimensione delle *feature* (indipendente dal batch) -`optimezer.step()` ci aggiunge una regola di aggiornamento. +```python +# LayerNorm in PyTorch +ln = nn.LayerNorm(normalized_shape=128) -```py -for epoch in range (n_epochs) - for data, targat in dataloader: - output = model(data)#costruisce un grafo - loss = criteration(output, target) - optimezer.zero_grad() #pulisce i buffer - loss.backward() - optimizer.step()#aggiorna i pesi +x = layer(input) +x = ln(x) # Normalizzazione per sample +x = activation(x) ``` -//aggoungere confronto mini-batch e singolo elemento -La disce del graideitne su un singolo elemnto alla volta è molto più smooth, tuttavia è molto costosa a livello computazionale. +#nota()[ + *Quando usare cosa?* + + - *BatchNorm*: ideale per CNN e reti fully-connected con batch grandi + - *LayerNorm*: preferito nei Transformer e RNN (batch piccoli, sequenze variabili) + LayerNorm non dipende dalla dimensione del batch, quindi è più stabile con batch piccoli. +] +=== Confronto tra Tecniche di Normalizzazione +#figure( + table( + columns: 4, + align: (left, center, center, center), + table.header([*Tecnica*], [*Normalizza su*], [*Dipendenza batch*], [*Uso tipico*]), + [Input Norm], [Feature], [No], [Preprocessing], + [BatchNorm], [Batch + Feature], [Sì], [CNN, FC layers], + [LayerNorm], [Feature (per sample)], [No], [Transformer, RNN], + ), + caption: [Confronto tra le principali tecniche di normalizzazione. BatchNorm normalizza lungo il batch, LayerNorm lungo le feature di ogni sample.], +) +#informalmente()[ + *Regola pratica*: + + 1. *Sempre* normalizzare gli input (standardizzazione) + 2. Usare *BatchNorm* per CNN con batch grandi ($>= 16$) + 3. Usare *LayerNorm* per Transformer e quando i batch sono piccoli + 4. Posizionare la normalizzazione *prima* o *dopo* l'attivazione (dipende dall'architettura) +] From e71cac56c4e7f3e0b2262257052c143901cc9e62 Mon Sep 17 00:00:00 2001 From: LucaCorra02 Date: Tue, 17 Feb 2026 15:25:53 +0100 Subject: [PATCH 13/13] update --- chapters/Lezione10.typ | 4 ---- 1 file changed, 4 deletions(-) diff --git a/chapters/Lezione10.typ b/chapters/Lezione10.typ index 6c4019a..8f7abb3 100644 --- a/chapters/Lezione10.typ +++ b/chapters/Lezione10.typ @@ -1582,16 +1582,12 @@ for epoch in range(n_epochs): for data, target in dataloader: # data è un batch # 1. Forward Pass output = model(data) - # 2. Calcolo Loss loss = criterion(output, target) - # 3. Azzeramento Gradienti optimizer.zero_grad() # Pulisce i buffer dei gradienti - # 4. Backward Pass (Backpropagation) loss.backward() # Calcola i gradienti automaticamente - # 5. Aggiornamento Parametri optimizer.step() # Aggiorna i pesi usando i gradienti ```