mercoledì 18 giugno 2025

Corso sulla Struttura dell’Intelligenza Artificiale: Creare una mini-AI autonoma


Creare una mini-AI autonoma

Obiettivo del modulo

Progettare, addestrare e deployare una micro-AI che svolge un compito ben definito (testo, immagini o decisioni), con pipeline completa: input → decisione AI → output → validazione, interfaccia d’uso (CLI, API o web), logging e salvataggio/ripristino dei pesi. Il percorso è hands-on e progressivo: si parte da un baseline semplice, poi si estende.


Scaletta passo-passo

🕐 Scoping e setup ambiente

  • Scegli il dominio:
    • Testo: classificatore di notizie (politica/sport/tech).
    • Immagini: generatore di descrizioni per immagini pre-caricate (feature estratte + template).
    • Decisioni: AI che suggerisce azioni su una checklist (regole+modello).
  • Definisci l’output: etichetta, punteggio, testo, raccomandazione con motivazione breve.
  • Setup: Python 3.10+, virtualenv, pacchetti minimi: pip install numpy pandas scikit-learn joblib fastapi uvicorn streamlit pydantic
  • Repo: struttura consigliata:
    mini_ai/
    ├─ data/ # dataset grezzi e processati
    ├─ models/ # pesi, vectorizer, versioni
    ├─ src/
    │ ├─ config.py
    │ ├─ preprocess.py
    │ ├─ model.py
    │ ├─ train.py
    │ ├─ eval.py
    │ ├─ serve_api.py # FastAPI
    │ └─ ui_streamlit.py # interfaccia web
    └─ logs/

🕑 Dati e metrica di successo

  • Raccolta: CSV con colonne minime (es. text,label per il testo; image_path,caption per immagini).
  • Split: train/val/test (70/15/15) con stratificazione per classi.
  • Metriche:
    • Classificazione: accuracy, F1 macro (classi sbilanciate), matrice di confusione.
    • Generazione (caption): BLEU/ROUGE (anche valutazione umana light: 1–5 coerenza).
    • Decisioni su checklist: precision@k e tasso di adozione (quante azioni proposte accettate).

🕒 Baseline funzionante (semplice & robusto)

Obiettivo: avere una prima versione end-to-end che produce un output coerente, anche se non perfetto.

  • Testo (consigliato per iniziare): CountVectorizer + Logistic Regression (veloce, solido, interpretabile).
    # src/train.py (estratto – baseline testo)
    import pandas as pd
    from sklearn.model_selection import train_test_split
    from sklearn.feature_extraction.text import CountVectorizer
    from sklearn.linear_model import LogisticRegression
    from sklearn.pipeline import Pipeline
    from sklearn.metrics import classification_report
    import joblib, os
    df = pd.read_csv("data/news.csv") # colonne: text,label
    train, test = train_test_split(df, test_size=0.2, stratify=df.label, random_state=42)
    pipe = Pipeline([
    ("vec", CountVectorizer(max_features=30000, ngram_range=(1,2))),
    ("clf", LogisticRegression(max_iter=200, n_jobs=-1))
    ])
    pipe.fit(train.text, train.label)
    pred = pipe.predict(test.text)
    print(classification_report(test.label, pred, digits=3))
    os.makedirs("models", exist_ok=True)
    joblib.dump(pipe, "models/news_baseline.joblib")
  • Immagini (baseline didattico): estrai feature con un backbone pre-addestrato (es. ResNet da torchvision), poi Nearest Neighbors per suggerire la caption dell’immagine più simile (semplice ma utile per il flusso end-to-end).
  • Decisioni: Rule-first + piccolo modello: regole deterministiche per i casi chiari; modello di classificazione binaria per consigliare “fai/non fare” dove le regole non bastano.

🕓 Validazione, error analysis, versioning

  • Valida sullo split di test; salva classification_report in logs/ con timestamp.
  • Errori ricorrenti: estrai i falsi positivi/negativi, crea una “lista nera” di pattern e una todo di miglioramenti (es. pulizia testo, stopword dominio-specifiche).
  • Versiona modelli/dati:
    # src/config.py
    MODEL_VERSION = "v1.0.0"
    ARTIFACT_DIR = f"models/{MODEL_VERSION}/"
    Salva anche le feature (vectorizer) e la configurazione usata (seed, parametri, vocabolario).

🕔 Interfacce d’uso (CLI, API, Web)

  • CLI (per uso locale/automazione):
    # src/model.py (inference)
    import joblib
    _pipe = joblib.load("models/news_baseline.joblib")
    def predict_text(txt: str):
    label = _pipe.predict([txt])[0]
    prob = max(_pipe.predict_proba([txt])[0])
    return {"label": label, "confidence": float(prob)}
    # cli.py
    import argparse
    from src.model import predict_text
    parser = argparse.ArgumentParser()
    parser.add_argument("--text", required=True)
    args = parser.parse_args()
    print(predict_text(args.text))
  • API (per integrazioni):
    # src/serve_api.py
    from fastapi import FastAPI
    from pydantic import BaseModel
    from src.model import predict_text
    app = FastAPI(title="Mini-AI API")
    class Item(BaseModel):
    text: str
    @app.post("/predict")
    def predict(item: Item):
    return predict_text(item.text)
    # Avvio: uvicorn src.serve_api:app --reload --port 8000
  • Web UI (demo rapida):
    # src/ui_streamlit.py
    import streamlit as st
    from src.model import predict_text
    st.title("🧠 Mini-AI Classificatore di Notizie")
    txt = st.text_area("Inserisci il testo della notizia")
    if st.button("Predici"):
    out = predict_text(txt)
    st.write(f"**Classe:** {out['label']} | **Confidenza:** {out['confidence']:.2f}")
    Avvio: streamlit run src/ui_streamlit.py

