――Dies ist das Ergebnis meiner eigenen Studienaufzeichnung über maschinelles Lernen und tiefes Lernen.
** Schritt 1 Datenkonvertierung, Modellbau und Lernen ** ** Schritt 2 Implementierung von Grad-CAM **
-Dieser Artikel von @T_Tao ** ([Erkennung und Visualisierung abnormaler Teile durch Implementierung von vgg16 und Grad-CAM mit Keras](https: // qiita. Die Implementierung von Grad-CAM wurde unter com / T_Tao / items / 0e869e440067518b6b58)) ** eingeführt.
――Ich möchte den in diesem Artikel eingeführten Code implementieren und weiterhin die Fotodaten des Shiba-Hundes verwenden, um ihn mit Grad-CAM zu visualisieren. Es ist sehr interessant zu sehen, welcher Teil des Bildes eines Hundes als Merkmal angesehen wird, indem man tief lernt, zwischen den beiden zu unterscheiden. ――In der folgenden Implementierung schreiben Sie den Code des Referenzartikels grundsätzlich so, wie er ist. Außerdem werden die in der vorherigen Analyse (2) eingerichteten Daten von Google Drive unverändert verwendet.
Hängen Sie es so ein, dass Sie Daten aus dem Ordner, der das Bild des Shiba-Hundes enthält, in Colab laden können.
#Google Drive-Mount
from google.colab import drive
drive.mount('/content/drive')
Importieren Sie mit dem folgenden Code.
#Bibliothek importieren
from __future__ import print_function
import keras
from keras.applications import VGG16
from keras.models import Sequential, load_model, model_from_json
from keras import models, optimizers, layers
from keras.optimizers import SGD
from keras.layers import Dense, Dropout, Activation, Flatten
from sklearn.model_selection import train_test_split
from PIL import Image
from keras.preprocessing import image as images
from keras.preprocessing.image import array_to_img, img_to_array, load_img
from keras import backend as K
import os
import numpy as np
import glob
import pandas as pd
import cv2
Bis zum letzten Mal habe ich den Image Data Generator von keras verwendet, um Bilddaten zu konvertieren. Verwenden Sie dieses Mal anstelle der Verwendung des Bilddatengenerators den folgenden Code, um die Bilddatei in einen Tensor zu konvertieren.
# cd '/content/drive/'My Drive/'Colab Notebooks'Wechseln Sie in den Arbeitsordner in
%cd '/content/drive/'My Drive/Colab Notebooks/Self_Study/02_mydog_or_otherdogs/
num_classes = 2 #Anzahl der Klassen
folder = ["mydog2", "otherdogs2"] #Ordnername, in dem Fotodaten gespeichert sind
image_size = 312 #Die Größe eines Eingabebildes
x = []
y = []
for index, name in enumerate(folder):
dir = "./original_data/" + name
files = glob.glob(dir + "/*.jpg ")
for i, file in enumerate(files):
image = Image.open(file)
image = image.convert("RGB")
image = image.resize((image_size, image_size))
data = np.asarray(image)
x.append(data)
y.append(index)
#Np, wenn Sie die Liste in ein Numpy-Array konvertieren möchten.array、np.Es gibt zwei Arten, Asarray.
#Wenn Sie eine Kopie des Numpy-Arrays erstellen möchten, np.Array verwenden.
#Wenn Sie eine Kopie erstellen möchten, die mit dem ursprünglichen Numpy-Array synchron bleibt, np.Verwenden Sie Asarray.
x = np.array(x)
y = np.array(y)
Lassen Sie uns überprüfen, wie die Daten konvertiert und in x und y gespeichert werden.
#Überprüfen Sie den Inhalt von x
display(x)
Der Inhalt von x, der die Bilddaten konvertiert hat, wird in die folgende Liste konvertiert.
array([[[[114, 109, 116],
[116, 111, 118],
[104, 99, 105],
...,
[ 37, 38, 30],
[ 37, 38, 30],
[ 36, 37, 29]],
[[117, 112, 119],
[120, 115, 121],
[110, 105, 111],
...,
[ 37, 38, 30],
[ 37, 38, 30],
[ 37, 38, 30]],
[[118, 113, 120],
[121, 116, 122],
[114, 109, 115],
...,
[ 37, 38, 30],
[ 38, 39, 31],
[ 38, 39, 31]],
(Weggelassen)
...,
[[ 60, 56, 53],
[ 60, 56, 53],
[ 61, 57, 54],
...,
[105, 97, 84],
[105, 97, 84],
[104, 96, 83]]]], dtype=uint8)
'\n[[[0, 0, 0],\n [0, 0, 0],\n [0, 0, 0],\n ...,\n [0, 0, 0],\n [0, 0, 0],\n [0, 0, 0]],\n'
Überprüfen Sie den Inhalt von y (Etikett).
#Überprüfen Sie den Inhalt von y
y
y wird mit zwei Arten von Beschriftungen erzeugt, "0" und "1".
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1])
Der konvertierte Tensor wird durch sklearns train_test_split aufgeteilt, um mit dem später erstellten Modell zu trainieren.
#Unterteilt in Zugdaten und Testdaten
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=1)
x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
x_train /= 255
x_test /= 255
#Das y-Label wurde in einen heißen Ausdruck geändert
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)
print(x_train.shape[0], 'train samples')
print(x_test.shape[0], 'test samples')
Sie sollten ein ähnliches Ergebnis sehen:
192 train samples
48 test samples
Erstellen Sie das Modell mit dem folgenden Code. Dieser Optimierer spezifiziert SDG (probabilistische Gradientenabstiegsmethode).
vgg_conv = VGG16(weights='imagenet', include_top=False, input_shape=(image_size, image_size, 3))
last = vgg_conv.output
mod = Flatten()(last)
mod = Dense(1024, activation='relu')(mod)
mod = Dropout(0.5)(mod)
preds = Dense(2, activation='sigmoid')(mod)
model = models.Model(vgg_conv.input, preds)
model.summary()
epochs = 100
batch_size = 48
model.compile(loss='binary_crossentropy',
optimizer=optimizers.SGD(lr=1e-4, momentum=0.9),
metrics=['accuracy'])
Trainiere das Modell.
history = model.fit(x_train, y_train,
batch_size=batch_size,
epochs=epochs,
validation_data=(x_test, y_test),
shuffle=True)
Speichern Sie das Modell.
model.save('mydog_or_otherdogs3(Grad-Cam).h5')
Zeigen Sie das Ergebnis mit dem folgenden Code an und zeichnen Sie ein Diagramm. Das Validierungsergebnis ist wahrscheinlich auch hoch, weil die Bilddatei alle Daten verwendet (240 Blatt).
#Score-Anzeige
scores = model.evaluate(x_test, y_test, verbose=1)
print('Test loss:', scores[0])
print('Test accuracy:', scores[1])
#Genauigkeits- und Verlustdiagramm
import matplotlib.pyplot as plt
acc = history.history["acc"]
val_acc = history.history["val_acc"]
loss = history.history["loss"]
val_loss = history.history["val_loss"]
epochs = range(1, len(acc) + 1)
plt.plot(epochs, acc, label = "Training acc" )
plt.plot(epochs, val_acc, label = "Validation acc")
plt.title("Training and Validation accuracy")
plt.legend()
plt.show()
plt.plot(epochs, loss, label = "Training loss" )
plt.plot(epochs, val_loss, label = "Validation loss")
plt.title("Training and Validation loss")
plt.legend()
plt.show()
Das Ergebnis ist wie folgt.
Test loss: 0.04847167782029327
Test accuracy: 0.9795918367346939
Geben sie den untenstehenden Code ein. Laut @T_Tao ** Grad-CAM mit einem von mir mit Keras erstellten Modell * Dies bedeutet, dass es auf dem Code von * basiert.
K.set_learning_phase(1) #set learning phase
def Grad_Cam(input_model, pic_array, layer_name):
#Vorverarbeitung
pic = np.expand_dims(pic_array, axis=0)
pic = pic.astype('float32')
preprocessed_input = pic / 255.0
#Berechnung der Vorhersageklasse
predictions = input_model.predict(preprocessed_input)
class_idx = np.argmax(predictions[0])
class_output = input_model.output[:, class_idx]
#Steigung bekommen
conv_output = input_model.get_layer(layer_name).output # layer_Ausgabe der Namensschicht
grads = K.gradients(class_output, conv_output)[0] # gradients(loss, variables)Gibt den Gradienten in Bezug auf den Verlust von Variablen zurück
gradient_function = K.function([input_model.input], [conv_output, grads]) # input_model.Wenn Sie eine Eingabe eingeben, wird conv_Funktion zur Ausgabe von Output und Absolventen
output, grads_val = gradient_function([preprocessed_input])
output, grads_val = output[0], grads_val[0]
#Mitteln Sie die Gewichte und multiplizieren Sie sie mit der Ausgabe der Ebene
weights = np.mean(grads_val, axis=(0, 1))
cam = np.dot(output, weights)
#Bild und kombinieren als Heatmap
cam = cv2.resize(cam, (312, 312), cv2.INTER_LINEAR)
cam = np.maximum(cam, 0)
cam = cam / cam.max()
jetcam = cv2.applyColorMap(np.uint8(255 * cam), cv2.COLORMAP_JET) #Pseudofarbige monochrome Bilder
jetcam = cv2.cvtColor(jetcam, cv2.COLOR_BGR2RGB) #Konvertieren Sie Farbe in RGB
jetcam = (np.float32(jetcam) + pic / 2) #Kombiniert mit dem Originalbild
return jetcam
Wenden wir das Ergebnis auf einige Bilder von Shiba-Hunden an. Zuallererst von meinem Hund.
# cd '/content/drive/'My Drive/'Colab Notebooks'Wechseln Sie in den angegebenen Ordner in
%cd '/content/drive/'My Drive/Colab Notebooks/
pic_array = img_to_array(load_img('/content/drive/My Drive/Colab Notebooks/Self_Study/02_mydog_or_otherdogs/original_data/mydog2/mydog1.jpg', target_size=(312, 312)))
pic = pic_array.reshape((1,) + pic_array.shape)
array_to_img(pic_array)
Überlagern Sie die Heatmap
picture = Grad_Cam(model, pic_array, 'block5_conv3')
picture = picture[0,:,:,]
array_to_img(picture)
Ist es so Durch die Visualisierung mit der Heatmap von Grad-CAM wurde gezeichnet, auf welcher Seite das Deep Learning als Merkmal betrachtet wird. Der Teil, in dem die Farbe röter ist, trägt wesentlich zum Verlust der Vorhersageklasse bei (der Teil mit einem großen Gradienten), aber schließlich ist es der Teil, der unter den Augen auf die Nase des Gesichts usw. trifft. Ich fragte mich, ob ich den Teil betrachtete, in dem die Individualität im Gesicht erschien. Ein wenig überraschend ist, dass die Farbe der Wärmekarte zwischen Augen und Ohren (dort?) Dunkler ist.
Ich habe auch ungefähr 2 Bilder von unserem Mirin und ungefähr 3 Bilder von anderen Shiba-Hunden angewendet und sie arrangiert.
Einige Bilder betrachten ähnliche Teile (von den Augen bis zur Nase), während andere völlig andere Teile betrachten, was sehr interessant ist. Ich denke, es scheint eine allgemeine Tendenz für die Merkmale zu geben, aber es kann ein wenig schwierig sein, dies allein mit dieser Heatmap zu erklären.
Dieses Mal haben wir mit Grad-CAM eine Heatmap erstellt. Es scheint verschiedene andere Methoden zur Visualisierung der Feature-Teile zu geben, wie z. B. Grad-CAM ++ und Guided-Grad-CAM. Daher möchte ich ab dem nächsten Mal verschiedene Methoden ausprobieren.
Recommended Posts