Visualization convolutional network and wherein

Explanatory often said neural network is not strong, i.e. the neural network model is a "black box", it is difficult to learn the way the human experience to be understood that the presentation (trans examples are tree model, strong interpretative). This statement is not entirely correct, convolution neural network learning to "experience" is very suitable for visualization, largely because they are a visual representation of concepts.

Visualization intermediate activation method

Visualization activated intermediate (commonly referred to as the output layer of the activated layer, i.e., the output of the activation function), means for a given input, wherein FIG Display Network layer and the convolution output cell layer.
First, we find a lovely cat Town House ......


9210113-5cca40f706bbfd84.jpg

The image is then read, and processed into a format tensor

from keras.preprocessing import image  # 将图像处理为4D张量形式
import matplotlib.pyplot as plt
import numpy as np
import os
# 忽略硬件加速的警告信息
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
# 获取当前目录地址
FILE_DIR = os.path.dirname(os.path.abspath(__file__))
# 设置图像参数尺寸
target_size = (224, 224, 3)

def path_to_tensor(img_path):
    '''图片格式处理'''
    img = image.load_img(img_path, target_size=target_size)
    img_tensor = image.img_to_array(img)
    img_tensor = np.expand_dims(img_tensor, axis=0).astype('float32')/255
    return img_tensor

if __name__ == '__main__':
    # 读取图片并进行格式处理
    img_path = os.path.join(FILE_DIR, 'cat.jpg')
    img_tensor = path_to_tensor(img_path)

Convolutional network uses keras own VGG16, feature extraction

# 模型初始化
model = vgg16.VGG16(weights='imagenet', include_top=False)
model.summary()

Then extract the intermediate layer output, mainly in two ways

# 采用K.function抽取中间层
layer_1 = K.function([model.layers[0].input], [model.layers[1].output])
layer_2 = K.function([model.layers[0].input], [model.get_layer('block1_conv2').output])   
# 构造一个新模型提取输出
activation_model = Model(inputs=model.layers[0].input, outputs=model.layers[3].output)

feature_maps1 = layer_1([img_tensor])[0]
feature_maps2 = layer_2([img_tensor])[0]
feature_maps3 = activation_model.predict([img_tensor])[0]

#plt.imshow(feature_maps1[0,:,:,3], cmap='viridis')
#plt.imshow(feature_maps2[0,:,:,3], cmap='viridis')
plt.imshow(feature_maps3[:,:,60], cmap='viridis')    # 可以改变数字以切换通道查看不同的特征图
plt.show()
9210113-f8005d4bb99b72e1.png

Next we will activate all channels of the intermediate layer visualization

#-*- coding:utf-8 -*-
from keras import backend as K
from keras.models import Model
from keras.applications import vgg16
from keras.preprocessing import image  # 将图像处理为4D张量形式
import matplotlib.pyplot as plt
import numpy as np
import os
# 忽略硬件加速的警告信息
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
# 获取当前目录地址
FILE_DIR = os.path.dirname(os.path.abspath(__file__))
# 设置图像参数尺寸
target_size = (224, 224, 3)

def path_to_tensor(img_path):
    '''图片格式处理'''
    img = image.load_img(img_path, target_size=target_size)
    img_tensor = image.img_to_array(img)
    img_tensor = np.expand_dims(img_tensor, axis=0).astype('float32')/255
    return img_tensor

if __name__ == '__main__':
    # 读取图片并进行格式处理
    img_path = os.path.join(FILE_DIR, 'cat.jpg')
    img_tensor = path_to_tensor(img_path)

    # 模型初始化
    model = vgg16.VGG16(weights='imagenet', include_top=False)
    # model.summary()

    # 构造一个新模型提取输出
    layer_outputs = [layer.output for layer in model.layers[1:8]]
    activation_model = Model(inputs=[model.layers[0].input], outputs=layer_outputs)
    activations = activation_model.predict([img_tensor])

    layer_names = []
    for layer in model.layers[1:8]:
        layer_names.append(layer.name)

    # 每行显示通道数量
    images_per_row = 16
    
    # 循环打印每一层的特征图
    for layer_name, layer_activation in zip(layer_names, activations):
        print(layer_name)
        print(layer_activation.shape)
        # 特征图中通道个数
        n_features = layer_activation.shape[-1]
        # 特征图形状为(1, width, height, array_len)
        size = layer_activation.shape[1]
        # 将激活通道平铺
        n_cols = n_features // images_per_row  # 需要多少行才能排满

        display_grid = np.zeros((n_cols*size, images_per_row*size))

        for col in range(n_cols):
            for row in range(images_per_row):
                # 定位特征通道
                channel_image = layer_activation[:,:,:,(col*images_per_row+row)]
                # 对特征进行后处理使其更美观
                channel_image -= channel_image.mean()
                channel_image *= 64
                channel_image += 128
                channel_image = np.clip(channel_image, 0, 255).astype('uint8')
                display_grid[col * size : (col + 1) * size, row * size : (row + 1) * size] = channel_image
            
        plt.title(layer_name)
        plt.imshow(display_grid)
        plt.show()
9210113-808f50b21fc62b8a.png
block1_conv1

9210113-3bc18992145f4014.png
block1_conv2

9210113-c3766ee8b94394af.png
block2_conv1

9210113-3ce8c6fefc0134bf.png
block3_conv1

With more and more models, the number of channels to extract more and more features are also more abstract.

Reproduced in: https: //www.jianshu.com/p/255b6be8ccad

Guess you like

Origin blog.csdn.net/weixin_34261739/article/details/91061084