[PYTHON] [Bildklassifizierung] Hundegesichtsanalyse

1. Zuallererst

Ich habe versucht, mich für Tiergesichtsanalysen zu interessieren.

2. Referenzen

"Erstellen Sie ein Modell für maschinelles Lernen, das in Keras zwischen" lachenden Hunden "und" wütenden Hunden "unterscheidet." https://qiita.com/ariera/items/545d48c961170a784075

3. Inhalt

3-1. Datenvorverarbeitung

#Definieren Sie eine Funktion zum Lesen und Konvertieren eines Bildes in eine Matrix
from keras.preprocessing.image import load_img, img_to_array
def img_to_traindata(file, img_rows, img_cols, rgb):
    if rgb == 0:
        img = load_img(file, color_mode = "grayscale", target_size=(img_rows,img_cols)) #Lesen Sie mit Graustufen
    else:
        img = load_img(file, color_mode = "rgb", target_size=(img_rows,img_cols)) #RGB einlesen
    x = img_to_array(img)
    x = x.astype('float32')
    x /= 255
    return x

#Trainingsdaten, Testdatengenerierung
import glob, os

img_rows = 224 #Die Bildgröße ist die Standardgröße von VGG16
img_cols = 224
nb_classes = 2 #2 Klassen wütend und lachend
img_dirs = ["./dog_angry", "./dog_smile"] #Verzeichnis mit Bildern von wütenden und lachenden Hunden

X_train = []
Y_train = []
X_test = []
Y_test = []
for n, img_dir in enumerate(img_dirs):
    img_files = glob.glob(img_dir+"/*.jpg ")   #Lesen Sie alle Bilddateien im Verzeichnis
    for i, img_file in enumerate(img_files):  #Verzeichnis(Zeichentyp)Für alle Dateien in
        x = img_to_traindata(img_file, img_rows, img_cols, 1) #Lesen Sie jede Bilddatei in RGB und konvertieren Sie sie in eine Matrix
        if i < 8: #Lerndaten vom 1. bis zum 8. Blatt
            X_train.append(x) #Trainingsdaten(Eingang)Fügen Sie eine Matrix hinzu, in die Bilder konvertiert werden
            Y_train.append(n) #Trainingsdaten(Ausgabe)Zur Klasse(Wütend=0, lol=1)Hinzufügen
        else:       #Testdaten für das 9. und nachfolgende Blatt
            X_test.append(x) #Testdaten(Eingang)Fügen Sie eine Matrix hinzu, in die Bilder konvertiert werden
            Y_test.append(n) #Testdaten(Ausgabe)Zur Klasse(Wütend=0, lol=1)Hinzufügen

import numpy as np
#Trainings- und Testdaten von Liste bis Numpy.In ndarray konvertieren
X_train = np.array(X_train, dtype='float') 
Y_train = np.array(Y_train, dtype='int')
X_test = np.array(X_test, dtype='float')
Y_test = np.array(Y_test, dtype='int')

#Kategoriale Daten(Vektor)Umstellung auf
from keras.utils import np_utils
Y_train = np_utils.to_categorical(Y_train, nb_classes)
Y_test = np_utils.to_categorical(Y_test, nb_classes)

#Speichern Sie die erstellten Trainingsdaten und Testdaten als Datei
np.save('models/X_train_2class_120.npy', X_train)
np.save('models/X_test_2class_120.npy', X_test)
np.save('models/Y_train_2class_120.npy', Y_train)
np.save('models/Y_test_2class_120.npy', Y_test)

#Zeigen Sie den Typ der erstellten Daten an
print(X_train.shape)
print(Y_train.shape)
print(X_test.shape)


from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation, Flatten
from keras.layers import Conv2D, MaxPooling2D

#【Parametereinstellungen】
batch_size = 20
epochs = 30

input_shape = (img_rows, img_cols, 3)
nb_filters = 32
# size of pooling area for max pooling
pool_size = (2, 2)
# convolution kernel size
kernel_size = (3, 3)

#[Modelldefinition]
model = Sequential()
model.add(Conv2D(nb_filters, kernel_size, #Faltschicht
                        padding='valid',
                        activation='relu',
                        input_shape=input_shape))
model.add(Conv2D(nb_filters, kernel_size, activation='relu')) #Faltschicht
model.add(MaxPooling2D(pool_size=pool_size)) #Pooling-Schicht
model.add(Conv2D(nb_filters, kernel_size, activation='relu')) #Faltschicht
model.add(MaxPooling2D(pool_size=pool_size)) #Pooling-Schicht
model.add(Dropout(0.25)) #Aussteigen(Trennen Sie die Eingabe und Ausgabe nach dem Zufallsprinzip, um ein Überlernen zu vermeiden)

