NeuralMath
Un’introduzione centrata sul codice, progettata per rendere visibile ogni operazione matematica di una rete neurale.
NeuralMath è un progetto didattico per studenti, docenti e lettori con formazione quantitativa che desiderano capire che cosa calcola realmente una rete neurale. Il sito segue un unico esempio completo in Python/NumPy, dai dati fino alla frontiera decisionale appresa. Le spiegazioni matematiche più estese restano nel testo didattico associato, così questa pagina può rimanere lineare, eseguibile e facile da consultare.
Come citare il testo didattico
Americo Cunha Jr. “A anatomia matemática de uma rede neural.” Manoscritto sottoposto a Professor de Matemática Online (PMO), 2026.
La citazione sarà aggiornata con volume, pagine e DOI dopo la pubblicazione. Nei lavori accademici, citare il testo didattico e non questo sito web.
@unpublished{cunha2026anatomia,
author = {Cunha Jr, Americo},
title = {A anatomia matemática de uma rede neural},
note = {Manuscript submitted to Professor de Matemática Online (PMO)},
year = {2026}
}Funzioni di attivazione
L’implementazione inizia con le due non linearità usate dalla rete. ReLU agisce nello strato nascosto, mentre la sigmoide trasforma il punteggio finale in un valore compreso tra 0 e 1.
def relu(s):
return np.maximum(0, s)
def relu_derivative(s):
return (s > 0).astype(float)
def sigmoid(s):
return 1 / (1 + np.exp(-s))Costruire un ampio insieme di dati sintetici
Usiamo massa e diametro come due caratteristiche fisiche. I dati sono sintetici, ma restano in intervalli plausibili per l’esempio didattico. Una curva di riferimento liscia serve soltanto a generare una geometria non banale; la rete non riceve mai questa curva.
def base_boundary(m):
return (
6.68
+ 0.74 * np.exp(-((m - 155) / 20) ** 2)
+ 1.50 / (1 + np.exp(-(m - 202) / 5))
)
X_train = np.vstack([apple_1, apple_2, orange_1, orange_2])
y_train = np.array([1.0] * 32 + [0.0] * 32)Standardizzare gli ingressi
Massa e diametro hanno scale numeriche diverse. Media e deviazione standard vengono calcolate soltanto sull’insieme di addestramento e poi riutilizzate coerentemente.
mean = X_train.mean(axis=0)
std = X_train.std(axis=0)
Xn = (X_train - mean) / stdInizializzare una rete 2–12–1
Il modello ha due ingressi, dodici neuroni ReLU nascosti e un’uscita sigmoide. In totale ci sono 49 parametri addestrabili, ma la rete resta abbastanza piccola da poter essere letta riga per riga.
rng = np.random.default_rng(42)
W1 = 0.1 * rng.standard_normal((12, 2))
b1 = np.zeros(12)
W2 = 0.1 * rng.standard_normal(12)
b2 = 0.0Propagazione in avanti
Una previsione è una sequenza di trasformazioni affini e funzioni di attivazione. Queste quattro righe costituiscono il nucleo computazionale dell’inferenza.
z1 = W1 @ x + b1
h = relu(z1)
z2 = W2 @ h + b2
y_hat = sigmoid(z2)Retropropagazione
Le derivate sono scritte esplicitamente. Non viene usata la differenziazione automatica: la regola della catena compare direttamente nel codice, che è il punto didattico centrale dell’esempio.
delta2 = (y_hat - target) * y_hat * (1 - y_hat)
dW2 = delta2 * h
db2 = delta2
delta1 = (delta2 * W2) * relu_derivative(z1)
dW1 = np.outer(delta1, x)
db1 = delta1Discesa del gradiente stocastica
A ogni epoca gli esempi vengono mescolati e i parametri aggiornati dopo ogni osservazione. La procedura riutilizza i gradienti calcolati sopra per ridurre la perdita.
for epoch in range(n_epochs):
for i in rng.permutation(len(Xn)):
# forward pass and backpropagation
W1 -= learning_rate * dW1
b1 -= learning_rate * db1
W2 -= learning_rate * dW2
b2 -= learning_rate * db2Che cosa produce l’addestramento
Con il seme casuale e gli iperparametri fissati qui, la piccola rete classifica i 64 esempi di addestramento e gli 8 esempi di test illustrativi secondo le etichette definite per l’esperimento sintetico.
Final mean loss: 0.0001785644
Training accuracy: 1.0000
Illustrative test accuracy: 1.0000
Test outputs:
[121.0, 7.20] -> 0.999927 -> apple
[135.0, 7.45] -> 0.999900 -> apple
[152.0, 7.75] -> 0.999780 -> apple
[171.0, 7.32] -> 0.986972 -> apple
[121.0, 6.28] -> 0.000019 -> orange
[152.0, 6.86] -> 0.000009 -> orange
[189.0, 6.48] -> 0.000028 -> orange
[208.0, 7.55] -> 0.014957 -> orangeDisegnare la frontiera decisionale appresa
Dopo l’addestramento, la rete viene valutata su una griglia fitta. Il livello y-hat = 0,5 diventa la frontiera decisionale appresa e mostra la geometria non lineare costruita dallo strato nascosto.
masses = np.linspace(116, 214, 500)
diameters = np.linspace(6.0, 8.85, 500)
M, D = np.meshgrid(masses, diameters)
grid = np.column_stack([M.ravel(), D.ravel()])
P = predict(grid, mean, std, W1, b1, W2, b2).reshape(M.shape)
ax.contour(M, D, P, levels=[0.5], linewidths=2.2)
Risorse complete
Gli script completi, i notebook e gli output riproducibili sono disponibili qui sotto. Il codice mostrato in tutte le lingue mantiene gli stessi identificatori canonici in inglese, evitando divergenze tra le traduzioni.
Estensioni future
NeuralMath è progettato per crescere come una sequenza di esempi computazionali. Le estensioni previste includono la dinamica dell’addestramento, la visualizzazione del contributo dei neuroni nascosti, il controllo dei gradienti, la classificazione multiclasse con softmax, reti più profonde e piccoli esperimenti interattivi nel browser.
L’autore
Americo Cunha Jr è uno scienziato computazionale, ricercatore presso il Laboratório Nacional de Computação Científica (LNCC) e professore associato presso l’Universidade do Estado do Rio de Janeiro (UERJ). La sua ricerca si colloca all’intersezione tra dinamica non lineare, modellazione matematica e computazionale, quantificazione dell’incertezza, problemi inversi e intelligenza artificiale/apprendimento automatico scientifico. Ha ricevuto il Premio ABMEC per giovani scienziati nel 2023 ed è attivo in collaborazioni scientifiche ed editoriali internazionali.
Licenza

Salvo diversa indicazione, il testo esplicativo del sito e le figure originali sono disponibili con licenza Creative Commons Attribuzione 4.0 Internazionale (CC BY 4.0). Il PDF didattico può essere soggetto alla licenza della versione pubblicata dalla rivista. Il codice sorgente è distribuito separatamente e dovrebbe adottare una licenza software dedicata.
Sostieni NeuralMath
Se questo materiale gratuito ti è stato utile, puoi sostenerne la manutenzione con un piccolo contributo di 5 USD. Il sostegno è completamente facoltativo e non modifica mai l’accesso ai contenuti.