Surajustement du réseau neuronal convolutif. Le décrochage n'aide pas


16

Je joue un peu avec des convnets. Plus précisément, j'utilise l'ensemble de données kaggle cats-vs-dogs qui consiste en 25000 images étiquetées comme chat ou chien (12500 chacune).

J'ai réussi à atteindre une précision de classification d'environ 85% sur mon test, mais je me suis fixé comme objectif d'atteindre une précision de 90%.

Mon problème principal est le sur-ajustement. D'une manière ou d'une autre, cela finit toujours par se produire (normalement après l'époque 8-10). L'architecture de mon réseau est vaguement inspirée du VGG-16, plus précisément mes images sont redimensionnées en , puis je lance:128X128X3

Convolution 1 128x128x32 (kernel size is 3, strides is 1)
Convolution 2 128x128x32 (kernel size is 3, strides is 1)
Max pool    1 64x64x32   (kernel size is 2, strides is 2)
Convolution 3 64x64x64   (kernel size is 3, strides is 1)
Convolution 4 64x64x64   (kernel size is 3, strides is 1)
Max pool    2 32x32x64   (kernel size is 2, strides is 2)
Convolution 5 16x16x128  (kernel size is 3, strides is 1)
Convolution 6 16x16x128  (kernel size is 3, strides is 1)
Max pool    3 8x8x128    (kernel size is 2, strides is 2)
Convolution 7 8x8x256    (kernel size is 3, strides is 1)
Max pool    4 4x4x256    (kernel size is 2, strides is 2)
Convolution 8 4x4x512    (kernel size is 3, strides is 1)
Fully connected layer 1024 (dropout 0.5)
Fully connected layer 1024 (dropout 0.5)

Toutes les couches sauf la dernière ont des relus comme fonctions d'activation.

Notez que j'ai essayé différentes combinaisons de convolutions (j'ai commencé avec des convolutions plus simples).

De plus, j'ai augmenté l'ensemble de données en reflétant les images, de sorte qu'au total, j'ai 50000 images.

De plus, je normalise les images en utilisant la normalisation min max, où X est l'image

X=X-0/255-0

Le code est écrit en tensorflow et les tailles de lot sont 128.

Les mini-lots de données d'entraînement finissent par sur-ajuster et ont une précision de 100% tandis que les données de validation semblent cesser d'apprendre à environ 84-85%.

J'ai également essayé d'augmenter / diminuer le taux d'abandon.

L'optimiseur utilisé est AdamOptimizer avec un taux d'apprentissage de 0,0001

En ce moment, je joue avec ce problème depuis 3 semaines et 85% semblent avoir placé une barrière devant moi.

Pour mémoire, je sais que je pourrais utiliser l'apprentissage par transfert pour obtenir des résultats beaucoup plus élevés, mais je suis intéressé à construire ce réseau comme une expérience d'auto-apprentissage.

Mise à jour:

J'exécute le même réseau avec une taille de lot différente, dans ce cas, j'utilise une taille de lot beaucoup plus petite (16 au lieu de 128) jusqu'à présent, j'atteins une précision de 87,5% (au lieu de 85%). Cela dit, le réseau finit par sur-équiper de toute façon. Je ne comprends toujours pas comment un décrochage de 50% des unités n'aide pas ... évidemment, je fais quelque chose de mal ici. Des idées?

Mise à jour 2:

Il semble que le problème soit lié à la taille du lot, car avec une taille plus petite (16 au lieu de 128), j'atteins maintenant une précision de 92,8% sur mon jeu de test, avec la taille de lot plus petite, le réseau est toujours sur-adapté (les mini-lots finissent avec une précision de 100%) cependant, la perte (erreur) continue de diminuer et elle est en général plus stable. Les inconvénients sont un temps de fonctionnement BEAUCOUP plus lent, mais cela vaut vraiment la peine d'attendre.


2
Pourriez-vous donner plus de détails sur votre évaluation du sur-ajustement? Par exemple, la précision de validation chute-t-elle à un moment donné, parallèlement à la divergence des résultats de la formation et de la validation? Et la fonction de perte?
Neil Slater

Bonne question, donc par surapprentissage, je veux dire le fait que les mini-lots en train atteignent une précision de 100% et des pertes de 0,08 tandis que la validation ne semble jamais descendre en dessous de 0,35 et sa précision reste maintenant à 88%. Selon la validation, il ne semble pas chuter (du moins pas trop), semble devenir plat, mais comment se fait-il que le mini-lot ait une perte aussi faible alors que la validation en est encore loin?
Juan Antonio Gomez Moriano

Je ne connais pas de réponse pour vous, cependant ce comportement - grande divergence entre le train et la validation, mais toujours la validation par plateau OK - est quelque chose que j'ai vu auparavant à quelques reprises. J'hésite presque à l'appeler trop ajusté car parfois les résultats des tests sont acceptables.
Neil Slater

"Je ne comprends toujours pas comment un décrochage de 50% des unités n'aide pas". J'ai vu des gens utiliser avec succès des valeurs de décrochage beaucoup plus élevées.
Ricardo Cruz

Réponses:


14

Ok, donc après beaucoup d'expérimentation, j'ai réussi à obtenir des résultats / idées.

En premier lieu, toutes choses étant égales par ailleurs, des lots plus petits dans l'ensemble de formation aident beaucoup à augmenter les performances générales du réseau, car, côté négatif, le processus de formation est beaucoup plus lent.

Deuxième point, les données sont importantes, rien de nouveau ici mais comme j'ai appris en luttant contre ce problème, plus de données semblent toujours aider un peu.

