[PYTHON] Apprentissage profond appris par la mise en œuvre ~ Détection d'anomalies (apprentissage sans enseignant) ~

introduction

Cet article est un article qui implémente, ajuste et considère Auto Encoder.

Lecteur cible

  1. Les personnes qui souhaitent créer un modèle qui détecte les anomalies sans enseignant
  2. Vous pouvez lire et améliorer vous-même le réseau neuronal de base.

Nous proposons un modèle recommandé pour ceux qui remplissent les conditions ci-dessus.

Explication du flux de détection d'anomalies

Problème de réglage

Tout d'abord, ce qu'est la détection d'anomalies sans enseignant sera expliqué à l'aide d'un exemple. Lorsque vous fabriquez un produit, vous vous retrouvez avec un produit défectueux. Si des rides sont visibles lorsque l'image du produit défectueux est prise, il est très difficile pour une personne de la séparer, de sorte que le réseau neuronal le détecte automatiquement. Cependant, lorsqu'il ne suffit pas de classer l'image froissée comme anormale ou normale, il est possible de trouver la valeur anormale de l'image en utilisant uniquement l'image normale pour l'apprentissage.

Approche de base

Une fonction qui prend une image normale en entrée et renvoie une image normale: Apprenez $ f $ avec un réseau neuronal tel que $ f (x) = x $ ($ x $ est une image normale). Outlier|x-f(x)|Défini parxSi c'est une image normale, elle sera plus petite car elle est formée à 0,xSi c'est une image anormale, c'est la première fois pour un réseau neuronal|x-f(x)|Devient plus grand,Il doit être établi. Un tel modèle est appelé Auto Encoder, et la structure interne du modèle est souvent telle que le calque de pliage est utilisé pour le rendre plus petit et l'échantillonnage ascendant est utilisé pour agrandir l'image et la renvoyer. (Type de sablier) Notez que si vous utilisez un modèle intelligent tel que U-net ici, il est facile de faire des prédictions pour des images anormales, etc., de sorte que vous ne pouvez pas bien obtenir des valeurs anormales.

Approche Denoise

Il est nécessaire de faire un modèle qui est stupide dans une certaine mesure avec le modèle écrit ci-dessus et prédit que c'est normal, mais échoue s'il est anormal. Par conséquent, il est assez courant pour le modèle d'être aussi intelligent que possible et d'annuler le bruit ajouté à l'entrée (débruitage), c'est-à-dire d'apprendre $ x = f (x + z) $ ($ z $ est du bruit). Cela semble fonctionner.

Recommandé par l'auteur

Quand j'ai deviné que l'utilisation de la super-résolution au lieu du débruitage fonctionnerait bien pour rendre la prédiction d'image difficile, les performances étaient plutôt bonnes dans le problème de la détection des rides et des rayures. Nous comparerons les trois approches introduites jusqu'à présent et montrerons à quel point elles diffèrent.

Implémentation spécifique

Problème de réglage

Il n'est pas possible de considérer le résultat en utilisant l'image du produit réel en raison des droits, donc le problème devient assez simple, mais 1 des nombres manuscrits de mnist est une image normale et les nombres autres que 1 sont anormaux. Comparez les trois approches ci-dessus sous forme d'image.

Organiser les données

Si vous copiez toute la partie de code, elle sera introduite sous une forme de travail. Mettre en œuvre avec keras. Tout d'abord, importez et téléchargez les données.

import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
from tensorflow.keras.datasets import mnist
from keras import layers
from keras import models
from keras import optimizers
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()

Convertissez les données dans un format gérable

train_true = train_images[train_labels==1].reshape(6742,28,28,1)/255#Image de formation(1)6742 feuilles
test_true = test_images[test_labels==1].reshape(1135,28,28,1)/255#Image normale de vérification(1)Soit 1135 feuilles
test_false = test_images[test_labels!=1].reshape(8865,28,28,1)/255#Image anormale de vérification(Autre que 1)Est de 1032 feuilles

