CNN可視化技術總結(二)--卷積核可視化


CNN可視化技術總結(一)-特征圖可視化

CNN可視化技術總結(三)--類可視化

導言:

    上篇文章我們介紹了特征圖可視化方法,對於特征圖可視化的方法(或者說原理)比較容易理解,即把feature map從特征空間通過反卷積網絡映射回像素空間。

    那卷積核怎樣可視化呢,基於什么原理來可視化?卷積核的尺寸一般只有3x3, 5x5大小,如何可視化?本文將介紹這個兩個內容。

 

卷積核可視化的原理

卷積核,在網絡中起到將圖像從像素空間映射到特征空間的作用,可認為是一個映射函數,像素空間中的值經過卷積核后得到響應值,在特征提取網絡中,基本都是使用最大池化來選擇最大響應值進入下一層繼續卷積,其余響應值低的都進入待定。也就是說,我們認定只有響應值大的才會對最終的識別任務起作用。

 

根據這個思路,給定一個已經訓練好的網絡,現在想要可視化某一層的某一個卷積核,我們隨機初始化生成一張圖(指的是對像素值隨機取值,不是數據集中隨機選一張圖),然后經過前向傳播到該層,我們希望這個隨機生成的圖在經過這一層卷積核時,它的響應值能盡可能的大,換句話說,響應值比較大的圖像是這個卷積核比較認可的,是與識別任務更相關的。然后不斷調整圖像像素值,直到響應值足夠大,我們就可以認為此時的圖像就是這個卷積核所認可的,從而達到可視化該卷積核的目的。

 

理解了它的原理后,它的實現方法就比較簡單了,設計一個損失函數,即以經過該層卷積核后的響應值為目標函數,使用梯度上升,更新像素值,使響應值最大。

 

實現代碼

Setup

import numpy as np
import tensorflow as tf
from tensorflow import keras
# The dimensions of our input image
img_width = 180
img_height = 180
# Our target layer: we will visualize the filters from this layer.
# See `model.summary()` for list of layer names, if you want to change this.
layer_name = "conv3_block4_out"

  

Build a feature extraction model

# Build a ResNet50V2 model loaded with pre-trained ImageNet weights
model = keras.applications.ResNet50V2(weights="imagenet", include_top=False)
# Set up a model that returns the activation values for our target layerlayer = model.get_layer(name=layer_name)
feature_extractor = keras.Model(inputs=model.inputs, outputs=layer.output)

  

Set up the gradient ascent process

    loss函數取最大化指定卷積核的響應值的平均值,為了避免邊界的影響,邊界的響應值不計。

def compute_loss(input_image, filter_index):
    activation = feature_extractor(input_image)
    # We avoid border artifacts by only involving non-border pixels in the loss.
    filter_activation = activation[:, 2:-2, 2:-2, filter_index]
    return tf.reduce_mean(filter_activation)

  

@tf.function
def gradient_ascent_step(img, filter_index, learning_rate):
    with tf.GradientTape() as tape:
        tape.watch(img)
        loss = compute_loss(img, filter_index)
    # Compute gradients.
    grads = tape.gradient(loss, img)
    # Normalize gradients.
    grads = tf.math.l2_normalize(grads)
    img += learning_rate * grads
    return loss, img

  

Set up the end-to-end filter visualization loop

def initialize_image():
    # We start from a gray image with some random noise
    img = tf.random.uniform((1, img_width, img_height, 3))
    # ResNet50V2 expects inputs in the range [-1, +1].
    # Here we scale our random inputs to [-0.125, +0.125]
    return (img - 0.5) * 0.25
 
def visualize_filter(filter_index):
    # We run gradient ascent for 20 steps
    iterations = 30
    learning_rate = 10.0
    img = initialize_image()
    for iteration in range(iterations):
        loss, img = gradient_ascent_step(img, filter_index, learning_rate)
 
    # Decode the resulting input image
    img = deprocess_image(img[0].numpy())
    return loss, img
 
def deprocess_image(img):
    # Normalize array: center on 0., ensure variance is 0.15
    img -= img.mean()
    img /= img.std() + 1e-5
    img *= 0.15
 
    # Center crop
    img = img[25:-25, 25:-25, :]
 
    # Clip to [0, 1]
    img += 0.5
    img = np.clip(img, 0, 1)
 
    # Convert to RGB array
    img *= 255
    img = np.clip(img, 0, 255).astype("uint8")
    return img

  

可視化效果圖

可視化vgg16卷積核

圖片

圖片

圖片

圖片

圖片

 

總結:本節內容介紹了一種可視化卷積核的方法,即通過生成指定卷積核響應值盡可能大的圖像來達到可視化卷積核的目的,使用的方法是梯度上升。

 

    在不少論文的末尾都有可視化卷積核來分析提出的模型,該方法值得了解。

 

    下一篇我們將介紹最常用的可視化方法--CAM系列,其作用是給出圖像中對類別識別起作用的區域的熱力圖。

 

代碼與可視化圖的參考鏈接

https://keras.io/examples/vision/visualizing_what_convnets_learn/

https://blog.keras.io/how-convolutional-neural-networks-see-the-world.html

 

本文來源於公眾號《CV技術指南》的技術總結部分,更多相關技術總結請掃描文末二維碼關注公眾號。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM