[PYTHON] Grad-CAM und erweiterte Faltung

Einführung

Grad-CAM ist eine gute Möglichkeit, um zu visualisieren, wo das Modell bestimmen möchte. Als persönliche Beschwerde hat Grad-CAM jedoch eine niedrige Auflösung von (14,14) im Vergleich zur Bildgröße (224,224). Der Grund, warum die Auflösung von Grad-CAM so niedrig ist, ist, dass das VGG16-Modell insgesamt 4 Pools hat. Mit Ausnahme der Pooling-Ebene können jedoch nur Merkmale des Bildes mit kurzer Reichweite und Merkmale mit großer Reichweite nicht extrahiert werden. Ich fragte mich, ob ich mit erweiterter Faltung ein hochauflösendes Grad-CAM erhalten könnte, also erstellte ich ein äquivalentes Modell von VGG16, das erweiterte Faltung verwendet, und experimentierte. Infolgedessen erhöhte sich die Auflösung von Grad-CAM, kehrte jedoch nicht zur ursprünglichen hohen Auflösung zurück. gradcam.jpg gradcam.jpg Links: Normales Grad-CAM, Rechts: Grad-CAM mit erweiterter Faltung

Was ist erweiterte Faltung?

Wie in der folgenden Abbildung gezeigt, ist dies eine Methode zum Falten eines Filters für fehlende Zähne mit einer Lücke. Wenn Sie dilation_rate erhöhen, können Sie eine lange Strecke mit einer kleinen Filtergröße falten, ohne Pooling zu verwenden. Wenn Sie dies verwenden, wird die Bildgröße nicht reduziert, da kein Pooling verwendet wird. image.png

Modell-

Ich habe unten ein in Keras geschriebenes Modell erstellt. Dieses Modell wird der Einfachheit halber als dilated_VGG16-Modell bezeichnet. Auf diese Weise können Sie Langstreckenwindungen mit der Größe (224.224) berechnen, indem Sie die dilationsrate anpassen. Daher hat die Auflösung vor der vollständigen Kombination die Auflösung von (224,224) anstelle von (14,14). Der Name der letzten Faltungsschicht lautet "Block5_conv3" für späteres Grad-CAM. Beachten Sie, dass das VGG16-Modell und das dilated_VGG16-Modell dieselbe Anzahl von Parametern haben.

python


    inputs = Input(shape=(224,224,3))
    x = Conv2D( 64, (3, 3), padding='same', activation='relu', dilation_rate=1)(inputs)
    x = Conv2D( 64, (3, 3), padding='same', activation='relu', dilation_rate=1)(x)
    x = Conv2D(128, (3, 3), padding='same', activation='relu', dilation_rate=2)(x)
    x = Conv2D(128, (3, 3), padding='same', activation='relu', dilation_rate=2)(x)
    x = Conv2D(256, (3, 3), padding='same', activation='relu', dilation_rate=4)(x)
    x = Conv2D(256, (3, 3), padding='same', activation='relu', dilation_rate=4)(x)
    x = Conv2D(256, (3, 3), padding='same', activation='relu', dilation_rate=4)(x)
    x = Conv2D(512, (3, 3), padding='same', activation='relu', dilation_rate=8)(x)
    x = Conv2D(512, (3, 3), padding='same', activation='relu', dilation_rate=8)(x)
    x = Conv2D(512, (3, 3), padding='same', activation='relu', dilation_rate=8)(x)
    x = Conv2D(512, (3, 3), padding='same', activation='relu', dilation_rate=16)(x)
    x = Conv2D(512, (3, 3), padding='same', activation='relu', dilation_rate=16)(x)
    x = Conv2D(512, (3, 3), padding='same', activation='relu', dilation_rate=16, name='block5_conv3')(x)
    x = MaxPooling2D(pool_size=32)(x)
    x = Flatten()(x)
    x = Dense(4096, activation='relu')(x)
    x = Dense(4096, activation='relu')(x)
    y = Dense(1000, activation='softmax')(x)
    
    model = Model(inputs=inputs, outputs=y)

dilated_VGG16

python


Layer (type)                 Output Shape              Param #
=================================================================
input_1 (InputLayer)         (None, 224, 224, 3)       0
_________________________________________________________________
conv2d_1 (Conv2D)            (None, 224, 224, 64)      1792
_________________________________________________________________
conv2d_2 (Conv2D)            (None, 224, 224, 64)      36928
_________________________________________________________________
conv2d_3 (Conv2D)            (None, 224, 224, 128)     73856
_________________________________________________________________
conv2d_4 (Conv2D)            (None, 224, 224, 128)     147584
_________________________________________________________________
conv2d_5 (Conv2D)            (None, 224, 224, 256)     295168
_________________________________________________________________
conv2d_6 (Conv2D)            (None, 224, 224, 256)     590080
_________________________________________________________________
conv2d_7 (Conv2D)            (None, 224, 224, 256)     590080
_________________________________________________________________
conv2d_8 (Conv2D)            (None, 224, 224, 512)     1180160
_________________________________________________________________
conv2d_9 (Conv2D)            (None, 224, 224, 512)     2359808
_________________________________________________________________
conv2d_10 (Conv2D)           (None, 224, 224, 512)     2359808
_________________________________________________________________
conv2d_11 (Conv2D)           (None, 224, 224, 512)     2359808
_________________________________________________________________
conv2d_12 (Conv2D)           (None, 224, 224, 512)     2359808
_________________________________________________________________
block5_conv3 (Conv2D)        (None, 224, 224, 512)     2359808
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 7, 7, 512)         0
_________________________________________________________________
flatten_1 (Flatten)          (None, 25088)             0
_________________________________________________________________
dense_1 (Dense)              (None, 4096)              102764544
_________________________________________________________________
dense_2 (Dense)              (None, 4096)              16781312
_________________________________________________________________
dense_3 (Dense)              (None, 1000)              4097000
=================================================================
Total params: 138,357,544
Trainable params: 138,357,544
Non-trainable params: 0
_________________________________________________________________

