Architectures CNN pour la régression?

32

J'ai travaillé sur un problème de régression où l'entrée est une image et l'étiquette est une valeur continue entre 80 et 350. Les images sont de certains produits chimiques après qu'une réaction ait lieu. La couleur qui apparaît indique la concentration d'un autre produit chimique qui reste, et c'est ce que le modèle doit produire - la concentration de ce produit chimique. Les images peuvent être pivotées, retournées, mises en miroir et la sortie attendue doit toujours être la même. Ce type d'analyse est effectué dans de vrais laboratoires (des machines très spécialisées produisent la concentration des produits chimiques en utilisant l'analyse des couleurs, tout comme j'entraîne ce modèle à le faire).

Jusqu'à présent, je n'ai expérimenté que des modèles basés à peu près sur VGG (plusieurs séquences de blocs conv-conv-conv-pool). Avant d'expérimenter avec des architectures plus récentes (Inception, ResNets, etc.), je pensais rechercher s'il existe d'autres architectures plus couramment utilisées pour la régression à l'aide d'images.

L'ensemble de données ressemble à ceci:

entrez la description de l'image ici

L'ensemble de données contient environ 5 000 échantillons 250 x 250, que j'ai redimensionnés à 64 x 64, ce qui facilite la formation. Une fois que j'ai trouvé une architecture prometteuse, je vais expérimenter avec des images de plus grande résolution.

Jusqu'à présent, mes meilleurs modèles ont une erreur quadratique moyenne sur les ensembles de formation et de validation d'environ 0,3, ce qui est loin d'être acceptable dans mon cas d'utilisation.

Jusqu'à présent, mon meilleur modèle ressemble à ceci:

// pseudo code
x = conv2d(x, filters=32, kernel=[3,3])->batch_norm()->relu()
x = conv2d(x, filters=32, kernel=[3,3])->batch_norm()->relu()
x = conv2d(x, filters=32, kernel=[3,3])->batch_norm()->relu()
x = maxpool(x, size=[2,2], stride=[2,2])

x = conv2d(x, filters=64, kernel=[3,3])->batch_norm()->relu()
x = conv2d(x, filters=64, kernel=[3,3])->batch_norm()->relu()
x = conv2d(x, filters=64, kernel=[3,3])->batch_norm()->relu()
x = maxpool(x, size=[2,2], stride=[2,2])

x = conv2d(x, filters=128, kernel=[3,3])->batch_norm()->relu()
x = conv2d(x, filters=128, kernel=[3,3])->batch_norm()->relu()
x = conv2d(x, filters=128, kernel=[3,3])->batch_norm()->relu()
x = maxpool(x, size=[2,2], stride=[2,2])

x = dropout()->conv2d(x, filters=128, kernel=[1, 1])->batch_norm()->relu()
x = dropout()->conv2d(x, filters=32, kernel=[1, 1])->batch_norm()->relu()

y = dense(x, units=1)

// loss = mean_squared_error(y, labels)

Question

Quelle est une architecture appropriée pour la sortie de régression d'une entrée d'image?

modifier

J'ai reformulé mon explication et supprimé les mentions d'exactitude.

Modifier 2

J'ai restructuré ma question donc j'espère qu'il est clair ce que je recherche

rodrigo-silveira
la source
4
La précision n'est pas une mesure qui peut être directement appliquée aux problèmes de régression. Que voulez-vous dire lorsque vous dites que votre précision est de 30%? La précision ne s'applique vraiment qu'aux tâches de classification, pas à la régression.
Nuclear Wang
1
Qu'entendez-vous par «prédit correctement 30% du temps» ? Faites-vous vraiment de la régression?
Firebug
1
Pourquoi appelez-vous ce problème de régression? N'essayez-vous pas de les classer en étiquettes? les étiquettes sont-elles cardinales?
Aksakal
2
Je ne veux pas exactement la même chose que vgg. Je fais quelque chose de similaire à vgg, ce qui signifie une série de convs suivie d'une mise en commun maximale, suivie d'une connexion complète. Cela ressemble à une approche générique pour travailler avec des images. Mais là encore, c'est tout l'objet de ma question initiale. On dirait que tous ces commentaires, bien que perspicaces pour moi, manquent complètement le point de ce que je demande en premier lieu.
rodrigo-silveira
1
De plus, nous pourrons peut-être fournir une meilleure aide si vous décrivez mieux le problème. 1) Quelles sont les images? Quelle est leur résolution? Quelle relation y a-t-il entre les images et votre réponse, ? Cette relation est-elle invariante en rotation, c'est-à-dire que si je tourne votre image circulaire d'un angle arbitraire θ , dois-je m'attendre à ce que y change? 2) Savez-vous que 5000 images pour former une architecture VGG-net sont une misère? Avez-vous calculé le nombre de paramètres de votre architecture? Existe-t-il un moyen d'obtenir plus d'images? Si vous ne le pouvez pas, alors vous avez peut-être besoin de ...y[80,350]θy
DeltaIV

Réponses:

42

Tout d'abord une suggestion générale: faites une recherche documentaire avant de commencer à faire des expériences sur un sujet que vous ne connaissez pas. Vous vous épargnerez beaucoup de temps.

Dans ce cas, en regardant les documents existants, vous avez peut-être remarqué que

  1. CNNs ont été utilisés à plusieurs reprises pour la régression: c'est un classique mais il est vieux (oui, 3 ans est vieux dans DL). Un journal plus moderne n'aurait pas utilisé AlexNet pour cette tâche. C'est plus récent, mais c'est pour un problème beaucoup plus compliqué (rotation 3D), et de toute façon je ne le connais pas.
  2. La régression avec les CNN n'est pas un problème trivial. En examinant à nouveau le premier article, vous verrez qu'ils ont un problème où ils peuvent essentiellement générer des données infinies. Leur objectif est de prédire l'angle de rotation nécessaire pour rectifier les images 2D. Cela signifie que je peux essentiellement prendre mon ensemble d'entraînement et l'augmenter en tournant chaque image selon des angles arbitraires, et j'obtiendrai un ensemble d'entraînement valide et plus grand. Ainsi, le problème semble relativement simple, en ce qui concerne les problèmes de Deep Learning. Soit dit en passant, notez les autres astuces d'augmentation de données qu'ils utilisent:

    Nous utilisons des traductions (jusqu'à 5% de la largeur de l'image), un réglage de la luminosité dans la plage [−0,2, 0,2], un réglage gamma avec γ ∈ [−0,5, 0,1] et un bruit de pixel gaussien avec un écart type dans la plage [0 , 0,02].

    k

    yxα=atan2(y,x)>11%de l'erreur maximale possible. Ils ont fait un peu mieux en utilisant deux réseaux en série: le premier effectuerait la classification (prédire si l'angle serait dans ou ), puis l'image, pivotée de la quantité prédite par le premier réseau, serait envoyée à un autre réseau de neurones (pour la régression, cette fois), qui prédirait la rotation supplémentaire finale dans la plage .[180°,90°],[90°,0°],[0°,90°][90°,180°][45°,45°]

    Sur un problème beaucoup plus simple (MNIST tourné), vous pouvez obtenir quelque chose de mieux , mais vous ne descendez toujours pas en dessous d'une erreur RMSE qui est de de l'erreur maximale possible.2.6%

Alors, que pouvons-nous apprendre de cela? Tout d'abord, ces 5000 images sont un petit ensemble de données pour votre tâche. Le premier article a utilisé un réseau qui a été pré-formé sur des images similaires à celles pour lesquelles ils voulaient apprendre la tâche de régression: non seulement vous devez apprendre une tâche différente de celle pour laquelle l'architecture a été conçue (classification), mais votre ensemble d'entraînement ne fonctionne pas ne ressemblent en rien aux ensembles de formation sur lesquels ces réseaux sont généralement formés (CIFAR-10/100 ou ImageNet). Vous n'obtiendrez donc probablement aucun avantage de l'apprentissage par transfert. L'exemple MATLAB avait 5000 images, mais elles étaient en noir et blanc et sémantiquement très similaires (eh bien, cela pourrait être votre cas aussi).

Alors, comment réaliste fait mieux que 0,3? Nous devons tout d'abord comprendre ce que vous entendez par 0,3 perte moyenne. Voulez-vous dire que l'erreur RMSE est de 0,3,

1Ni=1N(h(xi)yi)2

où est la taille de votre ensemble d'entraînement (donc, ), est la sortie de votre CNN pour l'image et est la concentration correspondante du produit chimique? Depuis , puis en supposant que vous coupez les prédictions de votre CNN entre 80 et 350 (ou que vous utilisez simplement un logit pour les faire tenir dans cet intervalle), vous obtenez moins de erreur. Sérieusement, à quoi vous attendez-vous? cela ne me semble pas du tout une grosse erreur.NN<5000h(xi)xiyiyi[80,350]0.12%

Essayez également de calculer le nombre de paramètres dans votre réseau: je suis pressé et je fais peut-être des erreurs stupides, alors vérifiez bien mes calculs avec une summaryfonction de n'importe quel cadre que vous utilisez. Cependant, grosso modo, je dirais que vous avez

9×(3×32+2×32×32+32×64+2×64×64+64×128+2×128×128)+128×128+128×32+32×32×32=533344