Je pensais que le nombre de jeux de données mnist était uniforme de 0 à 9, mais il semble être disjoint. L'image a été normalisée à la plage [0,1].

Définition du modèle

Définissez model1 comme un simple modèle de décodeur d'encodeur1

ffc = 8#first filter count
model1 = models.Sequential()
model1.add(layers.Conv2D(ffc,(3,3),padding="same",activation="relu",input_shape = (28,28,1)))
model1.add(layers.BatchNormalization())
model1.add(layers.MaxPooling2D((2,2)))
model1.add(layers.Conv2D(ffc,(3,3),padding="same",activation="relu"))
model1.add(layers.BatchNormalization())
model1.add(layers.MaxPooling2D((2,2)))
model1.add(layers.Conv2D(ffc,(3,3),padding="same",activation="relu"))
model1.add(layers.BatchNormalization())
model1.add(layers.UpSampling2D())
model1.add(layers.Conv2D(ffc,(3,3),padding="same",activation="relu"))
model1.add(layers.BatchNormalization())
model1.add(layers.UpSampling2D())
model1.add(layers.Conv2D(ffc,(3,3),padding="same",activation="relu"))
model1.add(layers.BatchNormalization())
model1.add(layers.Conv2D(1,(3,3),padding="same",activation="sigmoid"))
model1.compile(loss = "mae",optimizer="adam")
model1.summary()

Ici, la régularisation des lots a été appliquée entre les pliages. L'activation de la couche de sortie est sigmoïde. (Pour mapper à [0,1]) La fonction de perte a l'avantage qu'il est plus difficile de rendre flou dans la génération d'image si la valeur absolue est utilisée au lieu de l'erreur carrée dans MAE. J'ai défini model2 de la même manière.

ffc = 8#first filter count
model2 = models.Sequential()
model2.add(layers.MaxPooling2D((4,4),input_shape = (28,28,1)))
model2.add(layers.UpSampling2D())
model2.add(layers.Conv2D(ffc,(3,3),padding="same",activation="relu"))
model2.add(layers.BatchNormalization())
model2.add(layers.Conv2D(ffc,(3,3),padding="same",activation="relu"))
model2.add(layers.BatchNormalization())
model2.add(layers.UpSampling2D())
model2.add(layers.Conv2D(ffc,(3,3),padding="same",activation="relu"))
model2.add(layers.BatchNormalization())
model2.add(layers.Conv2D(ffc,(3,3),padding="same",activation="relu"))
model2.add(layers.BatchNormalization())
model2.add(layers.Conv2D(1,(3,3),padding="same",activation="sigmoid"))
model2.compile(loss = "mae",optimizer="adam")
model2.summary()

Le matériel de calcul est utilisé pour le décodage en n'effectuant que le maxpool et le codage.

Formation et résultats

Entraînons-nous réellement.

Décodeur encodeur normal

t_acc = np.zeros(50)
f_acc = np.zeros(50)
for i in range(50):
  hist = model1.fit(train_true,train_true,steps_per_epoch=10,epochs = 1,verbose=0)
  true_d = ((test_true - model1.predict(test_true))**2).reshape(1135,28*28).mean(axis=-1)
  false_d = ((test_false- model1.predict(test_false))**2).reshape(8865,28*28).mean(axis=-1)
  t_acc[i] = (true_d<=true_d.mean()+3*true_d.std()).sum()/len(true_d)
  f_acc[i] = (false_d>true_d.mean()+3*true_d.std()).sum()/len(false_d)
  print("{}Le pourcentage de réponses correctes pour les images d'apprentissage normales dans la semaine est{:.2f}%Ainsi, le taux de réponse correct des images anormales est{:.2f}%est".format(i+1,t_acc[i]*100,f_acc[i]*100))
plt.plot(t_acc)
plt.plot(f_acc)
plt.show()

Contrairement à la fonction de perte, la dérivation des valeurs aberrantes a utilisé une erreur quadratique. Lorsque cela est fait, le modèle 1, c'est-à-dire un graphique montrant la transition de la probabilité de la façon dont chacune de l'image normale et de l'image anormale peut être correctement jugée pendant l'apprentissage par un codeur / décodeur ordinaire est sorti. Le seuil est défini comme $ \ mu (moyenne) + 3 \ sigma (écart type) $ de l'image normale.