🕕 Logging, debugging, salvataggio/riuso pesi

  • Logging strutturato (JSON line per facile analisi):
    # src/logging_utils.py
    import json, time, os
    def log_event(event: dict, fname="logs/events.jsonl"):
    os.makedirs("logs", exist_ok=True)
    event["ts"] = time.time()
    with open(fname, "a", encoding="utf-8") as f:
    f.write(json.dumps(event, ensure_ascii=False) + "\n")
  • Usalo in API/UI:
    # dentro /predict
    res = predict_text(item.text)
    log_event({"route": "predict", "input_len": len(item.text), "output": res})
    return res
  • Salvataggio & ripristino: già visto con joblib; per reti neurali usa torch.save/model.save() (TF). Aggiungi checksum o hash del file e della config per riproducibilità.
  • Debugging:
    • stampa le top-n feature che “spingono” la predizione (es. coef_ di Logistic Regression) per audit.
    • logga eccezioni con exc_info=True, conserva input problematica in logs/bad_cases/.

🕖 Hardening & deploy

  • Seed & determinismo: imposta random_state ovunque per esperimenti ripetibili.
  • Config separata (.yaml o .json) per parametri (feature, modello, soglie).
  • Test: unit test su preprocess e su un paio di casi attesi del modello.
  • Docker (opzionale):
    # Dockerfile (minimal)
    FROM python:3.11-slim
    WORKDIR /app
    COPY requirements.txt .
    RUN pip install -r requirements.txt
    COPY . .
    CMD ["uvicorn", "src.serve_api:app", "--host", "0.0.0.0", "--port", "8000"]
  • Deploy: locale, VM, o PaaS (Railway/Render/Cloud Run). Esporre endpoint /predict; proteggi con chiave API se pubblico.

🔬 Lab guidato: micro-AI end-to-end

  1. Importa dati (CSV) e fai lo split con stratificazione.
  2. Addestra baseline (testo: CountVectorizer+LR) e salva pesi.
  3. Valida su test e salva report e matrice di confusione (immagine/CSV).
  4. Servi il modello via API FastAPI e prova con curl o Postman.
  5. Interfaccia Streamlit per demo; logga ogni richiesta.
  6. Itera: migliora preprocessing (stopword dominio-specifiche, n-grammi), confronta F1 e aggiorna versione (v1.1.0).

🧭 Design dell’autonomia: validazione & fallback

Evenienza reale: la mini-AI deve “sapere dire non so”. Aggiungi un validatore e un fallback:

  • Soglia di confidenza: se confidence < 0.55 → restituisci “richiedi conferma” o inoltra a regola/operatore.
  • Controlli di sicurezza: blocca input vuoti o troppo lunghi, rimuovi HTML/script.
  • Audit: salva i low-confidence per active learning e migliorare il dataset in seguito.

📈 Miglioramenti successivi (opzionali)

  • Text: TF-IDF, SVM, o DistilBERT (Hugging Face) con fine-tuning.
  • Immagini: CLIP per embedding e nearest neighbor con caption semantiche.
  • Decisioni: meta-policy: regole deterministiche + classificatore + spiegazioni (feature importanti) nel payload.

martedì 17 giugno 2025

Corso sulla Struttura dell’Intelligenza Artificiale: Architetture complesse: dai layer alla logica modulare


Architetture complesse: dai layer alla logica modulare

Perché “architetture complesse”?

Quando i problemi crescono di difficoltà (linguaggio naturale, visione, serie temporali multivariate), non basta una rete “piatta”. Serve costruire modelli componibili, con blocchi riutilizzabili, che separano le responsabilità: estrazione di feature, memorie a lungo raggio, ragionamento sequenziale, generazione. Questo modulo insegna come passare dai singoli layer a moduli più ricchi – e come assemblarli in pipeline robuste.


1) Layer base: mattoni fondamentali

I layer sono le unità minime di calcolo. Conoscerne comportamenti e limiti è cruciale per non “abusare” della profondità o scegliere attivazioni/normalizzazioni inadatte.

  • Dense (fully connected): proiezioni lineari con attivazione non lineare (ReLU, GELU, SiLU). Ottimi come head finali o per integrare feature eterogenee.
  • Convolutional (Conv): estraggono pattern locali con condivisione dei pesi. Varianti utili: depthwise separable, dilated, residual. Nati per immagini, efficaci anche su sequenze 1D.
  • Ricorrenti (LSTM/GRU): gestiscono dipendenze temporali. Le LSTM eccellono su contesti lunghi; le GRU sono più leggere con prestazioni simili.
  • Transformer block: stack di Multi-Head Self-Attention (MHSA) + Feed-Forward Network (FFN), con residual + LayerNorm. Cattura dipendenze lunghe in parallelo.
<!-- Esempio di “blocco” astratto -->
Input → [Normalizzazione] → [Operazione principale] → [Dropout] → (+ Residual) → Output