(notez que j'ai ignoré les paramètres des couches normalisées par lot, mais ce ne sont que 4 paramètres pour la couche, donc ils ne font pas de différence). Vous avez un demi-million de paramètres et 5000 exemples ... à quoi vous attendriez-vous? Bien sûr, le nombre de paramètres n'est pas un bon indicateur de la capacité d'un réseau neuronal (c'est un modèle non identifiable), mais quand même ... Je ne pense pas que vous puissiez faire beaucoup mieux que cela, mais vous pouvez essayer un quelques choses:

  • normaliser toutes les entrées (par exemple, redimensionner les intensités RVB de chaque pixel entre -1 et 1, ou utiliser la normalisation) et toutes les sorties. Cela vous sera particulièrement utile si vous rencontrez des problèmes de convergence.
  • passer en niveaux de gris: cela réduirait vos canaux d'entrée de 3 à 1. Toutes vos images semblent (à mon avis très peu formées) être de couleurs relativement similaires. Êtes-vous sûr que c'est la couleur dont vous avez besoin pour prédire , et non l'existence de zones plus sombres ou plus claires? Peut-être êtes-vous sûr (je ne suis pas un expert): dans ce cas, sautez cette suggestion.y
  • augmentation des données: puisque vous avez dit que le retournement, la rotation d'un angle arbitraire ou vos images en miroir devrait aboutir à la même sortie, vous pouvez augmenter la taille de votre ensemble de données beaucoup . Notez qu'avec un ensemble de données plus important, l'erreur sur l'ensemble d'entraînement augmentera: ce que nous recherchons ici est un plus petit écart entre la perte de l'ensemble d'entraînement et la perte de l'ensemble de test. De plus, si la perte de l'ensemble d'entraînement augmente beaucoup, cela pourrait être une bonne nouvelle: cela peut signifier que vous pouvez former un réseau plus profond sur cet ensemble d'entraînement plus grand sans risque de sur-ajustement. Essayez d'ajouter plus de couches et voyez si vous obtenez maintenant un ensemble d'entraînement plus petit et une perte de test. Enfin, vous pouvez également essayer les autres astuces d'augmentation de données que j'ai citées ci-dessus, si elles ont un sens dans le contexte de votre application.
  • utilisez l'astuce de classification puis de régression: un premier réseau détermine uniquement si doit être dans l'un, disons, de 10 bacs, tels que , etc. Un deuxième réseau calcule ensuite une correction : le centrage et la normalisation peuvent également aider ici. Je ne peux pas dire sans essayer.y[80,97],[97,124][0,27]
  • essayez d'utiliser une architecture moderne (Inception ou ResNet) plutôt qu'une architecture vintage. ResNet a en fait moins de paramètres que VGG-net. Bien sûr, vous voulez utiliser les petits ResNets ici - je ne pense pas que ResNet-101 pourrait aider sur un ensemble de données de 5000 images. Vous pouvez cependant augmenter considérablement l'ensemble de données ...
  • Étant donné que votre sortie est invariante à la rotation, une autre bonne idée serait d'utiliser soit des CNN équivariants de groupe , dont la sortie (lorsqu'elle est utilisée comme classificateurs) est invariante à des rotations discrètes , soit des CNN orientablesdont la sortie est invariante aux rotations continues. La propriété d'invariance vous permettrait d'obtenir de bons résultats avec beaucoup moins d'augmentation de données, ou idéalement aucune (pour ce qui concerne les rotations: bien sûr, vous avez toujours besoin des autres types de da). Les CNN équivariants de groupe sont plus matures que les CNN orientables d'un point de vue de mise en œuvre, donc j'essaierais d'abord les CNN de groupe. Vous pouvez essayer la classification puis la régression, en utilisant le G-CNN pour la partie classification, ou vous pouvez expérimenter avec l'approche de régression pure. N'oubliez pas de modifier la couche supérieure en conséquence.
  • expérimenter avec la taille du lot (ouais, ouais, je sais que le piratage hyperparamètres n'est pas cool, mais c'est le meilleur que je pourrais venir dans un délai limité et gratuitement :-)
  • enfin, il existe des architectures spécialement développées pour faire des prédictions précises avec de petits ensembles de données. La plupart d'entre eux ont utilisé des convolutions dilatées : un exemple célèbre est le réseau neuronal convolutionnel dense à échelle mixte . L'implémentation n'est cependant pas anodine.
DeltaIV
la source
3
Merci pour la réponse détaillée. J'avais déjà fait une augmentation significative des données. J'ai essayé quelques variantes du modèle de démarrage (où une variation signifie que le nombre de filtres est mis à l'échelle de manière égale sur l'ensemble du modèle). Vu des améliorations incroyables. Il reste encore du chemin à faire. Je vais essayer quelques-unes de vos suggestions. Merci encore.
rodrigo-silveira
@ rodrigo-silveira vous êtes les bienvenus, faites-moi savoir comment ça se passe. Peut-être que nous pourrons parler dans le chat une fois que vous aurez des résultats.
DeltaIV
1
Grande réponse, mérite plus ^
Gilly
1
Très bien composé!
Karthik Thiagarajan
1
Je vous donnerais 10 000 points pour cela si je le pouvais. Réponse étonnante
Boppity Bop