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