Nota pratica: Normalizzazione prima del blocco (pre-norm) tende a stabilizzare il training di modelli molto profondi; il residuo riduce il rischio di vanishing gradient.


2) Dalla collezione di layer alla logica modulare

Un’architettura complessa non è solo “più layer”: è composizione. Si definiscono moduli con un’API chiara e testabile, che possono essere riutilizzati in punti diversi della rete.

  • Blocchi ripetibili: es. “ConvBlock(k, s)” con Conv → Norm → Attivazione → Dropout; “TransformerBlock(h, d)” con MHSA → FFN → Residual/Norm.
  • Percorsi paralleli (inception-like): più rami con kernel/attività diverse, poi concatenazione: migliore copertura di scale differenti.
  • Skip/Residual multi-scala: collegamenti tra livelli lontani per preservare dettagli (U-Net in segmentazione, encoder–decoder in NLP).
  • Conditioning: iniezione di segnali esterni (classe/tempo/contesto) nei blocchi tramite concatenazione, gating o attenzione condizionata.
<!-- Pseudocodice di un modulo riutilizzabile -->
def TransformerBlock(x):
x_norm = LayerNorm(x)
x_attn = MultiHeadAttention(x_norm, x_norm)
x = x + Dropout(x_attn) # residual
y_norm = LayerNorm(x)
y_ffn = FFN(y_norm)
y = x + Dropout(y_ffn) # residual
return y

3) Strutture moderne: encoder–decoder, attention, embedding

  • Embedding: mappa token/ID in vettori densi. Fondamentali in NLP; analoghi per categorie in tabellari. Si può includere positional encoding (sinusoidale o learnable) per preservare l’ordine.
  • Attention/MHSA: meccanismo che assegna pesi Query–Key–Value alle relazioni tra elementi. Multi-head = sotto-spazi diversi in parallelo.
  • Encoder–Decoder:
    • Encoder: comprime l’input in rappresentazioni contestualizzate (BERT-like).
    • Decoder: genera output condizionato all’encoder (traduzione, riassunto) o in modo autoregressivo (GPT-like).
    • Cross-attention: il decoder “guarda” l’encoder per ogni passo di generazione.

Scelte progettuali chiave

  • Maschere di attenzione: causale (no “sbirciare” il futuro) per generazione; bidirezionale per comprensione.
  • Label smoothing: regolarizza la classificazione su vocabolari grandi.
  • Ottimizzazione: AdamW + scheduler con warmup lineare spesso accelera la convergenza.

4) Dataset sequenziali e input testuali

Il successo di un’architettura complessa dipende dalla corretta preparazione del dato.

  • Tokenizzazione: BPE/WordPiece alleviano out-of-vocabulary e mantengono compattezza. Conservare special tokens (PAD, BOS, EOS, SEP).
  • Padding & masking: batch di lunghezze uniformi, con maschere per ignorare il padding nell’attenzione e nella loss.
  • Bilanciamento: shuffling, pesi di classe, sampling per evitare bias di frequenza.
  • Serie temporali: finestre scorrevoli, lookback/horizon, normalizzazione per feature (z-score/min-max), gestione di “missing” (imputazione, maschere).
  • Data leakage: attenti a non usare informazioni future in addestramento (split temporale rigoroso).

5) Pattern di addestramento stabili

  • Inizializzazione & attivazioni: He (ReLU/SiLU), Xavier (tanh); evitare saturazioni; LayerNorm/BatchNorm dove appropriato.
  • Regolarizzazione: dropout (attenzione e FFN), weight decay, early stopping, stochastic depth in reti profonde.
  • Gradiente: clip del gradiente su RNN/Transformer (specie con sequenze lunghe); mixed precision per velocità/memoria.
  • Curriculum & teacher forcing: per modelli autoregressivi; scheduled sampling per ridurre esposizione a distribuzioni diverse tra train/test.

6) Valutazione e metriche

  • Classificazione: accuracy, F1 (macro/micro), AUC; matrici di confusione per classi sbilanciate.
  • Generazione testo: perplexity, BLEU/ROUGE/METEOR; analisi qualitativa (allucinazioni, ripetizioni, coerenza).
  • Serie temporali: MAE/MSE/RMSE, MAPE; backtesting a più orizzonti (rolling window).

7) Laboratorio: Progettare un piccolo encoder–decoder per generazione frasi

Obiettivo: costruire un modello che generi frasi di risposta data un’istruzione breve (mini traduzione o dialogo toy).

Dataset suggeriti

  • Tatoeba o coppie frase–frase semplificate (es. “it → en” ridotto) oppure un dataset custom di prompt–risposta (1000–5000 esempi bastano per il prototipo).

Passi operativi

  1. Preprocessing: tokenizzazione subword (BPE/WordPiece), definizione vocabolario, aggiunta di BOS/EOS, padding/truncation; split train/val/test.
  2. Embedding & Positional Encoding: dimensione embed 128–256; posizionale sinusoidale o learnable.
  3. Encoder: 2–4 TransformerBlock con 4–8 teste, FFN 2–4× dimensione embed, dropout 0.1–0.2.
  4. Decoder: 2–4 blocchi con masked self-attention + cross-attention verso l’encoder; tie embeddings opzionale.
  5. Loss & training: cross-entropy con label smoothing 0.1; AdamW (lr 3e−4) + warmup; early stopping via perdita di validazione.
  6. Decoding: greedy per debug; poi beam search (k=3–5) o top-k/top-p per qualità/varietà.
  7. Valutazione: BLEU/ROUGE su test; rassegna qualitativa di buone/cattive generazioni per guidare i miglioramenti.
<!-- Pseudocodice di montaggio (stile Keras/PyTorch-agnostico) -->
src = Input(shape=(T_src,))
tgt = Input(shape=(T_tgt,))
src_emb = TokenEmbedding(V, d)(src) + PositionalEncoding(T_src, d)
tgt_emb = TokenEmbedding(V, d)(tgt) + PositionalEncoding(T_tgt, d)
enc = src_emb
for _ in range(N_enc):
enc = TransformerBlock(d, heads=H, ffn=4*d, dropout=0.1)(enc)
dec = tgt_emb
for _ in range(N_dec):
dec = MaskedSelfAttentionBlock(d, heads=H, dropout=0.1)(dec)
dec = CrossAttentionBlock(d, heads=H, context=enc, dropout=0.1)(dec)
dec = FeedForwardBlock(d, ffn=4*d, dropout=0.1)(dec)
logits = Dense(V)(dec) # head linguistica
model = Model([src, tgt], logits)

Estensioni opzionali: weight tying embedding/output, shared encoder per multi-task, riduzione complessità con local attention per sequenze lunghe.


8) Errori comuni & best practice

  • Maschere mancanti: senza causal mask il decoder “vede il futuro” e impara scorciatoie.
  • Padding non mascherato: il modello impara a “predire” zeri: sempre applicare la mask del padding in attenzione e loss.
  • Learning rate inadeguato: troppo alto → divergenza; usare warmup e scheduler.
  • Overfitting precoce: aumentare dropout/weight decay, usare early stopping, più dati/augment.
  • Leakage temporale: nei dati sequenziali rispettare la cronologia nei split e nelle finestre.

9) Checklist rapida di design

  • Definisci chiaramente input/output e loro natura (immagini, testo, serie).
  • Scegli i moduli (Conv/RNN/Transformer) in base a località vs lunga dipendenza.
  • Applica normalizzazione, residual, dropout in ogni blocco profondo.
  • Stabilisci metriche coerenti con il task (F1/BLEU/MAE) e un protocollo di validazione.
  • Automatizza il training (checkpoint, early stopping, logging) e prova più semi.

lunedì 16 giugno 2025

Corso sulla Struttura dell’Intelligenza Artificiale: Progettare e addestrare un mini-modello


Progettare e addestrare un mini-modello

🎯 Obiettivo del modulo

Comprendere e sperimentare tutte le fasi necessarie per costruire e addestrare un modello di intelligenza artificiale semplice ma completo, utilizzando una rete neurale di tipo MLP (Multi-Layer Perceptron). Il modulo guida passo dopo passo nella realizzazione di un mini-engine per il training, includendo anche tecniche di miglioramento delle prestazioni come la normalizzazione, il dropout e l’early stopping. L’attività pratica culmina nell’allenamento di una mini-AI su dataset personalizzati.


📌 Contenuti dettagliati

🔧 Architettura MLP (Multi-Layer Perceptron)
  • Cos’è un MLP e perché è utile per problemi di classificazione e regressione.
  • Struttura base: input layer, hidden layer(s), output layer.
  • Attivazioni (ReLU, sigmoid, softmax) e funzione di output in base al compito.
  • Numero di neuroni e strati: come sceglierli e con quali criteri.
⚙️ Costruzione dell’engine di training
  • Forward pass: calcolo dell’output predetto dato l’input.
  • Loss function: scelta della funzione di perdita (MSE, cross-entropy) in base al tipo di compito.
  • Backward pass: calcolo dei gradienti tramite retropropagazione.
  • Ottimizzazione: aggiornamento dei pesi con gradient descent, SGD o Adam.
🧪 Tecniche per migliorare l’addestramento
  • Normalizzazione: scaling degli input (es. MinMax, Z-score) per velocizzare la convergenza.
  • Dropout: disattivazione casuale di neuroni durante il training per evitare overfitting.
  • Early stopping: interruzione automatica dell’addestramento quando non migliora più la validazione.
📊 Metriche e validazione
  • Accuracy, precision, recall, F1-score: come misurarle e quando usarle.
  • Divisione in training/validation/test set.
  • Visualizzazione delle curve di loss e accuratezza.

🧪 Laboratorio pratico – Allenare una mini-AI

Obiettivo: Costruire e addestrare una rete neurale MLP da zero (senza usare librerie avanzate come TensorFlow o PyTorch) su un dataset a scelta.

Dataset consigliati:

  • Classificazione emoji: data una parola o frase, predire l'emoji più coerente.
  • MNIST-like (cifre disegnate): classificazione di immagini semplici.
  • Sentiment Analysis: valutare se un testo è positivo o negativo.

Fasi del laboratorio:

  1. Definizione del dataset personalizzato.
  2. Preprocessing dei dati e normalizzazione.
  3. Costruzione della rete MLP in Python o pseudocodice.
  4. Definizione delle funzioni di forward, loss e backward.
  5. Implementazione dell’ottimizzazione (SGD o Adam).
  6. Aggiunta di dropout e early stopping.
  7. Addestramento e monitoraggio della rete.
  8. Valutazione delle prestazioni e visualizzazione dei risultati.