Exemple de sortie ci-dessous スクリーンショット 2020-06-04 18.58.28.png Le bleu est la transition de la probabilité qu'une image normale soit jugée normale, et l'orange est la transition de la probabilité qu'une image anormale soit jugée comme une image anormale. Puisqu'il y a toujours un seuil au-dessus de la moyenne des images normales de trois écarts types, la probabilité de juger une image normale comme une image normale est toujours d'environ 98%. Il semble qu'une cinquantaine d'époques suffisait à apprendre. (La valeur finale est que le taux de réponse correct pour les images normales est de 98,68% et le taux de réponse correct pour les images anormales est de 97,13).

Décodeur d'encodeur de bruit

Le modèle est entraîné à l'aide de model1 en ajoutant du bruit de même taille que la taille entraînée à l'échelle 0,1 au centre de 0 à l'entrée. Le code spécifique est le suivant.

t_acc = np.zeros(50)
f_acc = np.zeros(50)
for i in range(50):
  hist = model1.fit(train_true,train_true+0.1*np.random.normal(size=train_true.shape),steps_per_epoch=10,epochs = 1,verbose=0)
  true_d = ((test_true - model1.predict(test_true))**2).reshape(1135,28*28).mean(axis=-1)
  false_d = ((test_false- model1.predict(test_false))**2).reshape(8865,28*28).mean(axis=-1)
  t_acc[i] = (true_d<=true_d.mean()+3*true_d.std()).sum()/len(true_d)
  f_acc[i] = (false_d>true_d.mean()+3*true_d.std()).sum()/len(false_d)
  print("{}Le pourcentage de réponses correctes pour les images d'apprentissage normales dans la semaine est{:.2f}%Ainsi, le taux de réponse correct des images anormales est{:.2f}%est".format(i+1,t_acc[i]*100,f_acc[i]*100))
plt.plot(t_acc)
plt.plot(f_acc)
plt.show()

Si vous faites cela, vous obtiendrez le graphique suivant. スクリーンショット 2020-06-04 19.14.59.png Il semble que la convergence soit devenue plus rapide dans une certaine mesure. La valeur finale était de 98,68% pour les images normales et de 97,59% pour les images anormales.

Approche de super-résolution

Entraînons model2 et voyons le résultat.

t_acc = np.zeros(50)
f_acc = np.zeros(50)
for i in range(50):
  hist = model2.fit(train_true,train_true,steps_per_epoch=10,epochs = 1,verbose=0)
  true_d = ((test_true - model2.predict(test_true))**2).reshape(1135,28*28).mean(axis=-1)
  false_d = ((test_false- model2.predict(test_false))**2).reshape(8865,28*28).mean(axis=-1)
  t_acc[i] = (true_d<=true_d.mean()+3*true_d.std()).sum()/len(true_d)
  f_acc[i] = (false_d>true_d.mean()+3*true_d.std()).sum()/len(false_d)
  print("{}Le pourcentage de réponses correctes pour les images d'apprentissage normales dans la semaine est{:.2f}%Ainsi, le taux de réponse correct des images anormales est{:.2f}%est".format(i+1,t_acc[i]*100,f_acc[i]*100))
plt.plot(t_acc)
plt.plot(f_acc)
plt.show()

Graphique de résultat スクリーンショット 2020-06-04 19.25.23.png C'était un modèle inutile que je n'avais imaginé. Bien que la valeur finale ne semble pas avoir convergé, le taux normal de réponse correcte était de 98,59% et le taux de réponse correcte pour les images anormales était de 84,85%.

Conclusion

