Perché il mio modello TensorFlow non impara e la loss è bloccata?

👤 Iniziato da @zitaferrari3
📅 02/08/2025 15:01
📁 Intelligenza Artificiale 🌐 IT
Avatar di zitaferrari3
Ciao a tutti! Sono alle prese con il mio primo progetto di image classification usando TensorFlow 2.9 su Python 3.10 e sono un po' bloccata. Ho creato una CNN semplice per riconoscere cifre scritte a mano sul dataset MNIST, ma dopo 10 epoche la loss si blocca a 2.3 e l'accuracy non supera il 10%! Ho già provato a: cambiare learning rate (da 0.1 a 0.0001), sostituire l'ottimizzatore (SGD, Adam) e aggiungere dropout. Niente sembra funzionare :( Ecco il codice della definizione del modello:

```python
model = tf.keras.Sequential([
tf.keras.layers.Conv2D(32, (3,3), activation='relu', input_shape=(28,28,1)),
tf.keras.layers.MaxPooling2D((2,2)),
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(10, activation='softmax')
])

model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
```
L'output durante il training mostra sempre "loss: 2.302 - accuracy: 0.1135" senza miglioramenti. Qualcuno ha affrontato un problema simile? Mi date una mano a trovare dove sbaglio? Sono comunque entusiasta di imparare dai vostri consigli! 🌟
Avatar di elliotgreco73
Ciao @zitaferrari3, il tuo problema è interessante e comune a molti che iniziano con TensorFlow. Innanzitutto, complimenti per aver già provato diverse ottimizzazioni e modifiche al modello. Tuttavia, il tuo modello sembra troppo semplice per il dataset MNIST. Prova ad aggiungere più layer convoluzionali e fully connected per aumentare la capacità del modello. Inoltre, assicurati di normalizzare i dati di input dividendo per 255 per avere valori tra 0 e 1. Questo potrebbe già fare una grande differenza. Un altro consiglio è di aumentare il numero di epoche e monitorare attentamente l'overfitting. Tieni duro, sei sulla strada giusta!
Avatar di maurolongo83
Il tuo modello è troppo semplice per apprendere. Hai solo un Conv2D e un MaxPooling, poi vai subito in Flatten e butti direttamente su 10 neuroni. Qui manca un **Dense intermedio con almeno 128-256 unità** per fare feature extraction decente. Esempio: dopo Flatten aggiungi un Dense(128, 'relu') con Dropout(0.5), poi il softmax. Senza questo, i pesi non riescono a combinare le features estratte.

Poi controlla se hai normalizzato i dati: MNIST è 0-255, ma devi dividere per 255 per portarlo a [0,1], altrimenti i gradienti impazziscono. Infine: **10 epoche sono poche**, prova almeno 20-30 con un batch_size di 64. Se la loss resta inchiodata, stampa una preview dei primi batch per verificare che i dati non siano rotti (magari hai invertito input e label). Fidati, è quasi sempre un problema di preprocessing o architettura, non di ottimizzatore.
Avatar di ologentile69
Ciao Zita, capisco la frustrazione! Quel valore di loss bloccato a 2.302 è un classico sintomo di modello che non apprende, e il problema principale è la struttura troppo semplificata. Concordando con @maurolongo83, il salto diretto da Flatten a Dense(10) è critico: non hai strati intermedi per elaborare le feature estratte dalle convoluzionali.

Modifica così: dopo il Flatten, inserisci un Dense(128, activation='relu') o anche 256 unità, e solo poi l'output. Questo dà capacità combinatoria ai pesi. Contemporaneamente, verifica la normalizzazione dei dati: se non dividi i pixel per 255, i gradienti esplodono. Esempio rapido:

```python
# Aggiungi questo Dense e normalizza gli input
model = tf.keras.Sequential([
tf.keras.layers.Rescaling(1./255), # fondamentale!
tf.keras.layers.Conv2D(32, (3,3), activation='relu', input_shape=(28,28,1)),
tf.keras.layers.MaxPooling2D((2,2)),
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(128, activation='relu'), # strato mancante
tf.keras.layers.Dense(10, activation='softmax')
])
```

10 epoche sono poche per MNIST, ma senza queste correzioni, anche 100 saranno inutili. Prova e aggiornaci, sono curioso di sapere se risolvi! 💪
Avatar di beltramomartini49
Aggiungo un punto fondamentale che nessuno ha ancora menzionato: controlla che le tue label siano codificate correttamente! Ho visto troppi casi dove il problema era semplicemente che le label partivano da 1 invece che da 0, mandando in tilt la softmax.

Per la struttura del modello, ti straconsiglio di inserire almeno un altro blocco conv+pooling prima del flatten. Tipo così:
```python
tf.keras.layers.Conv2D(64, (3,3), activation='relu'),
tf.keras.layers.MaxPooling2D((2,2)),
```
E assolutamente DENSE intermedio come dicono gli altri, ma occhio a non esagerare con le unità per MNIST che è un dataset semplice. 128 va più che bene.

Ultima cosa: se dopo questi cambiamenti ancora non va, fai un sanity check estremo - prova a overfittare volontariamente su pochissimi esempi (tipo 10 immagini). Se nemmeno così la loss scende, hai un problema più profondo nel tuo setup.

PS: quell'accuracy del 10% è sospetta, sembra proprio che il modello stia facendo random guessing. Sicura di non aver mischiato train e test set?
Avatar di zitaferrari3
@beltramomartini49, grazie mille per questi spunti preziosissimi! La questione delle label mi ha fatto accapponare la pelle 😱 Ora corro a verificare: probabilmente ho dato per scontato l'encoding ma controllerò con `print(y_train[0:5])` per sicurezza.

Apprezzo tantissimo i suggerimenti architetturali! Proverò subito ad aggiungere il blocco conv+pooling extra e ridurrò le unità dense a 128 come dici. Il sanity check su 10 esempi è un'idea geniale che non avevo considerato!

E no, per fortuna train e test set sono separati correttamente (ho usato `train_test_split` con random_state), ma quell'accuracy al 10% è davvero sospetta... Mi hai dato tantissimo materiale per testare, aggiorno appena ho novelle! 💪
Avatar di augustaserra
@zitaferrari3, figurati, sono contenta che i consigli ti siano stati utili! La storia delle label mi fa venire in mente quando ho passato ore a debuggare un codice per poi scoprire che c'era un errore di battitura... Capisco perfettamente l'ansia!

L'idea del sanity check è un po' come leggere le prime pagine di un libro per capire se ti piacerà: se non funziona su pochi esempi, inutile andare avanti. E quell'accuracy al 10% è davvero un campanello d'allarme, hai ragione. Ricorda, se il modello "azzecca" solo il 10% significa che sta facendo peggio di un lancio di dadi! 🎲

Ah, e se ti piacciono i libri, ti consiglio "Neuromancer" di William Gibson. Forse ti darà qualche ispirazione (o almeno ti farà viaggiare con la fantasia!). Facci sapere come va! ✨

La Tua Risposta

💬

Vuoi partecipare alla discussione?

Accedi o registrati per scrivere la tua risposta e unirti alla conversazione!