Dieser Artikel ist ein Artikel, der Auto Encoder implementiert, optimiert und berücksichtigt.
Wir schlagen ein empfohlenes Modell für diejenigen vor, die die oben genannten Bedingungen erfüllen.
Zunächst wird anhand eines Beispiels erläutert, was Anomalieerkennung ohne Lehrer ist. Wenn Sie ein Produkt herstellen, erhalten Sie ein fehlerhaftes Produkt. Wenn beim Aufnehmen des Bildes des fehlerhaften Produkts Falten sichtbar sind, ist es für eine Person sehr schwierig, es zu trennen, sodass das neuronale Netzwerk es automatisch erkennt. Wenn es jedoch nicht ausreicht, das zerknitterte Bild als abnormal oder normal zu klassifizieren, ist es möglich, den abnormalen Wert des Bildes zu ermitteln, indem nur das normale Bild für das Training verwendet wird.
Eine Funktion, die ein normales Bild als Eingabe verwendet und ein normales Bild zurückgibt: Lernen Sie $ f $ mit einem neuronalen Netzwerk, sodass $ f (x) = x $ ($ x $ ist ein normales Bild).
Ausreißer
Es ist notwendig, ein Modell zu erstellen, das mit dem oben beschriebenen Modell bis zu einem gewissen Grad dumm ist und vorhersagt, dass es normal ist, aber fehlschlägt, wenn es abnormal ist. Daher ist es durchaus üblich, dass das Modell so intelligent wie möglich ist und das dem Eingang hinzugefügte Rauschen (Entrauschen) rückgängig macht, dh $ x = f (x + z) $ lernt ($ z $ ist Rauschen). Es scheint zu funktionieren.
Als ich versuchte, es schwierig zu machen, das Bild mit Superauflösung anstelle von Entrauschen vorherzusagen, funktionierte es gut, und die Leistung beim Erkennen von Falten und Kratzern war recht gut. Wir werden die drei bisher eingeführten Ansätze vergleichen und zeigen, wie sehr sie sich unterscheiden.
Aufgrund der Rechte ist es nicht möglich, das Ergebnis anhand des Abbilds des tatsächlichen Produkts zu betrachten, sodass das Problem recht einfach wird, aber 1 der handschriftlichen Zahlen von mnist ist ein normales Bild, und die anderen Zahlen als 1 sind abnormal. Vergleichen Sie die obigen drei Ansätze als Bild.
Wenn Sie den gesamten Codeteil kopieren, wird er in einer Arbeitsform eingeführt. Implementiere mit Keras. Importieren und laden Sie zunächst die Daten herunter.
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()
Konvertieren Sie Daten in ein verwaltbares Format
train_true = train_images[train_labels==1].reshape(6742,28,28,1)/255#Trainingsbild(1)6742 Blatt
test_true = test_images[test_labels==1].reshape(1135,28,28,1)/255#Normales Bild der Überprüfung(1)Ist 1135 Blatt
test_false = test_images[test_labels!=1].reshape(8865,28,28,1)/255#Anormales Bild der Überprüfung(Andere als 1)Ist 1032 Blatt
Ich dachte, dass die Anzahl der Mnist-Datensätze von 0 bis 9 einheitlich war, aber es scheint unzusammenhängend zu sein. Das Bild wurde auf den Bereich [0,1] normalisiert.
Definieren Sie Modell1 nur als Encoder-Decoder-Modell1
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()
Hier wurde zwischen dem Falten eine Chargenregulierung angewendet. Die Aktivierung der Ausgangsschicht erfolgt sigmoid. (Zuordnung zu [0,1]) Die Verlustfunktion hat den Vorteil, dass es bei der Bilderzeugung schwieriger ist, unscharf zu werden, wenn der absolute Wert anstelle des quadratischen Fehlers in MAE verwendet wird. Ich habe model2 auf die gleiche Weise definiert.
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()
Das Berechnungsmaterial wird zum Decodieren verwendet, indem nur Maxpooling und Codierung durchgeführt werden.
Lass uns tatsächlich trainieren.
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("{}Der Prozentsatz der richtigen Antworten für normale Lernbilder in der Woche beträgt{:.2f}%Die richtige Antwortrate für abnormale Bilder ist also{:.2f}%ist".format(i+1,t_acc[i]*100,f_acc[i]*100))
plt.plot(t_acc)
plt.plot(f_acc)
plt.show()
Im Gegensatz zur Verlustfunktion wurde bei der Ableitung von Ausreißern ein quadratischer Fehler verwendet. Wenn dies getan ist, wird Modell 1 ausgegeben, dh ein Graph, der den Übergang der Wahrscheinlichkeit zeigt, wie korrekt jedes der normalen Bilder und des abnormalen Bildes während des Trainings von einem gewöhnlichen Codierer / Decodierer richtig beurteilt werden kann. Der Schwellenwert wird als $ \ mu (Durchschnitt) + 3 \ Sigma (Standardabweichung) $ des normalen Bildes festgelegt.
Ausgabebeispiel unten Blau ist der Übergang der Wahrscheinlichkeit, dass ein normales Bild als normal beurteilt wird, und Orange ist der Übergang der Wahrscheinlichkeit, dass ein abnormales Bild als abnormales Bild beurteilt wird. Da es bei drei Standardabweichungen immer einen Schwellenwert gibt, der über dem Durchschnitt normaler Bilder liegt, beträgt die Wahrscheinlichkeit, ein normales Bild als normales Bild zu beurteilen, immer etwa 98%. Es scheint, dass ungefähr 50 Epochen genug waren, um zu lernen. (Der endgültige Wert ist, dass die richtige Antwortrate für normale Bilder 98,68% und die richtige Antwortrate für abnormale Bilder 97,13 beträgt.)
Das Modell wird unter Verwendung von Modell1 trainiert, indem dem Eingang Rauschen hinzugefügt wird, das der Größe entspricht, die auf der Skala 0,1 in der Mitte von 0 trainiert wurde. Der spezifische Code lautet wie folgt.
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("{}Der Prozentsatz der richtigen Antworten für normale Lernbilder in der Woche beträgt{:.2f}%Die richtige Antwortrate für abnormale Bilder ist also{:.2f}%ist".format(i+1,t_acc[i]*100,f_acc[i]*100))
plt.plot(t_acc)
plt.plot(f_acc)
plt.show()
Wenn Sie dies tun, erhalten Sie die folgende Grafik. Es scheint, dass die Konvergenz bis zu einem gewissen Grad schneller geworden ist. Der Endwert betrug 98,68% für normale Bilder und 97,59% für abnormale Bilder.
Lassen Sie uns model2 trainieren und das Ergebnis sehen.
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("{}Der Prozentsatz der richtigen Antworten für normale Lernbilder in der Woche beträgt{:.2f}%Die richtige Antwortrate für abnormale Bilder ist also{:.2f}%ist".format(i+1,t_acc[i]*100,f_acc[i]*100))
plt.plot(t_acc)
plt.plot(f_acc)
plt.show()
Ergebnisdiagramm Es war ein nutzloses Modell, als ich es mir vorgestellt hatte. Obwohl der Endwert nicht konvergiert zu sein scheint, betrug die normale korrekte Antwortrate 98,59% und die korrekte Antwortrate für abnormale Bilder 84,85%.
Ich habe mir das handgeschriebene Zeichen 1 angesehen, um zwischen 1 und den anderen zu unterscheiden, aber in diesem Fall stellte sich heraus, dass das Hinzufügen von Rauschen effektiv war. Es ist die Operation des Hinzufügens dieses Rauschens, die 1 wie 7 oder 9 aussehen lässt. Es ist also ziemlich offensichtlich, dass ein Modell, das daran gewöhnt ist, es auf 1 zurückzusetzen, die Genauigkeit verbessert. Mit anderen Worten, wenn die Art der Anomalie bekannt ist, ist die Leistung von Auto Encoder extrem hoch, wenn Schulungen hinzugefügt werden, um die Art der Anomalie hinzuzufügen und zurückzugeben.
Der für diesen Datensatz empfohlene Ansatz mit hoher Auflösung war nicht sehr effektiv. Beim Erkennen von Falten und Kratzern an tatsächlichen Industrieprodukten besteht der Ansatz darin, die Auflösung zu verringern, um die Falten und Kratzer unsichtbar zu machen und sie dann wiederherzustellen. Es gibt jedoch Fälle, in denen es effektiv ist. Daher ist es eine gute Idee, das zu verwendende Modell zu ändern, während das Zielproblem betrachtet wird.
Recommended Posts