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:
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
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.
la source
Réponses:
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
la source
NOTE USE EITHER mean centering or min-max, NOT BOTH
. Je divise actuellement mes images d'entrée par 255 à l'intérieur de moninput_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/…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.
la source
Il existe plusieurs solutions possibles à votre problème.
Utilisez également Dropout dans les couches précédentes (couches convolutives).
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:
Augmentation d'image afin d'augmenter virtuellement vos données d'entraînement
Essayez la formation contradictoire. Ça aide parfois.
la source
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%.
la source
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!
la source