深度学习课程--CNN--feature maps的visualization

一直很好奇,CNN的N个feature maps出来的图像是怎样的图像;是怎么提取原始图像的特征。虽然知道 features map,也就是特征图,理应是跟原始图像的某一部分相似,才能有效地提取出原始图像的特征,也就是之前CNN理解文章里面关于老鼠的介绍,要提取老鼠的某一个身体形状,对应的特征图,必定是跟老鼠形状相似的特征图,才能提取处出来。即当filter和我们的原始图像的对应部分越像,它们卷积的结果就会越大,因此输出的像素点就越亮

所以这次将会试着把原始图的几个layers的所有特征图可视化。看看CNN网络是怎么提取特征。

(1)提取VGG pretrain模型

vgg = tf.keras.applications.VGG19(include_top=False, weights='imagenet') 
vgg.trainable = False

#打印所有的layers
for layer in vgg.layers:
  print(layer.name)

在这里插入图片描述
我们将会提取 以下五层的layers的features map作为一个演示

#直接提取VGG的layers
layers = [vgg.get_layer('block1_conv1'),
		  vgg.get_layer('block2_conv1'),
		  vgg.get_layer('block3_conv1'),
		  vgg.get_layer('block4_conv1'),
		  vgg.get_layer('block5_conv1')]
#创建模型,将会输出五个layers的output,即feature maps
outputs= [layer.output for layer in layers]
model = tf.keras.Model([vgg.input], outputs)

(2)可视化

def plot_convolutional_filters(img):
    
    img = np.expand_dims(img, axis=0)   #多加一个维度
    pred = model.predict(img)           #应该会输出五个layers的predict的feature maps
    images_per_row = 8
    
    for layer_name, layer_pred in zip(layer_names, pred): 
        n_features = layer_pred.shape[-1]        #features 数
        size = layer_pred.shape[1]               #应该是 5 ,因为有5个layers
        n_cols = n_features // images_per_row    #
        display_grid = np.zeros((size * n_cols, images_per_row * size))
        for col in range(n_cols): 
            for row in range(images_per_row):
                channel_image = layer_pred[0,:, :, col * images_per_row + row]
                #===============================================================
                #normalize image 
                channel_image -= channel_image.mean()
                channel_image /= channel_image.std()
                #range between 0,1
                #===============================================================
                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
        scale = 1. / size
        plt.figure(figsize=(scale * display_grid.shape[1],
                            scale * display_grid.shape[0]))
        plt.title(layer_name)
        plt.grid(False)
        plt.imshow(display_grid, aspect='auto',cmap='gray')

原始图片为:

def image_process(path):
  image = Image.open(path).convert('RGB')
  image = image.resize((657,657))
  image = np.array(image)/255
  return image 
content_path = tf.keras.utils.get_file('YellowLabradorLooking_new.jpg', 'https://storage.googleapis.com/download.tensorflow.org/example_images/YellowLabradorLooking_new.jpg')
img = image_process(content_path)
plt.imshow(img)

在这里插入图片描述

它的filters 可视化的结果如下 :
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

(3)总结解释

首先,仔细观察block1_conv1层的特征图
在这里插入图片描述
我们可以看得出,这一层,主要是做边缘检测,即狗狗的大小,而且也有颜色的区分,这一层在努力把狗的颜色给识别出来。 当我们看到block2_conv1出来的图像,这里几乎完全都是形状的捕捉。所以浅层做的主要是边缘识别,颜色识别等等特征。

而深层的特征图,因为经过反复的卷积,这里的特征图大小会缩小,越来越“像素化,因此这里的特征图对应的都是原始图片的一个细节,一个特征,所以特征图出来的都是某一个部位特别发白(因为我用了gray的颜色),所以发亮就是发白。 所以深层可以激活图片的显著特征,比如狗狗的手脚,后面的草坪等等特征。

随着CNN的层数增加,每一层的输出图像越来越抽象复杂,因此可以推断,随着CNN的深入,网络层学得的特征越来越高级和复杂。

========================end

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jianafeng

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值