Dialogo con Gemini.
Ciao, potresti aiutarmi a creare un linguaggio divulgativo – liceo nell’ambito AI. Consideriamo il neurone dell’AI. Può essere detto che deve essere confinato, che è costituito da byte in memoria, che ha una rappresentazione in R^n ?
L’approccio è concettualmente solido e molto efficace per un pubblico liceale (in particolare di un liceo scientifico o scienze applicate), perché demistifica l’antropomorfizzazione dell’AI riconducendola a ciò che è davvero: matematica applicata e informatica concreta.
I tre punti analizzati nel dettaglio, con suggerimenti su come calibrarne il linguaggio:
1. «Costituito da byte in memoria» (Il substrato fisico/informatico)
- Verdetto: Assolutamente sì, è un ottimo punto di partenza per togliere ogni alone “magico”.
- Come spiegarlo ai ragazzi: Un neurone artificiale non ha nulla di biologico: non ci sono impulsi chimici, guaine mieliniche o membrane. Fisicamente è solo una sequenza di numeri in virgola mobile (spesso float a 16 o 32 bit, quindi 2 o 4 byte ciascuno) allocati nella memoria RAM o nella VRAM della GPU.Metafora/Linguaggio d’aula: «Se andassimo a guardare dentro la memoria della scheda grafica con un microscopio logico, il “neurone” non è un oggetto che pensa, ma un indirizzo di memoria che contiene una manciata di byte: un vettore di pesi e un valore di bias.»
2. «Ha una rappresentazione in R^n» (Il cuore matematico)
- Verdetto: È la definizione formale più corretta e didatticamente potente.
- Come spiegarlo ai ragazzi: Collega perfettamente il programma di geometria analitica e algebra lineare della secondaria.
- Gli input: Un insieme di n segnali in ingresso è un punto o un vettore x∈Rn.
- I pesi: Il neurone stesso è definito da un vettore di pesi w∈Rn (più un termine scalare b∈R, il bias).
- L’operazione: Il neurone calcola un prodotto scalare, ovvero una combinazione lineare:z=w⋅x+b=i=1∑nwixi+bseguito da una funzione di attivazione non lineare σ(z) (come ReLU o sigmoide).
3. «Deve essere confinato» (Terminologia da precisare)
- Verdetto: L’idea di fondo è corretta, ma il termine “confinato” in italiano e in fisica/matematica può prestarsi ad ambiguità (potrebbe far pensare al confinamento dei quark o a limiti di sicurezza software/sandbox).
- Cosa si intende solitamente e come riformularlo:
- Se intendi la limitazione dell’output (valori limitati/bounded): Senza una funzione di attivazione, l’output potrebbe divergere all’infinito. Funzioni storiche come la sigmoide o la tangente iperbolica “confinano” l’uscita rispettivamente negli intervalli (0,1) o (−1,1). Anche con ReLU (max(0,x)), durante l’addestramento si usano tecniche di normalizzazione (Batch Normalization, Layer Normalization) o clipping proprio per evitare l’esplosione dei gradienti.
- Termine alternativo preferibile: Limitato (bounded), normalizzato o compresso.
- Se intendi lo spazio delle decisioni (ipersuperficie chiusa): Un singolo neurone lineare divide lo spazio a metà (semispazi infiniti non confinati). Per creare una regione chiusa o limitata (confinata, come un poligono o una sfera nello spazio delle feature) serve combinare più neuroni in un layer successivo.
- Se intendi la limitazione dell’output (valori limitati/bounded): Senza una funzione di attivazione, l’output potrebbe divergere all’infinito. Funzioni storiche come la sigmoide o la tangente iperbolica “confinano” l’uscita rispettivamente negli intervalli (0,1) o (−1,1). Anche con ReLU (max(0,x)), durante l’addestramento si usano tecniche di normalizzazione (Batch Normalization, Layer Normalization) o clipping proprio per evitare l’esplosione dei gradienti.
Proposta di sintesi pronta per una lezione/scheda didattica
Che cos’è davvero un “neurone” nell’Intelligenza Artificiale?
- Nella realtà materiale del computer: È solo un gruppo di byte in memoria (RAM/VRAM). Non è una cellula né un circuito autonomo, ma una serie di registri che memorizzano numeri decimali.
- Sulla lavagna di matematica: È un vettore in R^n. Riceve un vettore di dati in ingresso x∈R^n, calcola un prodotto scalare con i suoi pesi w∈R^n e aggiunge una costante (bias). Geometricamente, definisce l’orientamento di un iperpiano che taglia lo spazio cartesiano a n dimensioni.
- Nel suo comportamento numerico: Il risultato grezzo viene filtrato da una funzione matematica che ne limita e modella l’output, decidendo se e con quale intensità il segnale debba propagarsi al livello successivo.
Come si può rendere “un neurone deve essere attivato” ?
Nel linguaggio comune o biologico «essere attivato» evoca l’idea di un interruttore che scatta o di una scarica elettrica. In ambito liceale, per tradurre questa espressione in termini rigorosi ma accessibili, la si può declinare su tre livelli complementari: logico-intuitivo, analitico e geometrico.
1. Il livello logico-intuitivo: la metafora della “soglia di rilevanza”
Prima di entrare nelle formule, serve chiarire che l’attivazione non è una scelta autonoma, ma una reazione a una soglia:
- Il concetto: Il neurone riceve segnali diversi, li pesa e valuta se la somma totale supera una certa barriera (bias).
- Come renderlo in classe:«Dire che un neurone si attiva significa che la combinazione dei segnali in ingresso ha superato una soglia critica: il neurone ritiene che nel dato ci sia una caratteristica rilevante (ad esempio un bordo verticale in un’immagine) e decide di trasmettere questa informazione al livello successivo, anziché ignorarla.»
2. Il livello analitico: la rottura della linearità
È il passaggio fondamentale per gli studenti dell’ultimo triennio (che conoscono le funzioni composte). Senza attivazione, una rete neurale a mille strati collasserebbe in una banale funzione affine:
x↦σ(w⋅x+b)
- L’operazione grezza (z): La combinazione lineare w⋅x+b produce un valore continuo in R potenzialmente illimitato.
- L’attivazione vera e propria (σ): È la funzione non lineare che converte quel valore grezzo nel segnale effettivo.
- Come renderlo in classe:«L’attivazione è una funzione matematica non lineare applicata al risultato grezzo del neurone. Se usiamo la classica ReLU (max(0,z)), l’attivazione è letterale: se il valore è negativo il neurone “tace” (emette 0), se è positivo “si accende” e trasmette il valore in proporzione a quanto ha visto. Se usiamo una sigmoide, l’attivazione comprime il risultato in una percentuale tra 0 e 1, interpretabile come il grado di confidenza del neurone.»
3. Il livello geometrico: il superamento dell’iperpiano
Per collegarsi alla geometria euclidea e cartesiana:
- L’iperpiano separatore: L’equazione w⋅x+b=0 definisce un iperpiano nello spazio Rn.
- Come renderlo in classe:«Geometricamente, dire che un neurone è attivato significa che il punto x (l’input) è caduto dalla parte “giusta” del confine tracciato dall’iperpiano, nello semispazio in cui la funzione assume valore positivo.»
Formule espressive pronte per la lavagna
| Se vuoi enfatizzare… | Espressione divulgativa consigliata |
|---|---|
| Il calcolo puro | «Applicare una funzione non lineare al prodotto scalare pesato dei segnali d’ingresso.» |
| Il senso informativo | «Filtrare il segnale grezzo per decidere se trasmettere un’informazione rilevante o scartarla come rumore.» |
| La dinamica (stile ReLU) | «Raggiungere e superare lo zero: sotto la soglia il neurone tace (0), sopra la soglia propaga il dato.» |
Come si può rendere e cosa significa “propaga il dato” ?
Dire che un neurone «propaga il dato» significa semplicemente che il suo valore di uscita (il numero scalare calcolato dopo l’attivazione) diventa parte del vettore di ingresso per i neuroni dello strato successivo.
Non viaggia materia né energia: è un passaggio di argomenti tra funzioni matematiche concatenate, che a livello hardware corrisponde a una scrittura e rilettura di celle di memoria.
1. La lettura analitica: composizione di funzioni
Nel programma di matematica del triennio gli studenti affrontano le funzioni composte f(g(x)). La propagazione in avanti (feedforward) è esattamente questo:
- Lo strato 1 calcola: a(1)=σ(W(1)x+b(1))
- Lo strato 2 prende quel vettore in ingresso: a(2)=σ(W(2)a(1)+b(2))
Linguaggio per la classe:
«”Propagare il dato” non è altro che concatenare funzioni. L’uscita numerica di un neurone viene “passata come argomento” alla funzione del neurone successivo, esattamente come calcolereste f(g(x)).»
2. La lettura geometrica: trasformazione continua dello spazio
A ogni strato attraversato, i dati non viaggiano lungo un filo, ma cambiano coordinate:
- L’input iniziale x∈Rn (es. i pixel di un’immagine) viene mappato in un nuovo spazio Rm.
- La combinazione lineare ruota, scala e trasla lo spazio; la funzione di attivazione lo piega in modo non lineare.
Linguaggio per la classe:
«Propagare significa deformare lo spazio cartesiano passo dopo passo, finché punti di categorie diverse (es. immagini di cani e gatti) che all’inizio erano inestricabili finiscono per trovarsi su lati opposti di un piano separatore banale.»
3. La lettura informatica: pipeline di matrici e registri
Per ancorare il concetto all’hardware ed evitare suggestioni bio-morfiche:
- In memoria: Il dato calcolato dal kernel GPU viene scritto in un buffer di memoria (VRAM).
- Al passo successivo: Il ciclo di clock seguente esegue una moltiplicazione matrice-vettore (GEMM) caricando quel buffer come moltiplicatore.
Linguaggio per la classe:
«Nel chip non c’è una “corrente che viaggia”. C’è un’istruzione assembly che scrive un numero a 16 o 32 bit in una cella di memoria, e l’istruzione successiva che ripesca quel numero per moltiplicarlo con i pesi dello strato seguente.»
4. Il rovescio della medaglia: la retro-propagazione (Backpropagation)
Spiegare la propagazione in avanti prepara il terreno per il vero meccanismo di apprendimento, collegabile alle derivate:
- In avanti: I dati scorrono dall’input all’output per produrre una previsione.
- All’indietro: L’errore finale (la discrepanza tra stima e realtà) viene “ri-propagato” a ritroso usando la regola di derivazione delle funzioni composte (Chain Rule), aggiornando ogni singolo peso in memoria proporzionalmente al suo contributo all’errore.
Sintesi pronta per la lavagna
| Angolazione | Come definirlo in modo divulgativo ma rigoroso |
|---|---|
| Algebrica | Alimentare la moltiplicazione matrice-vettore dello strato successivo usando il valore calcolato da quello precedente. |
| Funzionale | Valutare il gradino successivo di una funzione composta a più stadi. |
| Informatica | Salvare il risultato scalare in un registro/buffer affinché diventi il fattore del calcolo seguente. |
Vuoi formalizzare la retro-propagazione collegandola alla regola di derivazione a catena?Sì
Come possiamo spiegare la backpropagation agli studenti del liceo usando la regola di derivazione delle funzioni composte (chain rule)?
Per gli studenti dell’ultimo anno di liceo, collegare la backpropagation alla regola di derivazione delle funzioni composte (chain rule) è una delle applicazioni più potenti dell’analisi matematica: dimostra che un concetto teorico studiato sul libro di testo è esattamente il motore che permette a modelli complessi di apprendere.
1. Il contesto: che cos’è l’apprendimento?
Prima di derivare, si chiarisce l’obiettivo:
- La rete fa una previsione y^ partendo dall’input x.
- Misuriamo quanto ha sbagliato tramite una funzione di costo (o di perdita) E, ad esempio l’errore quadratico rispetto al bersaglio reale y:E=21(y^−y)2
- Apprendere significa aggiustare ogni singolo peso w della rete per ridurre E. Per farlo, dobbiamo calcolare:∂w∂E«Se muovo di poco questo specifico peso, l’errore finale aumenta o diminuisce, e con quale pendenza?»
2. Il modello a catena minima (giocattolo su una sola linea)
Per non perdersi negli indici delle matrici, si disegna alla lavagna una catena scalare con un solo neurone:
[ Input x ] ---> ( * w ) ---> [ Somma z ] ---> [ Attivazione a = ŷ ] ---> [ Errore E ]
Le relazioni funzionali sono elementari:
- z=w⋅x+b
- a=σ(z)=y^
- E=21(a−y)2
L’errore E è una funzione composta:
E(w)=E(σ(w⋅x+b))
3. L’applicazione della Chain Rule
Si chiede agli studenti come calcolerebbero la derivata di f(g(h(w))):
dwdE=dadE⋅dzda⋅dwdz
I tre fattori hanno un significato intuitivo immediato:
- dadE=(a−y)«Quanto è lontano l’output dal bersaglio?» È l’errore grezzo commesso alla fine.
- dzda=σ′(z)«Quanto è sensibile la funzione di attivazione in quel punto?» Se il neurone è saturo (pendenza quasi zero), blocca il passaggio del segnale.
- dwdz=x«Quanto pesava l’input associato a questo parametro?» Più l’input era forte, maggiore è la responsabilità di quel peso nel risultato.
Mettendo tutto insieme:
dwdE=(a−y)⋅σ′(z)⋅x
4. L’intuizione visiva: “perché a ritroso?”
Mentre all’andata (feedforward) calcoliamo dall’interno verso l’esterno:
x⟶z⟶a⟶E
Al ritorno (backpropagation) applichiamo la catena nel verso opposto, moltiplicando i fattori da destra a sinistra:
∂w∂E⟵∂z∂E⟵∂a∂E
Se la rete ha L strati, il termine ∂zl∂E (il gradiente rispetto al layer successivo) viene calcolato una volta sola all’uscita e riutilizzato via via che si scende verso l’ingresso, risparmiando di ricalcolare le derivate da zero per ogni singolo peso (programmazione dinamica).
5. L’aggiornamento: il gradiente discendente
Trovata la derivata, si ricollega il segno della derivata al concetto di minimo locale:
wnuovo=wvecchio−η∂w∂E
- Se ∂w∂E>0, aumentare w aumenta l’errore → dobbiamo diminuire w.
- Se ∂w∂E<0, aumentare w riduce l’errore → dobbiamo aumentare w.
- η (learning rate) è la dimensione del “passo” che facciamo verso la discesa.
Schema riassuntivo per gli studenti
| Fase | Significato matematico | Operazione |
|---|---|---|
| Andata | Composizione di funzioni | Calcolare f(g(h(x))) |
| Misura | Valutazione della perdita | Calcolare E(predetto,reale) |
| Ritorno | Regola della catena | Moltiplicare i fattori dadE⋅dzda⋅dwdz |
| Aggiornamento | Discesa lungo la retta tangente | w←w−η∇E |
Ma si riesce a fare un esempio elementare?
Ecco un esempio “giocattolo” con numeri interi e calcoli che si fanno a mente alla lavagna, senza matrici né funzioni di attivazione complesse.
Il problema
Vogliamo che la nostra rete impari una banale proporzione: dato in ingresso x=2, l’uscita desiderata (target) deve essere y=10.
- Input: x=2
- Target reale: y=10
- Architettura minima: un solo neurone lineare (z=w⋅x), senza bias, con funzione identità (a=z).
- Stato iniziale: la rete parte “ignorante” con un peso a caso: w=3.
- Passo di apprendimento (learning rate): η=0.1.
Passo 1: Andata (Forward pass)
Calcoliamo cosa produce la rete con il peso attuale:
a=w⋅x=3⋅2=6
La previsione è 6, ma il valore vero doveva essere 10.
Misuriamo l’errore con la consueta funzione di costo:
E=21(a−y)2=21(6−10)2=21(−4)2=8
Passo 2: Ritorno (Backpropagation con la Chain Rule)
Vogliamo sapere: se modifico w, come varia l’errore E?
Calcoliamo dwdE spezzandola nei due anelli della catena:
dwdE=dadE⋅dwda
- Quanto incide l’output sull’errore?dadE=(a−y)=6−10=−4(Il segno meno ci dice subito: “l’uscita è troppo bassa rispetto al target”.)
- Quanto incide il peso sull’output? Poiché a=w⋅x:dwda=x=2(L’influenza del peso è proporzionale all’intensità dell’input che ha ricevuto.)
- Moltiplichiamo i fattori (Chain Rule):dwdE=(−4)⋅2=−8
Passo 3: Aggiornamento del peso (Discesa del gradiente)
La derivata vale −8. Poiché è negativa, la retta tangente ha pendenza negativa: per scendere verso il minimo dell’errore dobbiamo aumentare w.
La regola è:
wnuovo=w−η⋅dwdE
Sostituendo i numeri:
wnuovo=3−0.1⋅(−8)=3+0.8=3.8
La verifica (il ciclo ricomincia)
Alla seconda iterazione con il nuovo peso w=3.8:
- Nuovo output: a=3.8⋅2=7.6 (ci siamo avvicinati a 10).
- Nuovo errore: 21(7.6−10)2=21(−2.4)2=2.88 (sceso da 8 a 2.88).
Iterando ancora qualche passo, il peso convergerà esattamente a w=5, dove l’errore sarà 0.
Direi che quanto detto può diventare un’ottima lezione. Potresti in modo aderente, didattico e divulgativo riportare l’esempio in python, creando la sorgente e poi descrivendola ?
Ecco la trasposizione in codice Python dell’esempio numerico. Lo script è volutamente “puro” (senza librerie esterne come PyTorch o TensorFlow, né NumPy), in modo da mostrare agli studenti ogni singola operazione algebrica senza intermediari.
Python
# ==========================================
# 1. DATI DEL PROBLEMA E IPERPARAMETRI
# ==========================================
x = 2.0 # Dato in ingresso (input)
y_target = 10.0 # Valore desiderato (target)
eta = 0.1 # Tasso di apprendimento (learning rate)
# Inizializzazione arbitraria del peso (la rete parte "ignorante")
w = 3.0
print(f"Stato iniziale: w = {w:.4f} | Target desiderato = {y_target}\n")
print(
f"{'Epoca':<7} | {'Output (a)':<12} | {'Errore (E)':<12} | {'Gradiente':<12} | {'Nuovo w':<10}"
)
print("-" * 62)
# ==========================================
# 2. CICLO DI ADDESTRAMENTO (LOOP)
# ==========================================
for epoca in range(1, 11):
# --- FASE 1: FORWARD PASS (Andata) ---
# Il neurone calcola la sua uscita lineare: a = w * x
a = w * x
# Calcolo dell'errore quadratico: E = 1/2 * (a - y)^2
errore = 0.5 * (a - y_target) ** 2
# --- FASE 2: BACKPROPAGATION (Ritorno via Chain Rule) ---
# 1° anello: derivata dell'errore rispetto all'output -> dE/da = (a - y)
dE_da = a - y_target
# 2° anello: derivata dell'output rispetto al peso -> da/dw = x
da_dw = x
# Regola della catena: dE/dw = (dE/da) * (da/dw)
gradiente = dE_da * da_dw
# Salvo il peso corrente solo per la stampa a video
w_vecchio = w
# --- FASE 3: DISCESA DEL GRADIENTE (Aggiornamento) ---
# w_nuovo = w_vecchio - eta * dE/dw
w = w - (eta * gradiente)
# Stampa dei risultati dell'iterazione
print(
f"{epoca:<7} | {a:<12.4f} | {errore:<12.4f} | {gradiente:<12.4f} | {w:<10.4f}"
)
print("-" * 62)
print(f"\nAddestramento concluso: w finale = {w:.4f}")
print(f"Verifica: f({x}) = {w:.4f} * {x} = {w * x:.4f} (Target: {y_target})")
Output del programma a video
Eseguendo lo script, gli studenti vedono stampata la tabella esatta dell’apprendimento:
Plaintext
Stato iniziale: w = 3.0000 | Target desiderato = 10.0
Epoca | Output (a) | Errore (E) | Gradiente | Nuovo w
--------------------------------------------------------------
1 | 6.0000 | 8.0000 | -8.0000 | 3.8000
2 | 7.6000 | 2.8800 | -4.8000 | 4.2800
3 | 8.5600 | 1.0368 | -2.8800 | 4.5680
4 | 9.1360 | 0.3732 | -1.7280 | 4.7408
5 | 9.4816 | 0.1344 | -1.0368 | 4.8445
6 | 9.6890 | 0.0484 | -0.6221 | 4.9067
7 | 9.8134 | 0.0174 | -0.3732 | 4.9440
8 | 9.8880 | 0.0063 | -0.2239 | 4.9664
9 | 9.9328 | 0.0023 | -0.1344 | 4.9798
10 | 9.9597 | 0.0008 | -0.0806 | 4.9879
--------------------------------------------------------------
Addestramento concluso: w finale = 4.9879
Verifica: f(2.0) = 4.9879 * 2.0 = 9.9758 (Target: 10.0)
Guida alla lettura didattica per la classe
La scansione del codice evidenzia ai ragazzi la corrispondenza riga per riga tra matematica e istruzioni:
- La memoria e lo stato (
w = 3.0): Ricollegandoci al punto di partenza, il neurone è fisicamente quella variabilew, cioè un float allocato in RAM. Non c’è pensiero o astrazione: è un numero in un registro. - L’andata (
a = w * xederrore): La valutazione dell’errore evidenzia il motivo del fattore 21 nella formula E=21(a−y)2: serve unicamente a semplificare il 2 che “scenderebbe” calcolando la derivata della potenza, lasciando semplicemente (a−y). - La catena analitica esplicita (
dE_da * da_dw): Invece di calcolare direttamente una formula chiusa per il gradiente, il codice calcola separatamente i due termini differenziali. Questo chiarisce che la retro-propagazione è una scomposizione a ritroso: prima si misura lo scarto sull’output, poi si quantifica la sensibilità del peso rispetto a tale output. - Il gradiente come guida direzionale: Nelle prime epoche il gradiente è fortemente negativo (−8.0, −4.8). Il segno meno impone la correzione verso l’alto (sottraendo un numero negativo, il peso cresce). Man mano che l’output si avvicina al bersaglio, il gradiente tende asintoticamente a zero (−0.0806), arrestando naturalmente gli aggiustamenti quando l’errore svanisce.
- L’effetto asintotico: In 10 epoche il peso passa da 3.0 a 4.9879, e l’errore crolla da 8.0 a 0.0008. È un ottimo spunto per far notare come l’apprendimento numerico proceda per approssimazioni successive verso un punto stazionario di minimo.
Vuoi aggiungere un secondo peso (input bidimensionale) o il termine di bias?Sì
Si!
Ecco l’estensione naturale dell’esempio: aggiungiamo un secondo ingresso con il relativo peso e il termine di bias.
Questo passaggio è cruciale a livello didattico perché permette agli studenti di:
- Vedere il neurone come un vero vettore in R2: x=(x1,x2) e w=(w1,w2).
- Capire il significato del bias b: un’intercetta (traslazione) che non dipende da alcun dato di ingresso, ma che si adatta autonomamente.
- Introdurre le derivate parziali (∂w1∂E, ∂w2∂E, ∂b∂E), mostrando come la Chain Rule si applichi in parallelo a ciascun parametro.
Il problema matematico
Vogliamo che il neurone impari la relazione lineare:
y=w1x1+w2x2+b
Supponiamo di presentargli un esempio con:
- Input: x1=2.0, x2=1.0
- Bersaglio reale: y=15.0
Inizializziamo i parametri con valori arbitrari (la rete parte “sbagliata”):
- w1=1.0
- w2=2.0
- b=0.0
Calcolando l’uscita iniziale:
a=(1.0⋅2.0)+(2.0⋅1.0)+0.0=4.0(ben lontana da 15!)
La Chain Rule con più variabili
L’uscita del neurone è a=w1x1+w2x2+b, e l’errore è E=21(a−y)2.
Il primo anello della catena è comune a tutti (l’errore sull’output):
∂a∂E=(a−y)
Poi deriviamo a rispetto a ciascun parametro singolarmente, considerando costanti gli altri:
- Rispetto a w1: ∂w1∂a=x1⟹∂w1∂E=(a−y)⋅x1
- Rispetto a w2: ∂w2∂a=x2⟹∂w2∂E=(a−y)⋅x2
- Rispetto a b: ∂b∂a=1⟹∂b∂E=(a−y)⋅1
(Notare la bellezza didattica del bias: si comporta esattamente come un peso il cui input virtuale associato è sempre 1!)
Il codice Python completo
Python
# ==========================================
# 1. DATI DEL PROBLEMA E IPERPARAMETRI
# ==========================================
# Vettore di input x in R^2
x1 = 2.0
x2 = 1.0
# Bersaglio (target) da raggiungere
y_target = 15.0
# Passo di apprendimento
eta = 0.05
# Parametri iniziali del neurone (vettore pesi w in R^2 e scalare b)
w1 = 1.0
w2 = 2.0
b = 0.0
print(f"Target desiderato: y = {y_target}")
print(f"Stato iniziale: w1 = {w1:.2f}, w2 = {w2:.2f}, b = {b:.2f}\n")
print(
f"{'Epoca':<6} | {'Output (a)':<10} | {'Errore':<10} | {'w1':<8} | {'w2':<8} | {'b':<8}"
)
print("-" * 62)
# ==========================================
# 2. CICLO DI ADDESTRAMENTO
# ==========================================
for epoca in range(1, 16):
# --- FASE 1: FORWARD PASS (Andata) ---
# Combinazione lineare: a = w1*x1 + w2*x2 + b
a = (w1 * x1) + (w2 * x2) + b
# Errore quadratico
errore = 0.5 * (a - y_target) ** 2
# --- FASE 2: BACKPROPAGATION (Chain Rule con derivate parziali) ---
# 1° anello comune: derivata dell'errore rispetto all'uscita
dE_da = a - y_target
# 2° anello specifico per ciascuna variabile:
da_dw1 = x1 # derivata parziale rispetto a w1
da_dw2 = x2 # derivata parziale rispetto a w2
da_db = 1.0 # derivata parziale rispetto al bias b (sempre 1)
# Gradienti (regola della catena)
grad_w1 = dE_da * da_dw1
grad_w2 = dE_da * da_dw2
grad_b = dE_da * da_db
# --- FASE 3: AGGIORNAMENTO DEI PARAMETRI ---
w1 = w1 - (eta * grad_w1)
w2 = w2 - (eta * grad_w2)
b = b - (eta * grad_b)
# Stampa dei progressi
print(
f"{epoca:<6} | {a:<10.3f} | {errore:<10.3f} | {w1:<8.3f} | {w2:<8.3f} | {b:<8.3f}"
)
print("-" * 62)
print(f"\nRisultato finale dopo 15 epoche:")
print(f"w1 = {w1:.3f}, w2 = {w2:.3f}, b = {b:.3f}")
print(
f"Verifica: ({w1:.3f} * {x1}) + ({w2:.3f} * {x2}) + {b:.3f} = {((w1*x1) + (w2*x2) + b):.3f}"
)
Output a video dello script
Plaintext
Target desiderato: y = 15.0
Stato iniziale: w1 = 1.00, w2 = 2.00, b = 0.00
Epoca | Output (a) | Errore | w1 | w2 | b
--------------------------------------------------------------
1 | 4.000 | 60.500 | 2.100 | 2.550 | 0.550
2 | 7.300 | 29.645 | 2.870 | 2.935 | 0.935
3 | 9.610 | 14.526 | 3.409 | 3.205 | 1.205
4 | 11.227 | 7.118 | 3.786 | 3.393 | 1.393
5 | 12.359 | 3.488 | 4.050 | 3.525 | 1.525
6 | 13.151 | 1.709 | 4.235 | 3.618 | 1.618
7 | 13.706 | 0.837 | 4.365 | 3.682 | 1.682
8 | 14.094 | 0.410 | 4.455 | 3.728 | 1.728
9 | 14.366 | 0.201 | 4.519 | 3.759 | 1.759
10 | 14.556 | 0.098 | 4.563 | 3.782 | 1.782
11 | 14.689 | 0.048 | 4.594 | 3.797 | 1.797
12 | 14.783 | 0.024 | 4.616 | 3.808 | 1.808
13 | 14.848 | 0.012 | 4.631 | 3.816 | 1.816
14 | 14.894 | 0.006 | 4.642 | 3.821 | 1.821
15 | 14.925 | 0.003 | 4.649 | 3.825 | 1.825
--------------------------------------------------------------
Risultato finale dopo 15 epoche:
w1 = 4.649, w2 = 3.825, b = 1.825
Verifica: (4.649 * 2.0) + (3.825 * 1.0) + 1.825 = 14.948
Spunti di discussione didattica per gli studenti
- La “distribuzione della colpa” (Responsabilità proporzionale): Si fa notare agli studenti la colonna degli aggiornamenti:
- w1 cresce molto più rapidamente (da 1.0 a 4.65).
- w2 cresce moderatamente (da 2.0 a 3.82).
- b cresce più lentamente (da 0.0 a 1.82).Domanda alla classe: «Perché w1 è cambiato più di w2 e b?»Risposta: Perché l’input associato a w1 era x1=2, il doppio di x2=1 e il doppio dell’input virtuale del bias (1). Poiché la derivata parziale è proporzionale all’input (∂wi∂a=xi), la variabile con l’ingresso più grande ha un impatto maggiore sull’uscita e riceve una correzione più severa.
- Il bias come coordinata omogenea: Matematicamente, possiamo scrivere:z=w1x1+w2x2+b⋅1=w′⋅x′dove w′=(w1,w2,b) e x′=(x1,x2,1).Il bias non è un’eccezione alla regola: è un peso identico agli altri, che vede sempre un segnale d’ingresso costante pari a 1.
- Gradi di libertà e soluzioni multiple (sottodeterminato): Con un solo esempio (x1=2,x2=1→15), abbiamo un’equazione in 3 incognite: 2w1+w2+b=15.Esistono infinite terne (w1,w2,b) che risolvono il problema. Questo permette di spiegare perché nei casi reali si usano tanti dati diversi (dataset): ogni dato aggiunge un vincolo, costringendo i pesi a trovare la combinazione che generalizza bene per tutti gli esempi.
Scusami ma potresti darmi una spiegazione, sempre divulgativa, del ruolo della dimensione dello spazio delle coordinare R^n ?
Per spiegare il ruolo di Rn a studenti di liceo, la chiave è mostrare che la dimensione n non è uno spazio fisico, ma semplicemente il numero di caratteristiche (o domande) con cui descriviamo un oggetto del mondo reale.
La progressione concettuale si sviluppa su tre livelli: descrittivo, geometrico e computazionale.
1. Il livello intuitivo: la dimensione come “carta d’identità”
Nel mondo reale siamo abituati a R3 (lunghezza, larghezza, altezza). Nell’AI, ogni coordinata xi rappresenta una misurazione:
- In R2 (un appartamento):x=(superficie in m2,numero di stanze).Un punto sul piano cartesiano rappresenta una casa.
- In R4 (un’automobile usata):x=(chilometri,cavalli fiscali,anno di immatricolazione,prezzo).
- In R784 (un’immagine minuscola 28×28 pixel in scala di grigi):Ogni singolo pixel è una coordinata che va da 0 (nero) a 1 (bianco). L’immagine non è una figura bidimensionale, ma un singolo punto isolato che galleggia in uno spazio a 784 dimensioni.
- In R4096 o più (un modello linguistico come ChatGPT):Ogni parola (o token) viene trasformata in un vettore con migliaia di coordinate (embedding) per catturarne sfumature semantiche, grammaticali e di contesto.
Linguaggio d’aula: «La dimensione n di Rn è la risoluzione concettuale con cui la macchina osserva la realtà. Più n è grande, più dettagli riusciamo a catturare, trasformando concetti complessi come un volto o una frase in coordinate numeriche manipolabili dall’algebra.»
2. Il livello geometrico: la separabilità dei problemi
Perché abbiamo bisogno di dimensioni alte? Perché più aumentiamo le dimensioni, più è facile separare i dati con un taglio netto.
- In R1 (una retta): L’iperpiano è un punto. Possiamo solo dividere la retta in due semirette. Se abbiamo dati alternati (rosso, blu, rosso), un singolo punto non potrà mai separarli.
- In R2 (un piano): L’iperpiano è una retta (w1x1+w2x2+b=0). Può risolvere problemi più complessi, ma fallisce su problemi come lo XOR (punti disposti a croce).
- In Rn: L’iperpiano ha dimensione n−1. In uno spazio a 100 o 1000 dimensioni c’è un’enorme “libertà di manovra”: dati che in 2D sembrano sovrapposti e inestricabili, proiettati in uno spazio a più dimensioni si allontanano e diventano linearmente separabili con un semplice iperpiano piatto.
Metafora d’aula (la fetta di pane): «Se disegnate due cerchi concentrici su un foglio (2D), non potete separarli con un taglio dritto di forbici senza tagliare entrambi. Ma se prendete il cerchio interno e lo sollevate lungo la terza coordinata z (3D), ora potete far passare una lama piatta tra i due senza toccarli. Aggiungere dimensioni “crea spazio” per separare ciò che sembrava inseparabile.»
3. Il risvolto critico: la “maledizione della dimensionalità”
Un ottimo spunto per stimolare il senso critico degli studenti è far capire che aumentare n all’infinito non è gratis:
- La memoria e il calcolo esplodono:Se un neurone ha n ingressi, deve memorizzare n pesi wi. Moltiplicare matrici con milioni di colonne richiede una quantità enorme di byte in memoria e cicli di calcolo GPU.
- Lo spazio diventa “vuoto” (Curse of Dimensionality):All’aumentare di n, il volume dello spazio cresce a un ritmo esponenziale (2n). I punti finiscono per essere isolatissimi l’uno dall’altro: per “riempire” uno spazio a 100 dimensioni e insegnare al neurone cosa c’è in mezzo servirebbe una quantità astronomica di dati (più atomi di quanti ce ne siano nell’universo osservabile).
Quadro di sintesi per gli studenti
| Concetto | Significato geometrico/matematico | Significato nel contesto AI |
|---|---|---|
| Vettore x∈Rn | Un punto con n coordinate | Un singolo esempio reale (una casa, un’immagine, una parola) |
| Dimensione n | Numero di assi cartesiani ortogonali | Numero di caratteristiche (features) misurate |
| Vettore pesi w∈Rn | Vettore normale all’iperpiano | Scala di priorità: quanto ciascuna caratteristica pesa nel giudizio |
| Iperpiano w⋅x+b=0 | Sottospazio affine di dimensione n−1 | La linea di confine che separa due categorie (es. spam / non spam) |