――Dies ist das Ergebnis meiner eigenen Studienaufzeichnung über maschinelles Lernen und tiefes Lernen.
Genauso wie letztes Mal. Für Details ** hier **.
――Wir haben insgesamt 120 Bilddateien (JPG), 60 Fotos von Hunden (Shiba-Hunde) und 60 Fotos von Shiba-Hunden (außer Hunden) gesammelt und diese durch tiefes Lernen in zwei Kategorien eingeteilt. ―― Als Ergebnis des Trainings des Modells und der Überprüfung mit Testdaten betrug die Genauigkeit nur etwa 75-76%.
** Schritt 1 Erhöhen Sie die Menge der Analysedaten (doppelte Anzahl von Fotos) und laden Sie sie auf Google Drive hoch ** ** Schritt 2 Erstellen Sie einen Arbeitsordner in Google Drive, dekomprimieren und kopieren Sie die Daten ** ** Schritt 3 Modellbau / Lernen / Ergebnisse ** ** Schritt 4 Transferlernen mit ImageNet-Modell (VGG16) ** ** Schritt 5 Feinabstimmung mit dem ImageNet-Modell (VGG16) **
In der vorherigen Analyse gab es meines Erachtens verschiedene Gründe, warum die Klassifizierungsgenauigkeit im Bereich von 70% blieb, aber ich denke, das Wichtigste ist, dass die Trainingsdaten nur 60 Daten betrugen. Es ist ziemlich schwierig, die Daten zu erhöhen, aber für diese Klassifizierung haben wir die Anzahl der Fotos auf 120 für Hunde und 120 für andere Shiba als Hunde erhöht, was insgesamt 240 Fotos entspricht. Neu klassifizieren anhand dieser Datendatei.
--Pet Dog JPG-Datei (120 Blatt) Neu hinzugefügtes Fotobeispiel ⇒ In mydog2.zip zusammenfassen
--Jpg-Datei mit anderen Shiba-Hunden als Ihrem Hund (120 Blatt) Neu hinzugefügtes Fotobeispiel → In otherdogs2.zip zusammenfassen
--Wenn Sie die vorherige Analyse durchgeführt haben, haben Sie die folgenden Ordner zum Speichern der Daten erstellt. (Die Abbildung ist ein Beispiel für meine Ordnerstruktur)
** Hinweis) Informationen zur Zeitverzögerung bei der Zusammenarbeit zwischen Colaboratory und Google Drive ** Dies ist eher das Schreiben eines Memos als eine Warnung, jedoch für die Zusammenarbeit zwischen Colaboratory und Google Drive Ich denke, es gibt eine Zeitverzögerung. Um die Verarbeitung sicher durchzuführen, ist es besser, Schritt für Schritt fortzufahren und zu bestätigen, dass jede Verarbeitung abgeschlossen ist, anstatt jede Verarbeitung durchzuführen, z. B. einen Arbeitsordner zu erstellen und alle auf einmal zu kopieren. Ich denke. In meiner Testversion dauert es nach der Ausgabe eines Befehls von Colaboratory an Google Drive einige Zeit, bis er tatsächlich angezeigt wird. Daher kann, obwohl dies vom Zeitpunkt abhängen kann, ein Fehler auftreten, wenn der nächste Prozess vor der Reflexion ausgeführt wird. Wenn es nicht auf einmal funktioniert, halte ich es für eine gute Idee, den Prozess in mehrere Schritte zu unterteilen. </ font>
――Die Ergebnisse des Trainings sind in der folgenden Grafik dargestellt. Es gibt Anzeichen für Überlernen sowohl bei der Genauigkeit als auch beim Verlust, und es gibt keine merkliche Verbesserung.
Die auf die Testdaten angewendeten Verifizierungsergebnisse sind wie folgt. Das Erhöhen der Anzahl von Probendaten hat zu einer verbesserten Genauigkeit geführt, und die Genauigkeit hat etwa 80% erreicht. test loss: 1.7524430536416669 test acc: 0.8166666567325592
Dann habe ich mit Datenerweiterung trainiert. Die Ergebnisse des Trainings sind in der folgenden Grafik dargestellt.
Als nächstes lauten die Überprüfungsergebnisse der Testdaten, wenn die Bildgeneratoreinstellung so eingestellt ist, dass die Bilddaten aufgefüllt werden, wie folgt (die Auffüllbedingungen sind dieselben wie die Einstellungen des vorherigen Versuchs, nur die Ergebnisanzeige). Dieser hat eine höhere Genauigkeit. test loss: 1.382319548305386 test acc: 0.8666666634877522
Dieses Mal werden wir Transferlernen durchführen. Importieren Sie das trainierte Modell (VGG16) von ImageNet, das ein typisches Modell ist, aus der Keras-Bibliothek und verwenden Sie es. Aus dem VGG16-Modell wird nur die trainierte Faltungsbasis verwendet, um eine vielseitige lokale Feature-Map zu extrahieren. Durch Verbinden des Klassifikators "(für Shiba-Hund) mein Kind - anderes Kind" mit der Ausgabe wird die Klassifizierungsgenauigkeit verbessert.
--VGG16 ist ein mehrschichtiges neuronales Netzwerk, das aus 13 Faltungsschichten und 3 vollständig verbundenen Schichten für insgesamt 16 Schichten besteht. Das veröffentlichte Modell wird mit einem großen Bildsatz namens ImageNet trainiert.
―― Im Folgenden wird davon ausgegangen, dass in Google Drive ein Datenspeicherordner und ein Arbeitsordner erstellt wurden und Bilddaten für die Analyse gespeichert wurden. (Implementiert in derselben Analyseumgebung wie zuvor) --Laden Sie das VGG16-Modell in die Variable conv_base.
#Laden von VGG16
from keras.applications import VGG16
conv_base = VGG16(weights='imagenet', #Geben Sie die Art des Gewichts an(Geben Sie hier das von Imagenet gelernte Gewicht an)
include_top=False, #Gibt an, ob der vollständig gekoppelte Klassifikator auf der Ausgangsseite des NW enthalten sein soll(Da wir hier unseren eigenen vollständig verbundenen Klassifikator verwenden, werden wir ihn nicht einschließen.)
input_shape=(320, 320, 3)) #Der ImageNet-Standard ist die Form des Bildtensors, der dem NW zugeführt wird.(224, 224 3) (Diesmal 320pxl*Geben Sie ein 320pxl-RGB-Bild an)
conv_base.summary()
Die folgende Modellstruktur wird für den relevanten Teil des geladenen VGG16 angezeigt.
Model: "vgg16"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
input_2 (InputLayer) (None, 320, 320, 3) 0
_________________________________________________________________
block1_conv1 (Conv2D) (None, 320, 320, 64) 1792
_________________________________________________________________
block1_conv2 (Conv2D) (None, 320, 320, 64) 36928
_________________________________________________________________
block1_pool (MaxPooling2D) (None, 160, 160, 64) 0
_________________________________________________________________
block2_conv1 (Conv2D) (None, 160, 160, 128) 73856
_________________________________________________________________
block2_conv2 (Conv2D) (None, 160, 160, 128) 147584
_________________________________________________________________
block2_pool (MaxPooling2D) (None, 80, 80, 128) 0
_________________________________________________________________
block3_conv1 (Conv2D) (None, 80, 80, 256) 295168
_________________________________________________________________
block3_conv2 (Conv2D) (None, 80, 80, 256) 590080
_________________________________________________________________
block3_conv3 (Conv2D) (None, 80, 80, 256) 590080
_________________________________________________________________
block3_pool (MaxPooling2D) (None, 40, 40, 256) 0
_________________________________________________________________
block4_conv1 (Conv2D) (None, 40, 40, 512) 1180160
_________________________________________________________________
block4_conv2 (Conv2D) (None, 40, 40, 512) 2359808
_________________________________________________________________
block4_conv3 (Conv2D) (None, 40, 40, 512) 2359808
_________________________________________________________________
block4_pool (MaxPooling2D) (None, 20, 20, 512) 0
_________________________________________________________________
block5_conv1 (Conv2D) (None, 20, 20, 512) 2359808
_________________________________________________________________
block5_conv2 (Conv2D) (None, 20, 20, 512) 2359808
_________________________________________________________________
block5_conv3 (Conv2D) (None, 20, 20, 512) 2359808
_________________________________________________________________
block5_pool (MaxPooling2D) (None, 10, 10, 512) 0
=================================================================
Total params: 14,714,688
Trainable params: 14,714,688
Non-trainable params: 0
_________________________________________________________________
Erstellen Sie ein Modell, indem Sie die vollständig verbundene Ebene für diese binäre Klassifizierung mit conv_base verbinden.
from keras import models
from keras import layers
model = models.Sequential()
model.add(conv_base)
model.add(layers.Flatten())
model.add(layers.Dense(256, activation='relu'))
model.add(layers.Dense(1, activation='sigmoid'))
model.summary()
Die folgende Modellstruktur wird angezeigt.
Model: "sequential_1"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
vgg16 (Model) (None, 10, 10, 512) 14714688
_________________________________________________________________
flatten_1 (Flatten) (None, 51200) 0
_________________________________________________________________
dense_1 (Dense) (None, 256) 13107456
_________________________________________________________________
dense_2 (Dense) (None, 1) 257
=================================================================
Total params: 27,822,401
Trainable params: 27,822,401
Non-trainable params: 0
_________________________________________________________________
# conv_Anzahl der Gewichte, die vor dem Einfrieren der Basis trainiert werden können
print('conv_Anzahl der Gewichte, die vor dem Einfrieren der Basis trainiert werden können:' ,len(model.trainable_weights))
Bei der Ausführung wird das Ergebnis "30" angezeigt.
# conv_Stellen Sie nur das Grundgewicht so ein, dass es nicht trainierbar ist
conv_base.trainable = False
#Überprüfen der Anzahl der trainierbaren Gewichte
print('conv_Basis Anzahl der Gewichte, die im gefrorenen Zustand trainiert werden können:' ,len(model.trainable_weights))
Bei der Ausführung wird die Anzahl der trainierbaren Gewichte auf "4" geändert und angezeigt. Trainieren Sie das Modell in diesem Setup-Zustand.
Verwenden Sie den folgenden Code.
from keras.preprocessing.image import ImageDataGenerator
from keras import optimizers
#Einstellungen des Zugdatengenerators Aufgeblasen: Ja
train_datagen = ImageDataGenerator(
rescale=1./255,
rotation_range=40,
width_shift_range=0.2,
height_shift_range=0.2,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True,
fill_mode='nearest')
#Generatoreinstellungen für Validierungsdaten und Testdaten Aufgeblasen: Keine\(Der Generator von Validierungsdaten und Testdaten ist üblich)
test_datagen = ImageDataGenerator(rescale=1./255)
#Tensolisierung von Zugdaten
train_generator = train_datagen.flow_from_directory(
# target directory
train_dir,
# size 320x320
target_size=(320, 320),
batch_size=20,
#Binär als Verlustfunktion_Erfordert eine binäre Bezeichnung für die Verwendung von Crossentropy
class_mode='binary')
#Tensolisierung von Validierungsdaten
validation_generator = test_datagen.flow_from_directory(
validation_dir,
target_size=(320, 320),
batch_size=32,
class_mode='binary')
#Modell kompilieren
model.compile(loss='binary_crossentropy',
optimizer=optimizers.RMSprop(lr=2e-5),
metrics=['acc'])
#Lernen
history = model.fit_generator(
train_generator,
steps_per_epoch=100,
epochs=30,
validation_data=validation_generator,
validation_steps=50,
verbose=2)
Speichern Sie das Modell nach der Ausführung.
model.save('mydog_or_otherdogs_02a.h5')
--Überprüfen Sie als nächstes das Klassifizierungsergebnis dieses Modells mit Testdaten. (Code siehe vorherigen Artikel) test loss: 0.274524162985399 test acc: 0.9333333373069763
Durch die Feinabstimmung werden mehrere ausgangsseitige Schichten der gefrorenen Faltungsbasis, die für die Merkmalsextraktion verwendet wird, aufgetaut und sowohl der neu hinzugefügte Teil des Modells (in diesem Fall der vollständig gekoppelte Klassifikator) als auch die aufgetaute Schicht trainiert. Es ist ein Mechanismus zu tun.
- Fügen Sie am Ende des trainierten Basisnetzwerks ein benutzerdefiniertes Netzwerk hinzu
conv_base.trainable = True
set_trainable = False
for layer in conv_base.layers:
if layer.name == 'block5_conv1':
set_trainable = True
if set_trainable:
layer.trainable = True
else:
layer.trainable = False
Lernen wir mit dem folgenden Code.
#Wählen Sie RMSprop als Optimierer und verwenden Sie eine relativ niedrige Lernrate
#Wenn der Aktualisierungswert groß ist, werden die Ausdrücke der drei Feinabstimmungsebenen beschädigt.
model.compile(loss='binary_crossentropy',
optimizer=optimizers.RMSprop(lr=1e-5),
metrics=['acc'])
history = model.fit_generator(
train_generator,
steps_per_epoch=100,
epochs=100,
validation_data=validation_generator,
validation_steps=50)
Speichern Sie das Modell nach dem Training.
model.save('mydog_or_otherdogs_02b.h5')
Das resultierende Diagramm ist unten dargestellt. Der folgende Code glättet das Diagramm.
#Plotglättung
def smooth_curve(points, factor=0.8):
smoothed_points = []
for point in points:
if smoothed_points:
previous = smoothed_points[-1]
smoothed_points.append(previous * factor + point * (1 - factor))
else:
smoothed_points.append(point)
return smoothed_points
plt.plot(epochs, smooth_curve(acc), 'bo', label='Smoothed training acc')
plt.plot(epochs, smooth_curve(val_acc), 'b', label='Smoothed validation acc')
plt.title('Training and validation accuracy')
plt.legend()
plt.figure()
plt.plot(epochs, smooth_curve(loss), 'bo', label='Smoothed training loss')
plt.plot(epochs, smooth_curve(val_loss), 'b', label='Smoothed validation loss')
plt.title('Training and validation loss')
plt.legend()
plt.show()
Die Grafik ist wie folgt. Betrachtet man den Validierungsstatus, so scheint sich die Leistung mit zunehmender Anzahl von Epochen nicht zu verbessern, aber der Änderungsbereich des Diagramms wird in einem engeren Bereich als zuvor angezeigt, sodass die Genauigkeit verbessert wird. Sie können erwarten, dort zu sein.
Die auf die Testdaten angewendeten Verifizierungsergebnisse sind wie folgt.
test loss: 0.5482699687112941 test acc: 0.9499999916553498
Durch die Feinabstimmung konnten wir die Klassifizierungsleistung weiter verbessern. Ich möchte verschiedene Ansätze implementieren, die ich noch nicht versucht habe, um die Genauigkeit weiter zu verbessern. Bei dieser Überprüfung werden wir bisher eine Pause einlegen.
Recommended Posts