[PYTHON] Selbststudien-Memo "Deep Learning from Grund" (Nr. 18) Eins! Miau! Grad-CAM!

Während ich "Deep Learning von Grund auf neu" lese (geschrieben von Yasuki Saito, veröffentlicht von O'Reilly Japan), werde ich die Websites notieren, auf die ich verwiesen habe. Teil 17 ← → Teil 19

In Google Colaboratory konnte ich bestätigen, dass das Skript des Buches durch Keras ersetzt und ausgeführt werden kann.

damit,

Dieses Mal habe ich beschlossen, Kaggle zwischen Katzen- und Hundedatensätzen unterscheiden zu lassen. Als ich es mit Memo Nr. 6-2 zum Selbststudium gemacht habe, lag die korrekte Antwortrate bei 60%, was etwas besser als das Ergebnis war. Zu diesem Zeitpunkt traten beim Erstellen von Daten häufig Speicherfehler auf, sodass ich die Anzahl der Trainingsdaten reduzierte. Da das neuronale Netz ein zweischichtiges, vollständig verbundenes Netz war, das ich zu diesem Zeitpunkt verstehen konnte, habe ich es in eine Dimension konvertiert. tat. In Memo 12 zum Selbststudium habe ich versucht, mit einem Faltungsnetz zu verarbeiten, konnte jedoch aufgrund eines Speicherfehlers nicht richtig lernen und die richtige Antwortrate betrug 50%. Und das gleiche Niveau wie die Adresse.

Dieses Mal werde ich das Faltungs-Neuronale Netz erneut versuchen, ohne mir Gedanken über den Speicherfehler in Google Colaboratory zu machen.

Laden Sie Fotos auf Google Drive hoch

Die Daten für Katzen und Hunde betragen jeweils ca. 400 MB, und in My Drive befinden sich einige Gigabyte freier Speicherplatz, sodass die Kapazität kein Problem darstellt. Als ich jedoch versuchte, dies für jeden Ordner hochzuladen, dauerte es zu lange und es kam zu einer Zeitüberschreitung. Da sich 12500 Dateien in einem Ordner befinden, liegt möglicherweise ein Problem mit der Anzahl der Dateien vor, aber der Hundeordner wurde in der Mitte angehalten, aber der Katzenordner kann alle hochgeladen werden, sodass ich die Ursache nicht gut verstehe. Es kann nicht geholfen werden, da es lange gedauert hat, weil die Leitung besetzt war, die Auslastung des Servers hoch war und die Umstände zu diesem Zeitpunkt.

Wird der Colab-Bildschirm eine Zeitüberschreitung aufweisen, wenn er längere Zeit unbeaufsichtigt bleibt?

Es wurde gesagt, dass, wenn Sie das Skript für längere Zeit laufen lassen und den Bildschirm nicht bedienen, eine Zeitüberschreitung auftritt, sodass der Prozess der Bildformung in Hunde und Katzen unterteilt und separat gespeichert wird Ich habe es in zusammengefasst.

Ich habe das Bild auf die gleiche Weise verarbeitet wie in Memo 12 zum Selbststudium, aber Memo 12 zum Selbststudium waren die Daten für DeepConvNet des Buches. , Channels_first (Stapel, Kanäle, Höhe, Breite) wurde durch Transponieren so verarbeitet, dass es im Format vorliegt. Keras hat das Format canal_last (Stapel, Höhe, Breite, Kanäle), sodass es ohne Transponierung gespeichert wird.

Ich habe versucht, mit der zuletzt erstellten Keras-Version von DeepConvNet zu lernen

#Vorbereitung der Eingabedaten
from google.colab import drive
drive.mount('/content/drive')

import os
import pickle

mnist_file = '/content/drive/My Drive/Colab Notebooks/deep_learning/dataset/catdog.pkl'
with open(mnist_file, 'rb') as f:
    dataset = pickle.load(f)

x_train = dataset['train_img']  / 255.0 #Es ist normalisiert.
t_train = dataset['train_label']
x_test  = dataset['test_img'] / 255.0
t_test  = dataset['test_label']

print(x_train.shape)

(23411, 80, 80, 3)

Die Bilddaten sind ein ganzzahliger Wert von 0 bis 255, der jedoch durch 255,0 geteilt und so konvertiert wird, dass er in den Bereich von 0,0 bis 1,0 fällt. Dies beschleunigte das Lernen. Ohne Normalisierung erreichte die korrekte Antwortrate auch nach 5 Epochen nicht 60%, aber nach der Normalisierung lag sie beim 4. Mal über 60%.

#TensorFlow und tf.Keras importieren
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
from keras.layers import Dense, Activation, Flatten, Conv2D, MaxPooling2D, Dropout

#Hilfsbibliothek importieren
import numpy as np
import matplotlib.pyplot as plt

def create_model(input_shape, output_size, hidden_size):
  import numpy as np
  import matplotlib.pyplot as plt
  
  filter_num = 16
  filter_size = 3
  filter_stride = 1
  filter_num2 = 32
  filter_num3 = 64
  pool_size_h=2
  pool_size_w=2
  pool_stride=2

  model = keras.Sequential(name="DeepConvNet")
  model.add(keras.Input(shape=input_shape))
  model.add(Conv2D(filter_num, filter_size, strides=filter_stride, padding="same", activation="relu", kernel_initializer='he_normal'))
  model.add(Conv2D(filter_num, filter_size, strides=filter_stride, padding="same", activation="relu", kernel_initializer='he_normal'))
  model.add(MaxPooling2D(pool_size=(pool_size_h, pool_size_w),strides=pool_stride))

  model.add(Conv2D(filter_num2, filter_size, strides=filter_stride, padding="same", activation="relu", kernel_initializer='he_normal'))
  model.add(Conv2D(filter_num2, filter_size, strides=filter_stride, padding="same", activation="relu", kernel_initializer='he_normal'))
  model.add(MaxPooling2D(pool_size=(pool_size_h, pool_size_w),strides=pool_stride))

  model.add(Conv2D(filter_num3, filter_size, strides=filter_stride, padding="same", activation="relu", kernel_initializer='he_normal'))
  model.add(Conv2D(filter_num3, filter_size, strides=filter_stride, padding="same", activation="relu", kernel_initializer='he_normal'))
  model.add(MaxPooling2D(pool_size=(pool_size_h, pool_size_w),strides=pool_stride))

  model.add(keras.layers.Flatten())
  model.add(Dense(hidden_size, activation="relu", kernel_initializer='he_normal')) 
  model.add(Dropout(0.5))
  model.add(Dense(output_size))
  model.add(Dropout(0.5))
  model.add(Activation("softmax")) 

  #Modell kompilieren
  model.compile(loss="sparse_categorical_crossentropy", 
                optimizer="adam", 
                metrics=["accuracy"])

  return model

input_shape=(80,80,3)
output_size=2
hidden_size=100
model = create_model(input_shape, output_size, hidden_size)

model.summary()

Model: "DeepConvNet" Layer (type)          Output Shape      Param #


conv2d (Conv2D)        (None, 80, 80, 16)     448
conv2d_1 (Conv2D)       (None, 80, 80, 16)     2320
max_pooling2d (MaxPooling2D) (None, 40, 40, 16)     0
conv2d_2 (Conv2D)       (None, 40, 40, 32)     4640
conv2d_3 (Conv2D)       (None, 40, 40, 32)     9248
max_pooling2d_1 (MaxPooling2 (None, 20, 20, 32)     0
conv2d_4 (Conv2D)       (None, 20, 20, 64)     18496
conv2d_5 (Conv2D)       (None, 20, 20, 64)     36928
max_pooling2d_2 (MaxPooling2 (None, 10, 10, 64)     0
flatten (Flatten)        (None, 6400)        0
dense (Dense)          (None, 100)        640100
dropout (Dropout)        (None, 100)        0
dense_1 (Dense)         (None, 2)         202
dropout_1 (Dropout)       (None, 2)          0
activation (Activation)     (None, 2)          0


Total params: 712,382 Trainable params: 712,382 Non-trainable params: 0

Mit Ausnahme von input_shape und output_size entspricht dies dem in Teil 17 erstellten Skript.

model.fit(x_train, t_train,  epochs=10, batch_size=128)
test_loss, test_acc = model.evaluate(x_test,  t_test, verbose=2)

Epoch 1/10 195/195 [==============================] - 385s 2s/step - loss: 0.7018 - accuracy: 0.5456 Epoch 2/10 195/195 [==============================] - 385s 2s/step - loss: 0.6602 - accuracy: 0.5902 Epoch 3/10 195/195 [==============================] - 383s 2s/step - loss: 0.6178 - accuracy: 0.6464 Epoch 4/10 195/195 [==============================] - 383s 2s/step - loss: 0.5844 - accuracy: 0.6759 Epoch 5/10 195/195 [==============================] - 383s 2s/step - loss: 0.5399 - accuracy: 0.7090 Epoch 6/10 195/195 [==============================] - 383s 2s/step - loss: 0.5001 - accuracy: 0.7278 Epoch 7/10 195/195 [==============================] - 382s 2s/step - loss: 0.4676 - accuracy: 0.7513 Epoch 8/10 195/195 [==============================] - 382s 2s/step - loss: 0.4485 - accuracy: 0.7611 Epoch 9/10 195/195 [==============================] - 380s 2s/step - loss: 0.4295 - accuracy: 0.7713 Epoch 10/10 195/195 [==============================] - 382s 2s/step - loss: 0.4099 - accuracy: 0.7788 4/4 - 0s - loss: 0.3249 - accuracy: 0.8500

Die richtige Antwortrate beträgt 85%. Ich habe versucht, das Ergebnis des Urteils anzuzeigen.

#Vorhersagen
predictions = model.predict(x_test)

def plot_image(i, predictions_array, t_label, img):
    class_names = ['cat', 'dog']
    predictions_array = predictions_array[i]
    img = img[i].reshape((80, 80, 3))
    true_label = t_label[i]
    plt.grid(False)
    plt.xticks([])
    plt.yticks([])
    plt.imshow(img, cmap=plt.cm.binary)

    predicted_label = np.argmax(predictions_array)
    if predicted_label == true_label:
        color = 'blue'
    else:
        color = 'red'

    plt.xlabel("{} {:2.0f}% ({})".format(class_names[predicted_label],
                                    100*np.max(predictions_array),
                                    class_names[true_label]),
                                    color=color)

#Zeigt X Testbilder, vorhergesagte Beschriftungen und korrekte Beschriftungen an.
#Richtige Vorhersagen werden blau und falsche Vorhersagen rot angezeigt.
num_rows = 10
num_cols = 10
num_images = num_rows*num_cols

plt.figure(figsize=(2*num_cols, 2.5*num_rows))
for i in range(num_images):
    plt.subplot(num_rows, num_cols, i+1)
    plot_image(i, predictions, t_test, x_test)
plt.show()

k-18-1.jpg k-18-2.jpg k-18-3.jpg

Neun Fälle verwechselten Katzen mit Hunden und sechs Fälle verwechselten Hunde mit Katzen. Wenn Ihr Gesicht groß ist und geradeaus zeigt, scheint es keinen Fehler zu geben. Sie können sich irren, seitwärts zu sein oder ein kleines Gesicht zu haben. Ist es ein Punkt, dass alle Katzen dreieckige Ohren haben und viele Hunde tropfende Ohren haben?

Indem ich sage

Ich wollte wissen, worauf ich im Bild geachtet habe, also entschied ich mich, GRAD-CAM zu verwenden, um es zu sehen.

Grad-CAM Gradientengewichtete Klassenaktivierungszuordnung (Grad-CAM) Es scheint eine gradientengewichtete Klassenaktivierungszuordnungsmethode zu sein. Ist es okay mit Gradcam?

Der Gradient kam in der Verlustfunktion heraus, aber es scheint, dass der Gradient den größten Einfluss auf die Klassifizierung hat, je größer der Gradient ist. Ich werde es aufgeben, weiter zu verfolgen, das Programm ausführen und nur die Ergebnisse sehen.

Das Programm zur Grad-CAM-Berechnung finden Sie hier. → Ich habe Grad-CAM mit Keras und Tensorflow implementiert

import numpy as np
import cv2

#Für die Grad-CAM-Berechnung
from tensorflow.keras import models
import tensorflow as tf

def grad_cam(input_model, x, layer_name):
    """
    Args: 
        input_model(object):Modellobjekt
        x(ndarray):Bild
        layer_name(string):Der Name der Faltungsschicht
    Returns:
        output_image(ndarray):Farbiges Bild des Originalbildes
    """

    #Bildvorverarbeitung
    #Da nur ein Bild gelesen werden muss, muss der Modus erhöht werden..Ich kann es nicht vorhersagen
    h, w, c = x.shape
    IMAGE_SIZE = (h, w)
    X = np.expand_dims(x, axis=0)
    preprocessed_input = X.astype('float32') / 255.0 

    grad_model = models.Model([input_model.inputs], [input_model.get_layer(layer_name).output, input_model.output])

    with tf.GradientTape() as tape:
        conv_outputs, predictions = grad_model(preprocessed_input)
        class_idx = np.argmax(predictions[0])
        loss = predictions[:, class_idx]

    #Berechnen Sie den Gradienten
    output = conv_outputs[0]
    grads = tape.gradient(loss, conv_outputs)[0]

    gate_f = tf.cast(output > 0, 'float32')
    gate_r = tf.cast(grads > 0, 'float32')

    guided_grads = gate_f * gate_r * grads

    #Mitteln Sie die Gewichte und multiplizieren Sie sie mit der Ausgabe der Ebene
    weights = np.mean(guided_grads, axis=(0, 1))
    cam = np.dot(output, weights)

    #Skalieren Sie das Bild auf die gleiche Größe wie das Originalbild
    cam = cv2.resize(cam, IMAGE_SIZE, cv2.INTER_LINEAR)
    #Anstelle von ReLU
    cam  = np.maximum(cam, 0)
    #Wärmekarte berechnen
    heatmap = cam / cam.max()

    #Pseudofarbige monochrome Bilder
    jet_cam = cv2.applyColorMap(np.uint8(255.0*heatmap), cv2.COLORMAP_JET)
    #In RGB konvertieren
    rgb_cam = cv2.cvtColor(jet_cam, cv2.COLOR_BGR2RGB)
    #Kombiniert mit dem Originalbild
    output_image = (np.float32(rgb_cam) / 2  + x / 2 )  
    return output_image , rgb_cam
from keras.preprocessing.image import array_to_img, img_to_array, load_img

predictions = model.predict(x_test)

def hantei_hyouji(i, x_test, t_test, predictions, model):
  class_names = ['cat', 'dog']

  x = x_test[i]
  true_label = t_test[i]
  predictions_array = predictions[i]
  predicted_label = np.argmax(predictions_array)

  target_layer = 'conv2d_5'
  cam, heatmap = grad_cam(model, x, target_layer)

  moto=array_to_img(x, scale=True)
  hantei=array_to_img(heatmap, scale=True)
  hyouji=array_to_img(cam, scale=True)

  print("{} {:2.0f}% ({})".format(class_names[predicted_label],
                                  100*np.max(predictions_array),
                                  class_names[true_label]))
  row = 1
  col = 3
  plt.figure(figsize=(15,15))
  plt.subplot(row, col, 1)
  plt.imshow(moto)
  plt.axis('off')
  plt.subplot(row, col, 2)
  plt.imshow(hantei)
  plt.axis('off')
  plt.subplot(row, col, 3)
  plt.axis('off')
  plt.imshow(hyouji)

  plt.show()
  return

for i in range(100):
    hantei_hyouji(i, dataset['test_img'], t_test, predictions, model)

Und das Ergebnis ist

k-18-4.jpg k-18-5.jpg k-18-6.jpg k-18-7.jpg k-18-8.jpg k-18-9.jpg

Wenn es um Katzen geht, ist es anscheinend so, als würde man die Muster und Formen des Körpers betrachten, nicht die Ohren oder Augen. Hunde scheinen mehr auf ihre Gesichter zu achten, besonders auf ihre Nasen. Im ersten Bildbeispiel achten wir auf die Körperform, aber da wir dem Gesicht mehr Aufmerksamkeit schenken, wird es als Hund mit einem kleinen Rand falsch eingeschätzt. Im letzten Bildbeispiel scheint er, während er auf die Nase achtete, sie als Katze falsch zu identifizieren, indem er auf seine Körperform achtete. Wahrscheinlich ist sein Rücken abgerundet. Im zweiten Beispiel achten Sie mehr auf die Umgebung als auf die Katze selbst, und wahrscheinlich haben Sie entschieden, dass es sich um eine Katze handelt, weil Sie die Nase oder die Eigenschaften des Hundes überhaupt nicht sehen können.

Referenzseite

Ich habe Grad-CAM mit Keras und Tensorflow implementiert

Ich werde den Quellcode von Grad-CAM und Guided Grad-CAM erläutern

Teil 17 ← → Teil 19 Klicken Sie hier, um eine Liste der Memos usw. anzuzeigen. Unlesbares Glossar

Recommended Posts

Selbststudien-Memo "Deep Learning from Grund" (Nr. 18) Eins! Miau! Grad-CAM!
"Deep Learning from Grund" Memo zum Selbststudium (Nr. 11) CNN
"Deep Learning from Grund" Memo zum Selbststudium (Nr. 19) Datenerweiterung
"Deep Learning from Grund" Memo zum Selbststudium (Teil 12) Deep Learning
Selbststudien-Memo "Deep Learning from Grund" (Nr. 15) TensorFlow-Anfänger-Tutorial
Selbststudien-Memo "Deep Learning from Grund" (unlesbares Glossar)
"Deep Learning from Grund" Memo zum Selbststudium (Nr. 9) MultiLayerNet-Klasse
Selbststudien-Memo "Deep Learning from Grund" (Nr. 13) Verwenden Sie Google Colaboratory
"Deep Learning from Grund" Memo zum Selbststudium (10) MultiLayerNet-Klasse
"Deep Learning from Grund" Memo zum Selbststudium (Nr. 10-2) Anfangswert des Gewichts
[Lernnotiz] Deep Learning von Grund auf neu gemacht [Kapitel 7]
Deep Learning / Deep Learning von Grund auf neu Kapitel 6 Memo
[Lernnotiz] Deep Learning von Grund auf neu gemacht [Kapitel 5]
Deep Learning / Deep Learning von Grund auf neu Kapitel 7 Memo
[Lernnotiz] Deep Learning von Grund auf neu gemacht [~ Kapitel 4]
"Deep Learning from Grund" Memo zum Selbststudium (Nr. 16) Ich habe versucht, SimpleConvNet mit Keras zu erstellen
"Deep Learning from Grund" Memo zum Selbststudium (Nr. 17) Ich habe versucht, DeepConvNet mit Keras zu erstellen
Deep Learning von Grund auf neu
"Deep Learning from Grund" Memo zum Selbststudium (Nr. 14) Führen Sie das Programm in Kapitel 4 in Google Colaboratory aus
Deep Learning von Grund auf neu Kapitel 2 Perceptron (Memo lesen)
[Lernnotiz] Deep Learning von Grund auf ~ Implementierung von Dropout ~
Deep Learning von Grund auf 1-3 Kapitel
Deep Learning / Deep Learning von Grund auf neu 2 Kapitel 4 Memo
Deep Learning / Deep Learning von Grund auf neu Kapitel 3 Memo
Deep Learning / Deep Learning von Null 2 Kapitel 5 Memo
Deep Learning / Deep Learning von Null 2 Kapitel 7 Memo
Deep Learning / Deep Learning von Null 2 Kapitel 8 Memo
Deep Learning / Deep Learning von Grund auf neu Kapitel 5 Memo
Deep Learning / Deep Learning von Grund auf neu Kapitel 4 Memo
Deep Learning / Deep Learning von Grund auf neu 2 Kapitel 3 Memo
Deep Learning Memo von Grund auf neu gemacht
Deep Learning / Deep Learning von Null 2 Kapitel 6 Memo
"Deep Learning from Grund" Memo zum Selbststudium (Teil 8) Ich habe die Grafik in Kapitel 6 mit matplotlib gezeichnet
Warum ModuleNotFoundError: In "Deep Learning from Grund" wird kein Modul mit dem Namen "didaset.mnist" angezeigt.
Tiefes Lernen von Grund auf neu (Vorwärtsausbreitung)
Tiefes Lernen / Tiefes Lernen von Grund auf 2-Versuchen Sie, GRU zu bewegen
"Deep Learning von Grund auf neu" mit Haskell (unvollendet)
[Windows 10] Aufbau einer "Deep Learning from Scratch" -Umgebung
Lernbericht über das Lesen von "Deep Learning von Grund auf neu"
[Deep Learning von Grund auf neu] Über die Optimierung von Hyperparametern
GitHub des guten Buches "Deep Learning von Grund auf neu"
Python vs Ruby "Deep Learning von Grund auf neu" Zusammenfassung
Django Memo # 1 von Grund auf neu
Anwendung von Deep Learning 2 von Grund auf neu Spam-Filter
Ich habe versucht, Dropout zu erklären
[Deep Learning von Grund auf neu] Implementierung der Momentum-Methode und der AdaGrad-Methode
Ein Amateur stolperte in Deep Learning von Grund auf neu Hinweis: Kapitel 1
Ein Amateur stolperte über Deep Learning ❷ von Grund auf neu Hinweis: Kapitel 5
Ein Amateur stolperte über Deep Learning ❷ von Grund auf neu Hinweis: Kapitel 2
Deep Learning / LSTM Scratch Code
Ein Amateur stolperte in Deep Learning von Grund auf neu Hinweis: Kapitel 3
Ein Amateur stolperte in Deep Learning von Grund auf neu. Hinweis: Kapitel 7
Ein Amateur stolperte in Deep Learning von Grund auf neu Hinweis: Kapitel 5
Ein Amateur stolperte über Deep Learning ❷ von Grund auf neu Hinweis: Kapitel 1
Ein Amateur stolperte über Deep Learning ❷ von Grund auf neu Hinweis: Kapitel 4
Ein Memo bei der Ausführung des Beispielcodes von Deep Learning, der mit Google Colaboratory von Grund auf neu erstellt wurde
Ein Amateur stolperte in Deep Learning von Grund auf neu Hinweis: Kapitel 4
Ein Amateur stolperte in Deep Learning von Grund auf neu Hinweis: Kapitel 2