J'ai regardé le caractère manuscrit 1 pour faire la distinction entre 1 et les autres, mais dans ce cas, il s'est avéré que l'ajout de bruit était efficace. C'est l'opération d'ajout de ce bruit qui fait que 1 ressemble à 7 ou 9, il est donc assez évident qu'un modèle habitué à le remettre à 1 améliorera la précision. En d'autres termes, si le type d'anomalie est connu, les performances d'Auto Encoder seront extrêmement élevées si un entraînement est ajouté pour ajouter ce type d'anomalie et le renvoyer.

L'approche de super-résolution recommandée pour cet ensemble de données n'était pas très efficace, mais lors de la détection des rides et des rayures sur des produits industriels réels, l'approche consiste à réduire la résolution pour rendre les rides et les rayures invisibles, puis à les restaurer. Cependant, il y a des cas où cela est efficace, c'est donc une bonne idée de changer le modèle à utiliser tout en regardant le problème cible.

Recommended Posts

Apprentissage profond appris par la mise en œuvre ~ Détection d'anomalies (apprentissage sans enseignant) ~
Apprentissage profond appris par l'implémentation 1 (édition de retour)
Deep learning 2 appris par l'implémentation (classification d'images)
Apprentissage profond appris par mise en œuvre (segmentation) ~ Mise en œuvre de SegNet ~
Détection de valeur anormale par apprentissage non supervisé: distance Maharanobis (implémentation)
[Détection d'anomalies] Détecter la distorsion de l'image par apprentissage à distance
Détection d'objets par apprentissage profond pour comprendre en profondeur par Keras
Chainer et deep learning appris par approximation de fonction
Détection de valeur anormale par apprentissage non supervisé: distance de Maharanobis (théorie)
Apprentissage par renforcement profond 2 Mise en œuvre de l'apprentissage par renforcement
J'ai essayé d'implémenter la détection d'anomalies par apprentissage de structure clairsemée
Détection d'anomalies par encodeur automatique à l'aide de keras [Exemple d'implémentation pour les débutants]
Implémentation du modèle de reconnaissance d'images d'apprentissage en profondeur 2
[Détection d'anomalies] Essayez d'utiliser la dernière méthode d'apprentissage à distance
Othello-De la troisième ligne de "Implementation Deep Learning" (3)
Produisez de belles vaches de mer par apprentissage profond
Détection d'anomalies à l'aide de MNIST par Autoencoder (PyTorch)
Détection d'anomalies des données ECG par profil matriciel
[Apprentissage en profondeur] Détection de visage Nogisaka ~ Pour les débutants ~
L'apprentissage en profondeur
Apprentissage profond à partir de zéro - Conseils du chapitre 4 pour la théorie de l'apprentissage profond et la mise en œuvre apprise en Python
Othello-De la troisième ligne de "Implementation Deep Learning" (2)
Deep Learning from scratch La théorie et la mise en œuvre de l'apprentissage profond appris avec Python Chapitre 3
[Mémo d'apprentissage] Apprentissage profond à partir de zéro ~ Mise en œuvre de l'abandon ~
99,78% de précision avec apprentissage en profondeur en reconnaissant les hiragana manuscrits
Interpolation d'images vidéo par apprentissage en profondeur, partie 1 [Python]
Apprentissage parallèle du deep learning par Keras et Kubernetes
Implémentation du modèle Deep Learning pour la reconnaissance d'images
Premier apprentissage profond en C # -Imitation de l'implémentation en Python-
Mémorandum d'apprentissage profond
Commencer l'apprentissage en profondeur
Apprentissage en profondeur Python
Apprendre sans enseignant 1 Principes de base
Apprentissage profond × Python
[Pour les débutants en apprentissage profond] Implémentation d'une classification binaire simple par couplage complet à l'aide de Keras
Investissement en actions par apprentissage approfondi (méthode du gradient de politique) (1)
Détection d'anomalies des données de séries chronologiques par LSTM (Keras)
Classer les articles avec des balises spécifiées par Qiita par apprentissage non supervisé
Othello ~ De la troisième ligne de "Implementation Deep Learning" (4) [Fin]
Classer les visages d'anime par suite / apprentissage profond avec Keras
J'ai essayé de faire d'Othello AI que j'ai appris 7,2 millions de mains par apprentissage profond avec Chainer