ImageDataGenerator
Die Bilderkennung erfordert eine große Anzahl von Kombinationen von Bilddaten und deren Beschriftungen (Lehrerdaten).
Es ist jedoch nicht möglich, eine ausreichende Anzahl von Bild- und Etikettenkombinationen zu haben. Oft kostet es viel.
Daher als Technik durchgeführt, wenn die Anzahl der Daten auf eine ausreichende Menge erhöht wird
Es gibt eine Bildauffüllung.
Das Aufblasen eines Bildes macht keinen Sinn, wenn Sie nur die Daten kopieren und die Menge erhöhen. So können Sie beispielsweise das Bild spiegeln oder verschieben, um neue Daten zu erstellen.
Hier verwenden wir den ImageDataGenerator von Keras zum Auffüllen.
ImageDataGenerator hat viele Argumente und wird entsprechend angegeben Sie können die Daten einfach verarbeiten.
Sie können auch mehrere Prozesse kombinieren, um ein neues Bild zu generieren. Schauen wir uns einige häufig verwendete Argumente in ImageDataGenerator an.
datagen = ImageDataGenerator(rotation_range=0.,
width_shift_range=0.,
height_shift_range=0.,
shear_range=0.,
zoom_range=0.,
channel_shift_range=0,
horizontal_flip=False,
vertical_flip=False)
rotation_range :Zufällig rotierender Drehbereich (Einheit: Grad)
width_shift_range :Zufällig parallele Bewegung in horizontaler Richtung, Verhältnis zur Breite des Bildes
height_shift_range :Zufällig parallele Bewegung in vertikaler Richtung, Verhältnis zur vertikalen Breite des Bildes
shear_range :Scherungsgrad. Durch Erhöhen der Größe wirkt das Bild diagonal gequetschter oder gedehnter (Einheit: Grad).
zoom_range :Die Rate, mit der das Bild zufällig komprimiert und vergrößert wird. Minimum 1-Auf Zoombereich komprimiert, bis zu 1+zoom_Erweitert auf Reichweite.
channel_shift_range:Wenn der Eingang ein RGB3-Kanalbild ist, wird R.,G,Addiere oder subtrahiere einen zufälligen Wert für jedes B.(0~255)
horizontal_flip :Wenn True angegeben ist, wird es zufällig zufällig horizontal gespiegelt.
vertical_flip :Wenn True angegeben ist, wird es zufällig vertikal gespiegelt.
flow
flow(x, y=None, batch_size=32, shuffle=True, seed=None, save_to_dir=None, save_prefix='', save_format='png', subset=None)
#Empfängt und erweitert numpy Daten und eine Reihe von Beschriftungen/Erzeugt einen Stapel normalisierter Daten.
Streit
x:Daten,Muss 4-dimensionale Daten sein. Stellen Sie Kanal 1 für Graustufendaten und Kanal 3 für RGB-Daten ein.
y:Etikette
batch_size:Ganzzahl (Standard:32). Gibt die Größe des Datenstapels an.
shuffle :Wahrheitswert (Standard):Wahr). Gibt an, ob die Daten gemischt werden sollen.
save_to_dir:Keine oder Zeichenfolge (Standard: None).. Sie können das Verzeichnis angeben, in dem Sie das generierte erweiterte Bild speichern möchten (nützlich, um zu visualisieren, was Sie getan haben).
save_prefix:Zeichenfolge (Standard'').. Präfix (Set), das dem Dateinamen beim Speichern des Bildes zugewiesen werden soll_to_Nur gültig, wenn dir ein Argument gegeben wird)
save_format: "png"Oder"jpeg"(set_to_Nur gültig, wenn dir ein Argument gegeben wird).. Der Standardwert ist"png"
Rückgabewert
x ist das Numpy-Array von Bilddaten und y ist das Numpy-Array der entsprechenden Bezeichnung.(x, y)Wird ein Iterator generiert von
Wenn Sie interessiert sind, können Sie verschiedene Verarbeitungen mit einigen anderen Argumenten durchführen. Bitte besuchen Sie die offizielle Website von Keras.
Das Bild unten ist ein Beispiel für die Normalisierung. Normalisierung ist der Prozess der Verarbeitung gemäß den Regeln in den Daten, um die Verwendung zu vereinfachen.
Im obigen Beispiel wird die Art und Weise, wie das Licht trifft, durch Durchführen einer Normalisierung vereinheitlicht. Es werden Unterschiede zwischen Daten beseitigt, die nicht direkt mit dem Training zusammenhängen. Dies kann die Effizienz des Lernens erheblich verbessern.
Die folgende Grafik wird in der Klassifizierung von cifar10 als "Batch Normalization (BN)" bezeichnet. Es zeigt, dass die korrekte Antwortrate bei der Normalisierung signifikant anstieg.
In den letzten Jahren ist eine Normalisierung in tiefen neuronalen Netzwerkmodellen manchmal weniger notwendig. Es besteht kein Zweifel, dass es bei Verwendung eines einfachen Modells äußerst nützlich sein wird.
Es gibt verschiedene Normalisierungsmethoden, die für tiefes Lernen verwendet werden, und die typischen sind
Chargennormalisierung(BN)
Hauptkomponentenanalyse (PCA)
Singularitätszerlegung (SVD)
Nullphasen-Komponentenanalyse (ZCA)
Lokale Antwortnormalisierung (LRN)
Globale Kontrastnormalisierung (GCN)
Lokale Kontrastnormalisierung (LCN)
Diese Normalisierungsmethoden können grob in "Standardisierung" und "Aufhellung" unterteilt werden.
Wir werden uns jeden von der nächsten Sitzung ansehen.
Die Standardisierung ist eine Methode, um die Verteilung der Daten für jedes Merkmal näher zu bringen, indem die einzelnen Merkmale auf 0 und Varianz 1 gemittelt werden.
Das folgende Bild befindet sich im CIFAR-10-Datensatz Über jedes Merkmal (hier 3 Kanäle von R, G, B) Es ist eine standardisierte Version. (Es wurde etwas mehr Verarbeitung hinzugefügt, um die Anzeige zu erleichtern.)
Durch die Standardisierung werden die Farbtöne gemittelt und es sieht grau aus. Im Gegenteil, die Farbe (R oder G oder B), die bis dahin nicht auffiel Weil es auf der gleichen Ebene wie andere Farben hervorgehoben (gewichtet) wird Es erleichtert das Auffinden versteckter Funktionen.
Klicken Sie hier für ein Implementierungsbeispiel
import matplotlib.pyplot as plt
from keras.datasets import cifar10
from keras.preprocessing.image import ImageDataGenerator
(X_train, y_train), (X_test, y_test) = cifar10.load_data()
for i in range(10):
plt.subplot(2, 5, i + 1)
plt.imshow(X_train[i])
plt.suptitle('base images', fontsize=12)
plt.show()
#Generatorgenerierung
datagen = ImageDataGenerator(samplewise_center=True, samplewise_std_normalization=True)
#Standardisierung
g = datagen.flow(X_train, y_train, shuffle=False)
X_batch, y_batch = g.next()
#Erleichtert die Anzeige des generierten Bildes
X_batch *= 127.0 / max(abs(X_batch.min()), X_batch.max())
X_batch += 127.0
X_batch = X_batch.astype('uint8')
for i in range(10):
plt.subplot(2, 5, i + 1)
plt.imshow(X_batch[i])
plt.suptitle('standardization results', fontsize=12)
plt.show()
Beim Aufhellen wird die Korrelation zwischen Datenmerkmalen beseitigt.
Das folgende Bild befindet sich im CIFAR-10-Datensatz Über jedes Merkmal (hier 3 Kanäle von R, G, B) Es ist weiß. (Es wurde etwas mehr Verarbeitung hinzugefügt, um die Anzeige zu erleichtern.)
Durch das Aufhellen sieht es insgesamt dunkler aus und die Kanten werden hervorgehoben. Dies liegt daran, dass durch das Aufhellen die Schattierungen ignoriert werden, die von den Informationen der umgebenden Pixel leicht zu erwarten sind.
Aufgrund des Aufhellens handelt es sich nicht um eine Oberfläche oder einen Hintergrund mit einer geringen Menge an Informationen Die Lerneffizienz kann verbessert werden, indem Kanten mit einer großen Menge an Informationen hervorgehoben werden.
#Generatorgenerierung
datagen = ImageDataGenerator(featurewise_center=True, zca_whitening=True)
#Bleaching
datagen.fit(X_train)
g = datagen.flow(X_train, y_train, shuffle=False)
X_batch, y_batch = g.next()
import matplotlib.pyplot as plt
from keras.datasets import cifar10
from keras.preprocessing.image import ImageDataGenerator
(X_train, y_train), (X_test, y_test) = cifar10.load_data()
#Dieses Mal werden wir 300 aller Daten für das Training und 100 zum Testen verwenden.
X_train = X_train[:300]
X_test = X_test[:100]
y_train = y_train[:300]
y_test = y_test[:100]
for i in range(10):
plt.subplot(2, 5, i + 1)
plt.imshow(X_train[i])
plt.suptitle('base images', fontsize=12)
plt.show()
#Generatorgenerierung
datagen = ImageDataGenerator(featurewise_center=True,zca_whitening=True)
#Bleaching
datagen.fit(X_train)
g = datagen.flow(X_train, y_train, shuffle=False)
X_batch, y_batch = g.next()
#Erleichtert die Anzeige des generierten Bildes
X_batch *= 127.0 / max(abs(X_batch.min()), abs(X_batch.max()))
X_batch += 127
X_batch = X_batch.astype('uint8')
for i in range(10):
plt.subplot(2, 5, i + 1)
plt.imshow(X_batch[i])
plt.suptitle('whitening results', fontsize=12)
plt.show()
Beim Deep Learning sollte während des Mini-Batch-Lernens für jede Charge eine Standardisierung durchgeführt werden. Es wird "Batch-Normalisierung" genannt.
In Keras, wie unten gezeigt, mit vollständig verbundenen Schichten, gewundenen Schichten, Aktivierungsfunktionen usw. Ebenso kann es mit der Add-Methode des Modells in das Modell integriert werden.
model.add(BatchNormalization())
Die Stapelnormalisierung kann nicht nur als Datenvorverarbeitung, sondern auch für die Ausgabe auf Zwischenebene angewendet werden. Insbesondere für die Ausgabe von Funktionen, deren Ausgabewertbereich nicht begrenzt ist, wie z. B. die Aktivierungsfunktion ReLU. Die Chargennormalisierung kann sehr effektiv sein, um ein reibungsloses Lernen zu ermöglichen.
import numpy as np
import matplotlib.pyplot as plt
from keras.datasets import mnist
from keras.layers import Activation, Conv2D, Dense, Flatten, MaxPooling2D, BatchNormalization
from keras.models import Sequential, load_model
from keras.utils.np_utils import to_categorical
(X_train, y_train), (X_test, y_test) = mnist.load_data()
X_train = np.reshape(a=X_train, newshape=(-1,28,28,1))[:300]
X_test = np.reshape(a = X_test,newshape=(-1,28,28,1))[:300]
y_train = to_categorical(y_train)[:300]
y_test = to_categorical(y_test)[:300]
#Definition von Modell1 (Modell, das die Sigmoidfunktion für die Aktivierungsfunktion verwendet)
model1 = Sequential()
model1.add(Conv2D(input_shape=(28, 28, 1), filters=32,
kernel_size=(2, 2), strides=(1, 1), padding="same"))
model1.add(MaxPooling2D(pool_size=(2, 2)))
model1.add(Conv2D(filters=32, kernel_size=(
2, 2), strides=(1, 1), padding="same"))
model1.add(MaxPooling2D(pool_size=(2, 2)))
model1.add(Flatten())
model1.add(Dense(256))
model1.add(Activation('sigmoid'))
model1.add(Dense(128))
model1.add(Activation('sigmoid'))
model1.add(Dense(10))
model1.add(Activation('softmax'))
model1.compile(optimizer='sgd', loss='categorical_crossentropy',
metrics=['accuracy'])
#Lernen
history = model1.fit(X_train, y_train, batch_size=32, epochs=3, validation_data=(X_test, y_test))
#Visualisierung
plt.plot(history.history['acc'], label='acc', ls='-', marker='o')
plt.plot(history.history['val_acc'], label='val_acc', ls='-', marker='x')
plt.ylabel('accuracy')
plt.xlabel('epoch')
plt.suptitle('model1', fontsize=12)
plt.show()
#Definition von Modell2 (Modell, das ReLU für die Aktivierungsfunktion verwendet)
model2 = Sequential()
model2.add(Conv2D(input_shape=(28, 28, 1), filters=32,
kernel_size=(2, 2), strides=(1, 1), padding="same"))
model2.add(MaxPooling2D(pool_size=(2, 2)))
model2.add(Conv2D(filters=32, kernel_size=(
2, 2), strides=(1, 1), padding="same"))
model2.add(MaxPooling2D(pool_size=(2, 2)))
model2.add(Flatten())
model2.add(Dense(256))
model2.add(Activation('relu'))
#Batch-Normalisierung unten hinzugefügt
model2.add(BatchNormalization())
model2.add(Dense(128))
model2.add(Activation('relu'))
#Batch-Normalisierung unten hinzugefügt
model2.add(BatchNormalization())
model2.add(Dense(10))
model2.add(Activation('softmax'))
model2.compile(optimizer='sgd', loss='categorical_crossentropy',
metrics=['accuracy'])
#Lernen
history = model2.fit(X_train, y_train, batch_size=32, epochs=3, validation_data=(X_test, y_test))
#Visualisierung
plt.plot(history.history['acc'], label='acc', ls='-', marker='o')
plt.plot(history.history['val_acc'], label='val_acc', ls='-', marker='x')
plt.ylabel('accuracy')
plt.xlabel('epoch')
plt.suptitle("model2", fontsize=12)
plt.show()
Das Trainieren eines großen neuronalen Netzes nimmt viel Zeit in Anspruch und erfordert eine große Datenmenge. In solchen Fällen ist es effektiv, ein Modell zu verwenden, das bereits mit einer großen Datenmenge trainiert und veröffentlicht wurde. Ein neues Modell mit einem trainierten Modell trainieren
Dies wird als "Transferlernen" bezeichnet.
In Keras mit dem von ImageNet erlernten Bildklassifizierungsmodell (ein riesiger Bilddatensatz, der aus 1,2 Millionen Blättern und 1000 Klassen besteht) Sie können dieses Gewicht herunterladen und verwenden.
Es gibt verschiedene Arten von veröffentlichten Modellen, aber hier verwenden wir als Beispiel ein Modell namens VGG16.
Das VGG-Modell belegte beim ILSVRC 2014, einem groß angelegten Bilderkennungswettbewerb, den zweiten Platz. Dies ist ein Netzwerkmodell, das vom VGG-Team (Visual Geometry Group) der Universität Oxford erstellt wurde.
Das Falten mit einem kleinen Filter wird 2 bis 4 Mal hintereinander wiederholt, und dann wird das Pooling wiederholt. Das Merkmal ist, dass die Ebene für diese Zeit ziemlich tief ist.
Das VGG-Modell besteht aus 16 Schichten gewichteter Schichten (Faltschicht und vollständig verbundene Schicht) und 19 Schichten. Sie werden als VGG16 bzw. VGG19 bezeichnet.
VGG16 ist ein neuronales Netzwerk mit 13 Faltungsschichten + 3 vollständig verbundenen Schichten = 16 Schichten.
Das ursprüngliche VGG-Modell ist ein Klassifizierungsmodell der 1000er-Klasse, daher gibt es 1000 Ausgabeeinheiten. Durch Verwenden der halben Ebene als Ebene für die Merkmalsextraktion ohne Verwendung der letzten vollständig verbundenen Ebene Es kann zum Transferlernen verwendet werden.
Außerdem müssen Sie sich keine Gedanken über die Größe des Eingabebilds machen.
Dies liegt daran, dass das VGG16-Modell eine kleine Kernelgröße der Faltungsschicht von 3 x 3 aufweist. Außerdem ist padding = 'same', es sei denn, das Eingabebild ist extrem klein. Dies liegt daran, dass eine bestimmte Anzahl von Merkmalen durch die 13 Schichten gesichert ist.
VGG16
Klassifizieren Sie cifar10-Datasets mithilfe des Transferlernens in Keras. Kombinieren Sie das VGG16-Modell mit dem von Ihnen verwendeten Modell vom Typ Sequential.
Erstellen Sie zunächst ein Modell von VGG.
from keras.applications.vgg16 import VGG16
#Vorgelernte Gewichte in ImageNet werden ebenfalls geladen
input_tensor = Input(shape=(32, 32, 3))
vgg16 = VGG16(include_top=False, weights='imagenet', input_tensor=input_tensor)
input_tensor ist ein optionaler Keras-Tensor (dh die Ausgabe von Ebenen.Input ()), der als Eingabebild für das Modell verwendet werden soll.
include_top gibt an, ob der letzte vollständig verbundene Layer-Teil des Originalmodells verwendet werden soll. Wenn Sie dies auf False setzen, wird nur der Merkmalsextraktionsteil durch die Faltungsschicht des Originalmodells verwendet. Sie können nachfolgenden Ebenen Ihr eigenes Modell hinzufügen.
Wenn für Gewichte ein Imagenet angegeben ist, werden die von ImageNet gelernten Gewichte verwendet, und wenn Keine angegeben ist, werden zufällige Gewichte verwendet.
Um nach dem Feature-Extraktionsteil eine weitere Ebene hinzuzufügen, definieren Sie im Voraus ein anderes Modell als VGG (in diesem Fall top_model) und kombinieren Sie es wie folgt.
top_model = Sequential()
top_model.add(Flatten(input_shape=vgg16.output_shape[1:]))
top_model.add(Dense(256, activation='sigmoid'))
top_model.add(Dropout(0.5))
top_model.add(Dense(10, activation='softmax'))
model = Model(inputs=vgg16.input, outputs=top_model(vgg16.output))
Das Gewicht des Feature-Extraktionsteils von vgg16 wird beim Aktualisieren reduziert. Korrigieren Sie es daher wie folgt.
#Bis zur 20. Modellschicht ist ein vgg-Modell
for layer in model.layers[:19]:
layer.trainable = False
Kompilieren und Lernen kann auf die gleiche Weise erfolgen, aber beim Übertragen von Lernen ist es besser, SGD als Optimierungsfunktion auszuwählen.
model.compile(loss='categorical_crossentropy',
optimizer=optimizers.SGD(lr=1e-4, momentum=0.9),
metrics=['accuracy'])
Klicken Sie hier für ein Implementierungsbeispiel
from keras import optimizers
from keras.applications.vgg16 import VGG16
from keras.datasets import cifar10
from keras.layers import Dense, Dropout, Flatten, Input
from keras.models import Model, Sequential
from keras.utils.np_utils import to_categorical
import matplotlib.pyplot as plt
import numpy as np
(X_train, y_train), (X_test, y_test) = cifar10.load_data()
X_train = X_train[:300]
X_test = X_test[:100]
y_train = to_categorical(y_train)[:300]
y_test = to_categorical(y_test)[:100]
#input_Tensor definieren
input_tensor = Input(shape=(32, 32, 3))
vgg16 = VGG16(include_top=False, weights='imagenet', input_tensor=input_tensor)
top_model = Sequential()
top_model.add(Flatten(input_shape=vgg16.output_shape[1:]))
top_model.add(Dense(256, activation='sigmoid'))
top_model.add(Dropout(0.5))
top_model.add(Dense(10, activation='softmax'))
#vgg16 und top_Bitte verketten Sie Modelle
model = Model(inputs=vgg16.input, outputs=top_model(vgg16.output))
#Bitte fixieren Sie das Gewicht bis zur 19. Schicht mit der for-Anweisung
for layer in model.layers[:19]:
layer.trainable = False
model.compile(loss='categorical_crossentropy',
optimizer=optimizers.SGD(lr=1e-4, momentum=0.9),
metrics=['accuracy'])
model.load_weights('param_vgg.hdf5')
model.fit(X_train, y_train, validation_data=(X_test, y_test), batch_size=32, epochs=1)
#Sie können die Modellgewichte unten speichern(Kann ich hier nicht machen)
# model.save_weights('param_vgg.hdf5')
#Bewertung der Genauigkeit
scores = model.evaluate(X_test, y_test, verbose=1)
print('Test loss:', scores[0])
print('Test accuracy:', scores[1])
#Datenvisualisierung (erste 10 Blatt Testdaten)
for i in range(10):
plt.subplot(2, 5, i+1)
plt.imshow(X_test[i])
plt.suptitle("10 images of test data",fontsize=16)
plt.show()
#Vorhersage (erste 10 Blatt Testdaten)
pred = np.argmax(model.predict(X_test[0:10]), axis=1)
print(pred)
model.summary()
Recommended Posts