Referenz: VGG16

python


_________________________________________________________________
Layer (type)                 Output Shape              Param #
=================================================================
input_2 (InputLayer)         (None, 224, 224, 3)       0
_________________________________________________________________
block1_conv1 (Conv2D)        (None, 224, 224, 64)      1792
_________________________________________________________________
block1_conv2 (Conv2D)        (None, 224, 224, 64)      36928
_________________________________________________________________
block1_pool (MaxPooling2D)   (None, 112, 112, 64)      0
_________________________________________________________________
block2_conv1 (Conv2D)        (None, 112, 112, 128)     73856
_________________________________________________________________
block2_conv2 (Conv2D)        (None, 112, 112, 128)     147584
_________________________________________________________________
block2_pool (MaxPooling2D)   (None, 56, 56, 128)       0
_________________________________________________________________
block3_conv1 (Conv2D)        (None, 56, 56, 256)       295168
_________________________________________________________________
block3_conv2 (Conv2D)        (None, 56, 56, 256)       590080
_________________________________________________________________
block3_conv3 (Conv2D)        (None, 56, 56, 256)       590080
_________________________________________________________________
block3_pool (MaxPooling2D)   (None, 28, 28, 256)       0
_________________________________________________________________
block4_conv1 (Conv2D)        (None, 28, 28, 512)       1180160
_________________________________________________________________
block4_conv2 (Conv2D)        (None, 28, 28, 512)       2359808
_________________________________________________________________
block4_conv3 (Conv2D)        (None, 28, 28, 512)       2359808
_________________________________________________________________
block4_pool (MaxPooling2D)   (None, 14, 14, 512)       0
_________________________________________________________________
block5_conv1 (Conv2D)        (None, 14, 14, 512)       2359808
_________________________________________________________________
block5_conv2 (Conv2D)        (None, 14, 14, 512)       2359808
_________________________________________________________________
block5_conv3 (Conv2D)        (None, 14, 14, 512)       2359808
_________________________________________________________________
block5_pool (MaxPooling2D)   (None, 7, 7, 512)         0
_________________________________________________________________
flatten (Flatten)            (None, 25088)             0
_________________________________________________________________
fc1 (Dense)                  (None, 4096)              102764544
_________________________________________________________________
fc2 (Dense)                  (None, 4096)              16781312
_________________________________________________________________
predictions (Dense)          (None, 1000)              4097000
=================================================================
Total params: 138,357,544
Trainable params: 138,357,544
Non-trainable params: 0
_________________________________________________________________

Umleitung des VGG16-Gewichts

Das Problem mit dem dilated_VGG16-Modell ist, dass es kein Pooling verwendet, daher ist die Bildgröße groß und das Erlernen dauert sehr lange. Da die Faltzeit der tiefen Schicht ** 16 * 16 = 256 mal ** von VGG16 aus dem Bildverhältnis ergibt, scheint es wahrscheinlich nicht realistisch zu sein, mit diesem Modell zu trainieren. Ich schrieb Folgendes und leitete das Gewicht von VGG16 auf dilated_VGG16 um. Dies ist möglich, weil VGG16 und dilated_VGG16 die gleiche Anzahl von Parametern haben.

python


    model1 = build_dilated_model()
    model2 = VGG16(include_top=True, weights='imagenet')

    model1.set_weights(model2.get_weights())

Klassifizierungsgenauigkeit

Ich habe die übliche Bildklassifizierungsvorhersage mit dilated_VGG16 unter Verwendung von VGG16-Gewichten gemacht. Die Klassifizierungsgenauigkeit wurde mit dilated_VGG16 stark verschlechtert, scheint jedoch etwas effektiv zu sein. cat_dog.png

Vorhersage mit dilated_VGG16 unter Verwendung von VGG16-Gewichten

Model prediction:
        Saint_Bernard   (247)   with probability 0.029
        boxer           (242)   with probability 0.026
        whippet         (172)   with probability 0.020
        tiger_cat       (282)   with probability 0.019
        vacuum          (882)   with probability 0.017

Referenz: Vorhersage mit VGG16

Model prediction:
        boxer           (242)   with probability 0.420
        bull_mastiff    (243)   with probability 0.282
        tiger_cat       (282)   with probability 0.053
        tiger           (292)   with probability 0.050
        Great_Dane      (246)   with probability 0.050

Grad-CAM-Ergebnisse

Ich wurde gebeten, das Grad-CAM-Ergebnis für die Boxer-Vorhersage zu schreiben. Eine normale VGG16 Grad-CAM-Karte hat nur eine Auflösung von (14,14), während dilated_VGG16 eine Auflösung von (224,224) hat. Es trat jedoch ein Gittermuster auf, das keine hohe Auflösung erreichte. gradcam.jpg gradcam.jpg Links: Normales Grad-CAM, Rechts: Grad-CAM mit erweiterter Faltung

Zusammenfassung

Ich fragte mich, ob ich durch eine erweiterte Faltung ein hochauflösendes Grad-CAM erhalten könnte, aber es funktionierte nicht. Als ich suchte, schien es eine Lösung für das Gittermuster der erweiterten Faltung zu geben, und das folgende Papier wurde gefunden. https://www.cs.princeton.edu/~funk/drn.pdf (Ich habe den Inhalt nicht gelesen ...) image.png image.png

Recommended Posts

Grad-CAM und erweiterte Faltung