model.add(Flatten()) #Konvertieren Sie ein mehrdimensionales Array in ein eindimensionales Array
model.add(Dense(128, activation='relu'))  #Vollständig verbundene Schicht
model.add(Dropout(0.2))  #Aussteigen
model.add(Dense(nb_classes, activation='sigmoid'))  #Da es sich um 2 Klassen handelt, ist die vollständig verbundene Schicht sigmoid

#Modell kompilieren
model.compile(loss='binary_crossentropy', #Binär, weil es 2 Klassen sind_crossentropy
              optimizer='adam', #Verwenden Sie Standardeinstellungen für Optimierungsfunktionsparameter
              metrics=['accuracy'])

#Definieren Sie einen Rückruf, um Lernergebnisse für jede Epoche zu generieren(Speichern Sie nur, wenn die Genauigkeit besser ist als beim letzten Mal)】
from keras.callbacks import ModelCheckpoint
import os
model_checkpoint = ModelCheckpoint(
    filepath=os.path.join('models','model_2class120_{epoch:02d}.h5'),
    monitor='val_accuracy',
    mode='max',
    save_best_only=True,
    verbose=1)
print("filepath",os.path.join('models','model_.h5'))

#[Lernen]
result = model.fit(X_train, Y_train, batch_size=batch_size, epochs=epochs, verbose=1, validation_data=(X_test, Y_test),
                   callbacks=[model_checkpoint],validation_split=0.1)

3-2. Lernen

from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation, Flatten
from keras.layers import Conv2D, MaxPooling2D

#【Parametereinstellungen】
batch_size = 20
epochs = 30

input_shape = (img_rows, img_cols, 3)
nb_filters = 32
# size of pooling area for max pooling
pool_size = (2, 2)
# convolution kernel size
kernel_size = (3, 3)

#[Modelldefinition]
model = Sequential()
model.add(Conv2D(nb_filters, kernel_size, #Faltschicht
                        padding='valid',
                        activation='relu',
                        input_shape=input_shape))
model.add(Conv2D(nb_filters, kernel_size, activation='relu')) #Faltschicht
model.add(MaxPooling2D(pool_size=pool_size)) #Pooling-Schicht
model.add(Conv2D(nb_filters, kernel_size, activation='relu')) #Faltschicht
model.add(MaxPooling2D(pool_size=pool_size)) #Pooling-Schicht
model.add(Dropout(0.25)) #Aussteigen(Trennen Sie die Eingabe und Ausgabe nach dem Zufallsprinzip, um ein Überlernen zu vermeiden)

model.add(Flatten()) #Konvertieren Sie ein mehrdimensionales Array in ein eindimensionales Array
model.add(Dense(128, activation='relu'))  #Vollständig verbundene Schicht
model.add(Dropout(0.2))  #Aussteigen
model.add(Dense(nb_classes, activation='sigmoid'))  #Da es sich um 2 Klassen handelt, ist die vollständig verbundene Schicht sigmoid

#Modell kompilieren
model.compile(loss='binary_crossentropy', #Binär, weil es 2 Klassen sind_crossentropy
              optimizer='adam', #Verwenden Sie Standardeinstellungen für Optimierungsfunktionsparameter
              metrics=['accuracy'])

#Definieren Sie einen Rückruf, um Lernergebnisse für jede Epoche zu generieren(Speichern Sie nur, wenn die Genauigkeit besser ist als beim letzten Mal)】
from keras.callbacks import ModelCheckpoint
import os
model_checkpoint = ModelCheckpoint(
    filepath=os.path.join('models','model_2class120_{epoch:02d}_{val_acc:.3f}.h5'),
    monitor='val_acc',
    mode='max',
    save_best_only=True,
    verbose=1)

#[Lernen]
result = model.fit(X_train, Y_train, batch_size=batch_size, epochs=epochs, verbose=1, validation_data=(X_test, Y_test),
                   callbacks=[model_checkpoint])

3-3. Klassifizierung

from keras.models import load_model
from keras.preprocessing.image import load_img, img_to_array
import matplotlib.pyplot as plt

model = load_model('models/model_2class120_04.h5')
model.summary()

def img_to_traindata(file, img_rows, img_cols, rgb):
    if rgb == 0:
        img = load_img(file, color_mode = "grayscale", target_size=(img_rows,img_cols)) #Lesen Sie mit Graustufen
    else:
        img = load_img(file, color_mode = "rgb", target_size=(img_rows,img_cols)) #RGB einlesen
    x = img_to_array(img)
    x = x.astype('float32')
    x /= 255
    return x

import numpy as np
img_rows = 224 #Die Bildgröße ist die Standardgröße von VGG16
img_cols = 224

##Bild wird geladen
filename = "dog_smile/n02085936_37.jpg "
x = img_to_traindata(filename, img_rows, img_cols, 1) # img_to_Die Traindatenfunktion wird beim Generieren von Trainingsdaten definiert
x = np.expand_dims(x, axis=0)

