Python: Anwendung der Bilderkennung mit CNN

Sperrige Daten

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.

image.png

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.

Normalisierung

Verschiedene Normalisierungsmethoden

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.

image.png

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.

Standardisierung

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.

image.png

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()

image.png

Bleaching

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()

image.png

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()

image.png

Chargennormalisierung

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()

image.png

Lernen übertragen

Lernen übertragen

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.

image.png

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

Python: Anwendung der Bilderkennung mit CNN
Python: Grundlagen der Bilderkennung mit CNN
Anwendung der CNN2-Bilderkennung
Bilderfassung von Firefox mit Python
Bilderkennung von Früchten mit VGG16
Bilderkennung mit CNN Pferden und Hirschen
Grundlagen der CNN 1-Bilderkennung
Anwendung von Python 3 vars
Akkorderkennung mit Chromagramm der Python Library Librosa
Python: Grundlagen der Verwendung von Scikit-Learn ①
Anwendung von Python: Datenbereinigung Teil 3: Verwendung von OpenCV und Vorverarbeitung von Bilddaten
Ich habe versucht, die handschriftliche Zeichenerkennung von Runenzeichen mit CNN mithilfe von Keras zu erkennen
[Python] Verwenden von OpenCV mit Python (Bildfilterung)
Beurteilung des hintergrundbeleuchteten Bildes mit OpenCV
Authentifizierung mit Tweepy-User-Authentifizierung und Anwendungsauthentifizierung (Python)
Python: Anwendung des überwachten Lernens (Rückkehr)
[Python] Verwenden von OpenCV mit Python (Bildtransformation)
Trübungsentfernung mit Python detailEnhanceFilter
Python x Tensoflow x Gesichtserkennung
Implementierung von Desktop-Benachrichtigungen mit Python
Implementierung von Light CNN (Python Keras)
Handschriftliche Zeichenerkennung mit KNN in Python
Test der Spracherkennung mit Azure mit Python (Eingabe vom Mikrofon)
Bilderkennung
Grundlagen der binärisierten Bildverarbeitung durch Python
Automatische Erfassung von Aktienkursen mit Python
Informationen zum Erstellen einer GUI mit TKinter of Python
Kategorieschätzung mit der Bilderkennungs-API von docomo
Beispielanwendung mit MongoDB von Spring Boot
Übung, dies in Python zu verwenden (schlecht)
Bilderkennungsmodell mit Deep Learning im Jahr 2016
Einfache Einführung der Spracherkennung mit Python
[Python] Berechnung der Bildähnlichkeit (Würfelkoeffizient)
Graustufen durch Matrix-Reinventor der Python-Bildverarbeitung-
Traffic Safety-Kun: Erkennung von Verkehrszeichen in Python
Zeichnen mit Matrix-Reinventor von Python Image Processing-
Studie über die Miete in Tokio mit Python (3-1 von 3)
Analyse des Röntgenmikrotomographiebildes durch Python
Faltungsfilterung durch Matrix-Reinventor der Python-Bildverarbeitung-
Zeitvariationsanalyse von Schwarzen Löchern mit Python
[Einführung in die Udemy Python3 + -Anwendung] 26. Kopie des Wörterbuchs
Ich habe versucht, Bilder mit CIFAR-10 mit Keras-Learning- zu erkennen.
So codieren Sie eine Drohne mithilfe der Bilderkennung
[Python] Ich habe versucht, das Mitgliederbild der Idolgruppe mithilfe von Keras zu beurteilen
Python-Bildverarbeitung
Nogizaka-Erkennungsprogramm (mit Yolov5) Inhaltsverzeichnis
Ich habe versucht, Bilder von CIFAR-10 mit Keras-Bilderkennung zu erkennen.
Maschinelles Lernen: Bilderkennung von MNIST mithilfe von PCA und Gaussian Native Bayes
[Einführung in die Udemy Python3 + -Anwendung] 19. Kopie der Liste
Holen Sie sich die Bild-URL mithilfe der Flickr-API in Python
Starten Sie Python
Einführung der Python Imaging Library (PIL) mit HomeBrew
Zeichenkodierung bei Verwendung des CSV-Moduls von Python 2.7.3
Python-Grundlagen ①
Grundlagen von Python ①
Bildverarbeitung? Die Geschichte, Python für zu starten