Ich habe mir die Feature-Map und Filter im CNN angesehen, die mit dem Subclassing-Modell erstellt wurden.
-Software- Windows 10 Home Anaconda3 64-bit(Python3.7) VSCode -Library- Tensorflow 2.1.0 opencv-python 4.1.2.30 -Hardware- CPU: Intel core i9 9900K GPU: NVIDIA GeForce RTX2080ti RAM: 16GB 3200MHz
Seite? ˅ ・ Keras: Visualisieren Sie CNN mit Fashion-MNIST
Ich werde es auf Github posten. https://github.com/himazin331/CNN-Visualization Das Repository enthält ein Demo-Programm (cnn_visual.py), ein Feature-Map-Visualisierungsmodul (feature_visual.py) und Enthält ein Filtervisualisierungsmodul (filter_visual.py).
Die weniger relevanten Teile werden weggelassen. ** Bitte beachten Sie, dass der Code verschmutzt ist ... **
cnn_visual.py
import argparse as arg
import os
import sys
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2' #TF-Nachricht ausblenden
import tensorflow as tf
import tensorflow.keras.layers as kl
import numpy as np
import matplotlib.pyplot as plt
import feature_visual
import filter_visual
# CNN
class CNN(tf.keras.Model):
def __init__(self, n_out, input_shape):
super().__init__()
self.conv1 = kl.Conv2D(16, 4, activation='relu', input_shape=input_shape)
self.conv2 = kl.Conv2D(32, 4, activation='relu')
self.conv3 = kl.Conv2D(64, 4, activation='relu')
self.mp1 = kl.MaxPool2D((2, 2), padding='same')
self.mp2 = kl.MaxPool2D((2, 2), padding='same')
self.mp3 = kl.MaxPool2D((2, 2), padding='same')
self.flt = kl.Flatten()
self.link = kl.Dense(1024, activation='relu')
self.link_class = kl.Dense(n_out, activation='softmax')
def call(self, x):
h1 = self.mp1(self.conv1(x))
h2 = self.mp2(self.conv2(h1))
h3 = self.mp3(self.conv3(h2))
h4 = self.link(self.flt(h3))
return self.link_class(h4)
#Lernen
class trainer(object):
def __init__(self, n_out, input_shape):
self.model = CNN(n_out, input_shape)
self.model.compile(optimizer=tf.keras.optimizers.Adam(),
loss=tf.keras.losses.SparseCategoricalCrossentropy(),
metrics=['accuracy'])
def train(self, train_img, train_lab, batch_size, epochs, input_shape, test_img):
#Lernen
self.model.fit(train_img, train_lab, batch_size=batch_size, epochs=epochs)
print("___Training finished\n\n")
#Feature-Map-Visualisierung
feature_visual.feature_vi(self.model, input_shape, train_img)
#Filtervisualisierung
filter_visual.filter_vi(self.model)
def main():
"""
Befehlszeilenoptionen
"""
#Datensatzerfassung, Vorverarbeitung
(train_img, train_lab), (test_img, _) = tf.keras.datasets.mnist.load_data()
train_img = tf.convert_to_tensor(train_img, np.float32)
train_img /= 255
train_img = train_img[:, :, :, np.newaxis]
test_img = tf.convert_to_tensor(test_img, np.float32)
test_img /= 255
test_img = train_img[:, :, :, np.newaxis]
#Fang an zu lernen
print("___Start training...")
input_shape = (28, 28, 1)
Trainer = trainer(10, input_shape)
Trainer.train(train_img, train_lab, batch_size=args.batch_size,
epochs=args.epoch, input_shape=input_shape, test_img=test_img)
if __name__ == '__main__':
main()
Dieses Mal wurde ich gebeten, handgeschriebene MNIST-Nummern einzugeben. Das Ergebnis sind 10 Epochen und 256 Mini-Batch-Größen.
** Faltschicht 1 **
** Pooling Schicht 1 **
** Faltschicht 2 **
** Pooling Schicht 2 **
** Faltschicht 1 **
** Faltschicht 2 **
** Faltschicht 3 ** Da das Display klein und schwer zu sehen ist, wird es durch Bearbeiten vergrößert und verkleinert.
Ich werde den zugehörigen Code erklären.
Das Netzwerkmodell ist ein CNN mit der folgenden Struktur.
Netzwerkmodell
# CNN
class CNN(tf.keras.Model):
def __init__(self, n_out, input_shape):
super().__init__()
self.conv1 = kl.Conv2D(16, 4, activation='relu', input_shape=input_shape)
self.conv2 = kl.Conv2D(32, 4, activation='relu')
self.conv3 = kl.Conv2D(64, 4, activation='relu')
self.mp1 = kl.MaxPool2D((2, 2), padding='same')
self.mp2 = kl.MaxPool2D((2, 2), padding='same')
self.mp3 = kl.MaxPool2D((2, 2), padding='same')
self.flt = kl.Flatten()
self.link = kl.Dense(1024, activation='relu')
self.link_class = kl.Dense(n_out, activation='softmax')
def call(self, x):
h1 = self.mp1(self.conv1(x))
h2 = self.mp2(self.conv2(h1))
h3 = self.mp3(self.conv3(h2))
h4 = self.link(self.flt(h3))
return self.link_class(h4)
Die Visualisierung der Feature-Map erfolgt in feature_visual.py.
feature_visual.py
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2' #TF-Nachricht ausblenden
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
#Feature-Map-Visualisierung
def feature_vi(model, input_shape, test_img):
#Modell umbauen
x = tf.keras.Input(shape=input_shape)
model_vi = tf.keras.Model(inputs=x, outputs=model.call(x))
#Netzwerkkonfigurationsausgabe
model_vi.summary()
print("")
#Ebeneninformationen abrufen
feature_vi = []
feature_vi.append(model_vi.get_layer('input_1'))
feature_vi.append(model_vi.get_layer('conv2d'))
feature_vi.append(model_vi.get_layer('max_pooling2d'))
feature_vi.append(model_vi.get_layer('conv2d_1'))
feature_vi.append(model_vi.get_layer('max_pooling2d_1'))
#Zufällige Datenextraktion
idx = int(np.random.randint(0, len(test_img), 1))
img = test_img[idx]
img = img[None, :, :, :]
for i in range(len(feature_vi)-1):
#Feature-Map-Erfassung
feature_model = tf.keras.Model(inputs=feature_vi[0].input, outputs=feature_vi[i+1].output)
feature_map = feature_model.predict(img)
feature_map = feature_map[0]
feature = feature_map.shape[2]
#Definition des Fensternamens
fig = plt.gcf()
fig.canvas.set_window_title(feature_vi[i+1].name + " feature-map visualization")
#Ausgabe
for j in range(feature):
plt.subplots_adjust(wspace=0.4, hspace=0.8)
plt.subplot(feature/6 + 1, 6, j+1)
plt.xticks([])
plt.yticks([])
plt.xlabel(f'filter {j}')
plt.imshow(feature_map[:,:,j])
plt.show()
Sie können das CNN-Klassenmodell nicht so verwenden, wie es ist. Dies liegt daran, dass die Eingabeebene nicht definiert ist. Fügen Sie bei der Implementierung im SubClassing-Modell ** dem Modell eine Eingabeebene hinzu **, wie unten gezeigt.
#Modell umbauen
x = tf.keras.Input(shape=input_shape)
model_vi = tf.keras.Model(inputs=x, outputs=model.call(x))
Bereiten Sie als Nächstes eine Liste vor und ** fügen Sie die Eingabeebene und beliebige Ebeneninformationen zur Liste hinzu **. Dieses Mal möchte ich die Ausgabe der ersten Faltschicht, der ersten maximalen Pooling-Schicht, der zweiten Faltschicht und der zweiten maximalen Pooling-Schicht sehen. Beschreiben Sie wie folgt.
#Ebeneninformationen abrufen
feature_vi = []
feature_vi.append(model_vi.get_layer('input_1'))
feature_vi.append(model_vi.get_layer('conv2d'))
feature_vi.append(model_vi.get_layer('max_pooling2d'))
feature_vi.append(model_vi.get_layer('conv2d_1'))
feature_vi.append(model_vi.get_layer('max_pooling2d_1'))
Bereiten Sie als Nächstes die Eingabedaten vor. Die dem Index entsprechenden Testdaten werden unter Verwendung eines zufälligen numerischen Werts basierend auf einer Zufallszahl als Index erfasst. Da die Form der erfassten Testdaten (28, 28, 1) ist, fügen wir die Dimension der Anzahl der Datenelemente hinzu.
#Zufällige Datenextraktion
idx = int(np.random.randint(0, len(test_img), 1))
img = test_img[idx]
img = img[None, :, :, :]
Erstellen Sie ein Modell feature_model
mit der Eingabe als Eingabeebene und der Ausgabe als Ausgabe jeder Ebene.
Übergeben Sie dann die Eingabedaten mit "Vorhersagen" und erhalten Sie die Ebenenausgabe.
#Feature-Map-Erfassung
feature_model = tf.keras.Model(inputs=feature_vi[0].input, outputs=feature_vi[i+1].output)
feature_map = feature_model.predict(img)
feature_map = feature_map[0]
feature = feature_map.shape[2]
Zeichnen Sie danach die Ebenenausgabe und wiederholen Sie sie wie die nächste Ebenenausgabe.
Die Filtervisualisierung erfolgt in fileter_visual.py.
filter_visual.py
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2' #TF-Nachricht ausblenden
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
#Filtervisualisierung
def filter_vi(model):
vi_layer = []
#Zu visualisierende Ebene
vi_layer.append(model.get_layer('conv2d'))
vi_layer.append(model.get_layer('conv2d_1'))
vi_layer.append(model.get_layer('conv2d_2'))
for i in range(len(vi_layer)):
#Ebenenfilter abrufen
target_layer = vi_layer[i].get_weights()[0]
filter_num = target_layer.shape[3]
#Definition des Fensternamens
fig = plt.gcf()
fig.canvas.set_window_title(vi_layer[i].name + " filter visualization")
#Ausgabe
for j in range(filter_num):
plt.subplots_adjust(wspace=0.4, hspace=0.8)
plt.subplot(filter_num/6 + 1, 6, j+1)
plt.xticks([])
plt.yticks([])
plt.xlabel(f'filter {j}')
plt.imshow(target_layer[ :, :, 0, j], cmap="gray")
plt.show()
Fügen Sie wie bei der Feature-Map-Visualisierung der Liste Faltungsebenen hinzu, die dem gewünschten Filter entsprechen.
vi_layer = []
#Zu visualisierende Ebene
vi_layer.append(model.get_layer('conv2d'))
vi_layer.append(model.get_layer('conv2d_1'))
vi_layer.append(model.get_layer('conv2d_2'))
Holen Sie sich den ** Filter der Zielebene mit get_weights () [0]
**.
Übrigens können Sie die Verzerrung erhalten, indem Sie "get_weights () [1]" schreiben.
Die Form des erhaltenen Filters ist (H, W, I_C, O_C). I_C ist die Anzahl der Eingangskanäle und O_C ist die Anzahl der Ausgangskanäle.
#Ebenenfilter abrufen
target_layer = vi_layer[i].get_weights()[0]
filter_num = target_layer.shape[3]
Geben Sie danach den Filter aus und wiederholen Sie den Vorgang wie beim nächsten Filter.
Ich wollte die Feature-Map und die Filter sehen, habe sie also nachgeschlagen und mit verschiedenen Änderungen implementiert. Die Feature-Map ist interessant anzusehen, aber ich weiß nicht, was der Filter ist, also ist es nicht interessant ~~. In den letzten Jahren scheint es, dass erklärbare KI (KI) Aufmerksamkeit erregt hat, aber ich freue mich auf die Zeit, in der Menschen verstehen können, warum solche Filter sie erkennen können.
Recommended Posts