🧠 Competenze acquisite

  • Progettare una rete neurale MLP funzionale da zero.
  • Comprendere a fondo il processo di addestramento e ottimizzazione.
  • Saper applicare tecniche di regolarizzazione e metriche di validazione.
  • Allenare un modello su dati reali e interpretarne le performance.

domenica 15 giugno 2025

Corso sulla Struttura dell’Intelligenza Artificiale: Mattoni matematici e computazionali


Mattoni matematici e computazionali

Destinatari: studenti universitari, autodidatti in AI, data scientist junior, insegnanti STEM
Prerequisiti: conoscenze base di algebra lineare, derivate, Python


🎯 Obiettivi del modulo

  • Comprendere le basi matematiche e computazionali che sottendono il funzionamento di una rete neurale.
  • Familiarizzare con vettori, matrici e tensori come strutture fondamentali nella rappresentazione dei dati e dei modelli.
  • Introdurre i concetti di calcolo differenziale automatico (autodiff) e computational graph.
  • Acquisire i primi strumenti pratici per lavorare con librerie come NumPy e PyTorch.
  • Costruire da zero una rete neurale semplice con forward pass e backpropagation.

🧱 Contenuti


1. 📐 Vettori, matrici e tensori: come ragiona il modello

  • Le reti neurali trattano input numerici come vettori (1D), matrici (2D) o tensori (nD).
  • Ogni livello di una rete effettua operazioni matriciali: moltiplicazioni, somme, funzioni di attivazione.
  • Il tensore è l’unità fondamentale: ad esempio, un batch di immagini RGB è un tensore 4D (batch, altezza, larghezza, canali).

📌 Esempio pratico:

  • Un input , un layer , output

✅ Competenze attese: interpretare il significato geometrico e computazionale di una rete come sequenza di trasformazioni lineari + non linearità.


2. 🔁 Differenziazione automatica e backpropagation

  • La funzione obiettivo (loss function) misura quanto il modello sbaglia: ad esempio MSE, cross-entropy.
  • Il calcolo del gradiente serve a capire come modificare i pesi per ridurre la loss.
  • Backpropagation sfrutta la regola della catena per aggiornare ogni peso in funzione del gradiente della loss rispetto a quel peso.

🔬 Differenziazione automatica:

  • Metodo che permette di calcolare derivate esatte senza scriverle manualmente.
  • Le librerie moderne (es. PyTorch) costruiscono un computational graph e poi lo attraversano all’indietro per calcolare i gradienti (reverse-mode autodiff).

📌 Concetto chiave: l’ottimizzazione nei modelli neurali è possibile solo grazie alla propagazione del gradiente lungo il grafo computazionale.


3. 🧠 Struttura dei dati nei modelli neurali

  • I dati (immagini, testo, suono) devono essere numerizzati e organizzati in tensori.
  • Input → hidden layers → output: ogni livello produce una trasformazione.
  • I pesi sono rappresentati come matrici/tensori e memorizzati come parametri addestrabili.
  • Le architetture più complesse (CNN, RNN, Transformer) si costruiscono su questi elementi base.

📌 Focus: ciò che cambia è l’organizzazione e la connettività, ma le operazioni sono sempre su tensori.


4. ⚙️ Introduzione a NumPy e PyTorch

✅ NumPy:

  • Libreria fondamentale per calcolo scientifico in Python.
  • Operazioni su array, broadcasting, algebra lineare.

✅ PyTorch:

  • Costruito su tensori simili a NumPy ma con autodiff e GPU support.
  • Ogni Tensor tiene traccia della sua storia computazionale se requires_grad=True.
  • torch.autograd permette di eseguire backprop automaticamente.

📌 Esempio:

import torch

x = torch.tensor([1.0, 2.0], requires_grad=True)
y = x ** 2 + 3 * x
z = y.sum()
z.backward()

print(x.grad)  # output: gradiente di z rispetto a x

🧠 Computational Graph

  • Ogni operazione crea un nodo nel grafo.
  • PyTorch costruisce il grafo in tempo reale ("define-by-run").

🧪 LAB: Implementare una rete neurale semplice da zero

Obiettivo: costruire un modello con:

  • 1 layer input
  • 1 layer hidden (ReLU)
  • 1 output (softmax o lineare)

Attività step-by-step:

  1. Inizializzazione pesi e bias con NumPy
  2. Forward pass: calcolo output
  3. Loss function: MSE o Cross-Entropy
  4. Backpropagation manuale: calcolo derivata, aggiornamento parametri
  5. Addestramento su un dataset semplice (es. XOR, AND, o dataset sintetico)
  6. Plot della loss nel tempo

📌 Sfida bonus: reimplementare la stessa rete usando PyTorch e confrontare risultati, performance e semplicità del codice.


📎 Materiali forniti

  • Slide PDF con tutti i concetti e formule
  • Foglio guida per il LAB (istruzioni + codice base)
  • Notebook Colab con versione PyTorch + visualizzazione computational graph
  • Dataset di test (XOR, MNIST semplificato)

🧩 Conclusione

I tensori sono i mattoni del ragionamento computazionale, le derivate sono la spinta dell’apprendimento, e librerie come PyTorch sono i mezzi con cui possiamo esplorare e costruire reti neurali. In questo modulo lo studente passa da concetti astratti a realizzazione pratica, unendo teoria matematica, logica computazionale e coding efficace.