##Bestimmen Sie, welche Klasse
preds = model.predict(x)
pred_class = np.argmax(preds[0])
print("Identifikationsergebnis:", pred_class)
print("Wahrscheinlichkeit:", preds[0])

from keras import backend as K
import cv2

#Nehmen Sie die endgültige Ausgabe des Modells heraus
model_output = model.output[:, pred_class]

#Nehmen Sie die letzte Faltungsschicht heraus
last_conv_output = model.get_layer('conv2d_3').output #'block5_conv3').output

#Gradient der Ausgabe der endgültigen Faltungsschicht in Bezug auf die endgültige Ausgabe des Modells
grads = K.gradients(model_output, last_conv_output)[0]
# model.Wenn Sie die Eingabe eingeben, zuletzt_conv_Definieren Sie eine Funktion, die Ausgabe und Noten ausgibt
gradient_function = K.function([model.input], [last_conv_output, grads]) 

#Finden Sie den Farbverlauf des geladenen Bildes
output, grads_val = gradient_function([x])
output, grads_val = output[0], grads_val[0]

#Durchschnittliche Gewichte und Multiplikation mit der Ebenenausgabe, um eine Heatmap zu erstellen
weights = np.mean(grads_val, axis=(0, 1))
heatmap = np.dot(output, weights)

heatmap = cv2.resize(heatmap, (img_rows, img_cols), cv2.INTER_LINEAR)
heatmap = np.maximum(heatmap, 0) 
heatmap = heatmap / heatmap.max()

heatmap = cv2.applyColorMap(np.uint8(255 * heatmap), cv2.COLORMAP_JET)  #Färben Sie die Heatmap
heatmap = cv2.cvtColor(heatmap, cv2.COLOR_BGR2RGB)  #Konvertieren Sie Farbe in RGB

img = plt.imread(filename, cv2.IMREAD_UNCHANGED)
print(img.shape)  # (330, 440, 4)

fig, ax = plt.subplots()
ax.imshow(img)

plt.show()

4. Klassifizierungsergebnis

2020-04-26 21:12:46.904489: I tensorflow/compiler/xla/service/service.cc:168] XLA service 0x7fded852e7f0 initialized for platform Host (this does not guarantee that XLA will be used). Devices:
2020-04-26 21:12:46.904528: I tensorflow/compiler/xla/service/service.cc:176]   StreamExecutor device (0): Host, Default Version
Model: "sequential_1"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_1 (Conv2D)            (None, 222, 222, 32)      896       
_________________________________________________________________
conv2d_2 (Conv2D)            (None, 220, 220, 32)      9248      
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 110, 110, 32)      0         
_________________________________________________________________
conv2d_3 (Conv2D)            (None, 108, 108, 32)      9248      
_________________________________________________________________
max_pooling2d_2 (MaxPooling2 (None, 54, 54, 32)        0         
_________________________________________________________________
dropout_1 (Dropout)          (None, 54, 54, 32)        0         
_________________________________________________________________
flatten_1 (Flatten)          (None, 93312)             0         
_________________________________________________________________
dense_1 (Dense)              (None, 128)               11944064  
_________________________________________________________________
dropout_2 (Dropout)          (None, 128)               0         
_________________________________________________________________
dense_2 (Dense)              (None, 2)                 258       
=================================================================
Total params: 11,963,714
Trainable params: 11,963,714
Non-trainable params: 0
_________________________________________________________________
Identifikationsergebnis: 1
Wahrscheinlichkeit:[0.27252397 0.6845933 ]
(375, 500, 3)

5. Zukünftige Probleme

Es ist notwendig, die Probleme einzugrenzen, um die Genauigkeit zu verbessern.

Recommended Posts

[Bildklassifizierung] Hundegesichtsanalyse
[PyTorch] Bildklassifizierung von CIFAR-10
Analyse des Röntgenmikrotomographiebildes durch Python
[PyTorch] Bildklassifizierung von CIFAR-10
Lernen mit dem Lehrer 1 Grundlagen des Lernens mit dem Lehrer (Klassifizierung)
Üben Sie typische statistische Methoden (1)
Multi-Class Multi-Label-Klassifizierung von Bildern mit Pytorch
Algorithmus für maschinelles Lernen (Implementierung einer Klassifizierung mit mehreren Klassen)
[Bildklassifizierung] Hundegesichtsanalyse
Richter Yosakoi Naruko nach Bildklassifikation von Tensorflow.
Bild der Schließung
[OpenCV / Python] Ich habe versucht, Bilder mit OpenCV zu analysieren
Geschichte der Bildanalyse von PDF-Dateien und Datenextraktion
Grundlagen der Regressionsanalyse