Troisième point, le décrochage est utile dans les grands réseaux avec beaucoup de données et de nombreuses itérations, dans mon réseau, j'ai appliqué le décrochage sur les couches finales entièrement connectées uniquement, les couches de convolution n'ont pas appliqué le décrochage.

Quatrième point (et c'est quelque chose que j'apprends encore et encore): les réseaux neuronaux prennent beaucoup de temps pour s'entraîner, même sur de bons GPU (j'ai formé ce réseau sur floydhub, qui utilise des cartes NVIDIA assez chères), donc la PATIENCE est la clé .

Conclusion finale: La taille des lots est plus importante que l'on pourrait penser, apparemment il est plus facile d'atteindre un minimum local lorsque les lots sont plus grands.

Le code que j'ai écrit est disponible sous forme de cahier python, je pense qu'il est décemment documenté

https://github.com/moriano/loco-learning/blob/master/cats-vs-dogs/cats-vs-dogs.ipynb


Merci d'avoir publié vos résultats. Question rapide: Je suis confronté à un problème similaire et j'ai vu cela dans le bloc - notes que vous avez posté: NOTE USE EITHER mean centering or min-max, NOT BOTH. Je divise actuellement mes images d'entrée par 255 à l'intérieur de mon input_fn(API Tensorflow Estimator). Ensuite, à l'intérieur du modèle, j'exécute cette entrée via la norme de lot. Dois-je encore faire une seule de ces normalisations? Voir github.com/formigone/tf-imagenet/blob/master/models/…
-silveira

Ma compréhension est que la division par 255 n'est effectuée qu'une seule fois pour chaque image, et la raison est de garder toutes les valeurs entre 0 et 1 car cela fournira une stabilité numérique.
Juan Antonio Gomez Moriano

Bien sûr, je comprends. Mais pensez-vous qu'il est logique de normaliser également par lots ces valeurs dans la plage [0, 1]?
rodrigo-silveira

Ça, je ne sais pas, ça fait un moment que je n'ai pas utilisé la normalisation par lots :)
Juan Antonio Gomez Moriano

3

Je vous suggère d'analyser les tracés d'apprentissage de votre précision de validation comme l'a suggéré Neil Slater. Ensuite, si la précision de la validation diminue, essayez de réduire la taille de votre réseau (semble trop profond), ajoutez un décrochage aux couches CONV et BatchNormalization après chaque couche. Il peut aider à éliminer le sur-ajustement et à augmenter la précision du test.


Merci pour le conseil, essayez-le, j'avais cependant l'impression que les couches CONV ne nécessitent pas de décrochage, sur la plupart des articles que j'ai lus, le décrochage semble être appliqué toujours aux couches finement connectées, pas aux convolutines.
Juan Antonio Gomez Moriano

3

Il existe plusieurs solutions possibles à votre problème.

  1. Utilisez également Dropout dans les couches précédentes (couches convolutives).

  2. Votre réseau semble en quelque sorte assez grand pour une tâche aussi «facile»; essayez de le réduire. Les grandes architectures sont également formées sur des ensembles de données beaucoup plus volumineux.

Si vous souhaitez conserver votre "grande" architecture, essayez:

  1. Augmentation d'image afin d'augmenter virtuellement vos données d'entraînement

  2. Essayez la formation contradictoire. Ça aide parfois.


"Votre réseau semble en quelque sorte assez grand pour une tâche aussi" facile "; essayez de le réduire. Les grandes architectures sont également entraînées sur des ensembles de données beaucoup plus importants." Je ne suis pas d'accord, car j'ai ajouté plus de circonvolutions, la précision a augmenté (au départ, j'atteignais 68% avec seulement deux circonvolutions). De plus, j'augmente déjà mon jeu de données, je fonctionne avec 50000 images.
Juan Antonio Gomez Moriano

2

Une chose qui n'a pas encore été mentionnée et que vous pouvez envisager pour l'avenir: vous pouvez toujours augmenter votre décrochage au niveau des couches entièrement connectées.

Une fois, j'ai lu un article qui utilisait un taux de décrochage de 90%. Bien qu'il ait eu beaucoup de nœuds (2048 si je me souviens bien), j'ai essayé moi-même sur des couches avec moins de nœuds et cela a été très utile dans certains cas.

J'ai simplement recherché de quel papier il s'agissait. Je ne me souviens pas du papier dont je viens de me souvenir, mais j'ai trouvé ceux qui avaient également un certain succès avec des taux d'abandon de 90%.

Karpathy, A., Toderici, G., Shetty, S., Leung, T., Sukthankar, R., et Fei-Fei, L. (2014). Classification vidéo à grande échelle avec des réseaux de neurones convolutifs. Dans Actes de la conférence de l'IEEE sur la vision par ordinateur et la reconnaissance des formes (pp. 1725-1732).

Simonyan, K. et Zisserman, A. (2014). Réseaux convolutionnels à deux flux pour la reconnaissance des actions dans les vidéos. Dans Advances in neural information processing systems (pp. 568-576).

Varol, G., Laptev, I., et Schmid, C. (2017). Convolutions temporelles à long terme pour la reconnaissance de l'action. Transactions IEEE sur l'analyse de modèle et l'intelligence machine.


0

J'ai eu ce problème également. Après y avoir réfléchi pendant des heures, j'ai décidé par hasard de mélanger les données avant de les alimenter dans le système et le tour est joué, cela a commencé à fonctionner. Il m'a fallu un peu pour comprendre que c'était le brassage qui avait fait l'affaire! J'espère que cela sauve quelqu'un de la frustration!

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.