🧾 Vuoi che converta il modulo in:

  • Codice HTML per Blogger
  • Scheda didattica PDF/Word
  • Notebook Jupyter (Colab ready)

Fammi sapere, posso fornirti tutto il materiale pronto all’uso.

sabato 14 giugno 2025

Corso sulla Struttura dell’Intelligenza Artificiale: Anatomia di un sistema di Intelligenza Artificiale


Anatomia di un Sistema di Intelligenza Artificiale

🤖 Cos’è una AI: struttura e livelli di astrazione

Un sistema di Intelligenza Artificiale è un insieme coordinato di componenti software e hardware progettati per replicare – in forma limitata – capacità cognitive umane, come percepire, apprendere, decidere e generare.

Livelli di astrazione:

  • ⚙️ Livello tecnico: algoritmi, reti neurali, modelli
  • 🧠 Livello concettuale: conoscenza, ragionamento, linguaggio
  • 🧩 Livello sistemico: interazione tra moduli e ambienti

🔄 Pipeline tipica di un sistema AI

  1. Data Preprocessing – pulizia, formattazione, normalizzazione dei dati
  2. Training del modello – apprendimento supervisionato o non supervisionato
  3. Inferenza – utilizzo del modello per fare previsioni su nuovi dati
  4. Valutazione – metrica di performance: accuracy, precision, recall, F1

🧩 Moduli software in un sistema AI

  • 📥 Data Ingestion – raccoglie dati da fonti eterogenee (API, CSV, sensori)
  • 🧪 Training Engine – gestisce il modello e l’addestramento
  • 📤 Inference Engine – risponde a nuove richieste in tempo reale
  • 🖥️ Interfaccia – dashboard, API REST, chatbot o visualizzazioni

📊 Dataset, obiettivi e task AI

Dataset: raccolte strutturate (es. immagini, testi, dati tabellari) che alimentano l’addestramento.

Obiettivi: prevedere, generare, riconoscere, classificare.

Task tipici:

  • 📈 Classificazione – riconoscere una categoria (es. spam vs non-spam)
  • 📉 Regressione – prevedere un valore numerico (es. prezzi immobiliari)
  • 📝 Generazione – creare nuovi contenuti (es. testo, immagini, codice)
  • 🧬 Segmentazione – identificare sezioni nei dati (es. in un’immagine medica)

🧪 LAB – Caso d’uso: mappare un sistema AI reale

Obiettivo: analizzare un'applicazione AI e scomporla in blocchi funzionali.

Esempio: sistema di riconoscimento facciale

  • 📸 Input: immagine da webcam o archivio
  • 🧹 Preprocessing: ridimensionamento, conversione in scala di grigi
  • 🧠 Modello: CNN addestrata su dataset di volti (es. LFW)
  • 📤 Output: ID utente o tag associato
  • 📈 Valutazione: accuratezza > 90%, FPR < 5%

Compito: scegli un'app AI (es. traduttore automatico, filtro antispam) e costruisci la sua mappa funzionale in 5 blocchi.

📘 Conclusione

Comprendere l’architettura e la pipeline di un sistema AI è il primo passo per progettare soluzioni efficaci, trasparenti e scalabili. Il prossimo modulo ti porterà nel cuore della progettazione dei modelli neurali.


giovedì 5 giugno 2025

Corso di Reti Neurali per il Machine Learning: Verso le architetture Transformer


Verso le architetture Transformer

Le architetture Transformer hanno rivoluzionato il campo dell’intelligenza artificiale, in particolare l’elaborazione del linguaggio naturale (NLP), ma anche la visione artificiale e la multimodalità. La loro forza risiede nella capacità di catturare relazioni a lungo raggio in sequenze di dati, superando i limiti delle reti ricorrenti (RNN, LSTM, GRU) e delle convoluzionali (CNN) in compiti linguistici e sequenziali.

1. Meccanismo di attenzione

  • Self-Attention: ogni parola di una frase “guarda” tutte le altre parole, attribuendo un peso (attenzione) diverso a seconda della loro rilevanza. Questo permette al modello di gestire contesti lunghi senza degradazione di memoria come accadeva nelle RNN.

  • Multi-Head Attention: più “teste” di attenzione lavorano in parallelo, ognuna catturando relazioni semantiche diverse (per esempio, una testa può cogliere concordanze grammaticali, un’altra la semantica tra soggetto e verbo).

  • Scalabilità: il calcolo dell’attenzione può essere parallelo, aumentando drasticamente la velocità di addestramento rispetto alle RNN.

2. Architettura Transformer

  • Encoder: riceve la sequenza in input, la rappresenta attraverso embedding e positional encoding, e applica blocchi di attenzione e feed-forward per produrre rappresentazioni contestualizzate.

  • Decoder: prende in input le rappresentazioni dell’encoder e le usa per generare sequenze in uscita (utile per traduzione automatica, generazione di testo, ecc.).

  • Positional Encoding: poiché il Transformer non è sequenziale, ha bisogno di un meccanismo che codifichi la posizione relativa degli elementi. Si usano quindi funzioni sinusoidali o embedding appositi che preservano l’informazione sulla sequenza.

3. Foundation Models: BERT, GPT, T5

  • BERT (Bidirectional Encoder Representations from Transformers): utilizza solo l’encoder. È ottimale per compiti di classificazione, sentiment analysis, named entity recognition (NER).

  • GPT (Generative Pretrained Transformer): basato sul decoder, è pensato per la generazione di sequenze testuali (chatbot, scrittura assistita).

  • T5 (Text-to-Text Transfer Transformer): trasforma ogni problema di NLP in un task di “traduzione” testuale, rendendo il modello molto flessibile per compiti eterogenei.

4. Fine-Tuning e Hugging Face

  • Approccio transfer learning: i Transformer vengono pre-addestrati su enormi dataset generici, e poi riadattati (fine-tuning) su dataset specifici con meno dati e costi computazionali ridotti.

  • Hugging Face Transformers: libreria open-source che mette a disposizione centinaia di modelli pre-addestrati, con interfacce semplici per il fine-tuning e l’integrazione in pipeline di NLP.

  • Esempi pratici:

    • Classificazione di recensioni positive/negative.

    • Riconoscimento di entità (NER).

    • Generazione di testo creativo o riassunti automatici.

5. Laboratorio pratico

Lab: Classificazione testuale con DistilBERT e fine-tuning su dataset custom

  • Introduzione a DistilBERT (versione leggera e veloce di BERT, con prestazioni simili ma minor costo computazionale).

  • Pipeline di Hugging Face per la classificazione del testo.

  • Preparazione di un dataset custom (es. recensioni di prodotti).

  • Addestramento e validazione del modello con valutazione delle metriche (accuracy, F1-score).

  • Test del modello su nuovi testi, interpretazione dei risultati.


mercoledì 4 giugno 2025

Corso di Reti Neurali per il Machine Learning: Reti ricorrenti e sequenziali (RNN, LSTM, GRU)


Reti ricorrenti e sequenziali (RNN, LSTM, GRU)

1. Modelli per dati sequenziali

Le reti ricorrenti sono progettate per gestire dati che hanno un ordine o una sequenza temporale:

  • Serie temporali: previsioni su dati che cambiano nel tempo (es. mercato finanziario, sensori)
  • Testi e linguaggio: elaborazione di frasi, traduzione automatica, analisi del sentiment

2. Problemi e architetture avanzate

Reti RNN tradizionali soffrono del problema del vanishing gradient, che rende difficile apprendere dipendenze a lungo termine. Soluzioni:

  • LSTM: Long Short-Term Memory, gestisce efficacemente dipendenze lunghe
  • GRU: Gated Recurrent Unit, versione semplificata ed efficiente di LSTM

3. Applicazioni in NLP

  • Traduzione automatica: convertire testi da una lingua all’altra
  • Analisi del sentiment: capire emozioni e opinioni nei testi
  • Previsione di sequenze: completamento automatico di frasi o serie temporali

4. Introduzione alle attention mechanism

Le attention mechanism permettono al modello di concentrarsi su parti rilevanti della sequenza, migliorando performance in traduzione, riassunto automatico e NLP avanzato.

5. Lab pratico

  • Previsione di testo su dataset di esempio
  • Sentiment analysis su recensioni o commenti
  • Osservazione dell’impatto di LSTM e GRU sulle prestazioni rispetto a RNN classiche


martedì 3 giugno 2025

Corso di Reti Neurali per il Machine Learning: Reti neurali convoluzionali (CNN)


Reti neurali convoluzionali (CNN)

1. Visione artificiale e architetture CNN

Le CNN sono alla base della visione artificiale, permettendo al modello di “vedere” e interpretare immagini. Concetti chiave:

  • Convoluzione: filtri che estraggono caratteristiche locali dall’immagine
  • Pooling: riduce le dimensioni mantenendo le informazioni principali (max pooling, average pooling)
  • Architetture famose: LeNet, VGG, ResNet

2. Interpretazione e visualizzazione dei filtri

Visualizzare i filtri e le mappe di attivazione aiuta a capire cosa impara la rete: - Individuare pattern e feature rilevanti - Diagnostica del modello in caso di errori

3. Compiti principali delle CNN

  • Classificazione: assegnare etichette a intere immagini
  • Segmentazione: identificare ogni pixel con la sua categoria
  • Object Detection: localizzare oggetti e classificarli all’interno dell’immagine

4. Lab pratico

Applicazione concreta:

  • Riconoscimento di immagini su dataset MNIST
  • Personalizzazione di una rete ResNet per compiti specifici
  • Osservazione di come cambiano le performance modificando i layer e i filtri


lunedì 2 giugno 2025

Corso di Reti Neurali per il Machine Learning: Tecniche di miglioramento e regolarizzazione


Tecniche di miglioramento e regolarizzazione



1. Normalizzazione

Per rendere l’addestramento più stabile e veloce, si utilizzano tecniche di normalizzazione:

  • Batch Norm: normalizza i valori di ciascun batch per evitare saturazioni nei neuroni
  • Layer Norm: normalizza lungo le feature di ciascun layer, utile in RNN e Transformers


2. Tecniche di regolarizzazione

Servono a prevenire l’overfitting, cioè quando il modello impara troppo bene i dati di training ma fallisce sui dati nuovi:

  • Dropout: disattiva casualmente neuroni durante l’addestramento
  • Weight Decay: penalizza pesi troppo grandi per mantenere il modello semplice
  • Data Augmentation: modifica i dati di input (rotazioni, traslazioni, rumore) per rendere il modello più robusto


3. Fine-tuning e Transfer Learning

Si parte da un modello già addestrato su un dataset grande e generale, e lo si adatta a un compito specifico. - Riduce i tempi di addestramento - Migliora le prestazioni su dataset piccoli o specifici


4. Hyperparameter Tuning

I parametri come learning rate, numero di layer o dimensione dei batch influiscono molto sulle prestazioni. Alcuni approcci per trovarli:

  • Grid Search: prova sistematicamente tutte le combinazioni possibili
  • Random Search: campiona casualmente nello spazio dei parametri
  • Optuna: libreria avanzata per ottimizzazione automatizzata degli iperparametri


5. Lab pratico

Applicazione concreta: migliorare l’accuratezza di una CNN su CIFAR-10 utilizzando dropout e batch normalization. - Osservare come cambia la convergenza del modello - Valutare l’impatto sulla performance finale


Questo modulo fornisce gli strumenti per ottimizzare le reti neurali e aumentare la loro capacità di generalizzare a nuovi dati, riducendo errori e migliorando l’affidabilità del modello.

domenica 1 giugno 2025

Corso di Reti Neurali per il Machine Learning: Meccanismi di apprendimento




Meccanismi di apprendimento

 Contenuti del modulo

1. 🧠 Apprendimento supervisionato e funzione obiettivo

L’apprendimento supervisionato consiste nell’addestrare un modello utilizzando dati etichettati, cioè coppie input-output noti. Il modello cerca di imparare una funzione .

📌 Funzione di perdita (loss function):
Misura quanto è sbagliata la previsione del modello rispetto all’output reale. Alcuni esempi:

  • MSE (Mean Squared Error) per regressione
  • Cross-Entropy per classificazione
  • Hinge loss per SVM

🧮 L’obiettivo dell’addestramento è minimizzare la funzione di perdita su tutti i dati del training set.

2. 🔄 Backpropagation: il cuore dell’apprendimento

L’algoritmo di backpropagation è il metodo con cui una rete neurale aggiorna i suoi pesi. Si compone di due fasi:

  • Forward pass: calcolo dell’output e della loss
  • Backward pass: calcolo del gradiente della loss rispetto a ogni peso usando la regola della catena

🧠 È un'applicazione diretta del calcolo differenziale e del teorema del gradiente: ogni peso viene aggiornato secondo la formula


w := w - \eta \cdot \frac{\partial \text{Loss}}{\partial w}

dove è il learning rate.

3. 📉 Ottimizzazione con Gradient Descent e varianti

Per aggiornare i pesi, si usa il Gradient Descent, con l’obiettivo di scendere nella valle della funzione di errore fino al minimo.

⚙️ Varianti:

  • SGD (Stochastic Gradient Descent): aggiorna i pesi a ogni esempio → più veloce ma rumoroso
  • Mini-Batch Gradient Descent: compromesso tra stabilità e rapidità
  • Adam (Adaptive Moment Estimation): combina momentum e adattività → molto usato
  • RMSProp: divide il gradiente per una media quadratica → utile in problemi con rumore o plateaux

🧪 Ogni variante modifica come e quanto ogni peso viene aggiornato.

4. ⚠️ Overfitting, Underfitting e Early Stopping

📉 Overfitting: il modello impara troppo bene i dati di training, ma non generalizza → curva di validazione peggiora

📈 Underfitting: il modello è troppo semplice o addestrato male → non impara neanche il training set

🔁 Early stopping: tecnica che interrompe l’addestramento quando la loss di validazione smette di migliorare → evita overfitting

🎯 Altre strategie:

  • Regularizzazione (L1, L2)
  • Dropout
  • Cross-validation
  • Aumento dei dati (data augmentation)

🔬 LAB: Visualizzazione del processo di apprendimento con TensorBoard

🧑‍💻 Obiettivo: osservare in tempo reale il processo di apprendimento di una rete semplice (es. classificazione MNIST o XOR)

✅ Attività:

  1. Creazione di una rete neurale semplice in TensorFlow/Keras
  2. Logging della loss e dell’accuratezza a ogni epoca con:
tensorboard_callback = tf.keras.callbacks.TensorBoard(log_dir="./logs")
  1. Avvio di TensorBoard con:
tensorboard --logdir=./logs
  1. Visualizzazione dinamica delle curve di loss e accuracy su training e validation

🎯 Osservare:

  • Inizio e fine del training
  • Convergenza della loss
  • Differenza tra loss training e validation → overfitting?

📎 Materiali di supporto

  • Dispensa con formule e schemi visivi
  • Notebook Jupyter precompilato (colab friendly)
  • Scheda di sintesi degli algoritmi (SGD vs Adam vs RMSProp)
  • Link per approfondimento su TensorBoard e diagnostica visuale

📌 Conclusione

Capire i meccanismi di apprendimento equivale a leggere nella mente dell’IA. In questo modulo, l’approccio non è solo tecnico, ma anche visivo e sperimentale: imparare a controllare ciò che la rete apprende è il primo passo per usarla in modo responsabile ed efficace.


Corso Fondamenti di Informatica e Reti: 4 Architettura del computer

  ARCHITETTURA DEL COMPUTER come funziona davvero una macchina Capire un computer non significa solo saperlo accendere o aprire file: die...