详解FCN模型中每一层的输出及可视化操作

对于FCN模型的搭建以及训练自己的数据集,其实并不是特别难。可以参考FCN训练自己的数据集。可能更多的人想知道FCN每一层输出的结果是什么。这篇博客主要介绍的是对FCN每一层输出进行可视化操作。

  1. 查看FCN总体框架
    先打开工具netcope,如果打不开点击这个netscope然后打开fcn-master2\voc-fcn32s下的train.prototxt文件,将train.prototxt文件内容复制到网页左侧编辑框后,shift+enter,就可以直接显示网络结构。
    在这里插入图片描述
  2. 查看每一层输出的结构
    打开fcn-master2\voc-fcn32s下infer.py文件,在原代码的最后写上如下代码。
for layer_name, blob in net.blobs.iteritems():
    print layer_name + '\t' + str(blob.data.shape)

运行程序,可以看到输出的结果如下

data	(1L, 3L, 375L, 500L)                                       
data_input_0_split_0	(1L, 3L, 375L, 500L)
data_input_0_split_1	(1L, 3L, 375L, 500L)
conv1_1	(1L, 64L, 573L, 698L)                              
conv1_2	(1L, 64L, 573L, 698L)
pool1	(1L, 64L, 287L, 349L)
conv2_1	(1L, 128L, 287L, 349L)
conv2_2	(1L, 128L, 287L, 349L)
pool2	(1L, 128L, 144L, 175L)
conv3_1	(1L, 256L, 144L, 175L)
conv3_2	(1L, 256L, 144L, 175L)
conv3_3	(1L, 256L, 144L, 175L)
pool3	(1L, 256L, 72L, 88L)
conv4_1	(1L, 512L, 72L, 88L)
conv4_2	(1L, 512L, 72L, 88L)
conv4_3	(1L, 512L, 72L, 88L)
pool4	(1L, 512L, 36L, 44L)
conv5_1	(1L, 512L, 36L, 44L)
conv5_2	(1L, 512L, 36L, 44L)
conv5_3	(1L, 512L, 36L, 44L)
pool5	(1L, 512L, 18L, 22L)
fc6	(1L, 4096L, 12L, 16L)
fc7	(1L, 4096L, 12L, 16L)
score_fr	(1L, 5L, 12L, 16L)
upscore	(1L, 5L, 416L, 544L)
score	(1L, 5L, 375L, 500L)

从输出结果可以看出输入的是500 x 375 x 3的图片,第一层卷积后输出的是698 x 573 x 64的特征图。可能有很多人疑惑为什么第一层卷积层分为conv1_1和conv1_2。因为FCN是基于VGG16的结构,VGG16总共是有16层,第一层分为conv1_1和conv1_2因为没有改变图像的大小以及卷积核数,所以两个层合并称为第一层。后面的层数是同样的道理,具体的可以参考博客详解VGG16模型

  1. 可视化数据函数
    在fcn-master2\voc-fcn32s下新建vis_square.py文件,复制代码
# -*- coding: utf-8 -*
####定义辅助函数来进行可视化中间层特征
import numpy as np
from PIL import Image
import scipy.misc
import pylab
import matplotlib.pyplot as plt
def vis_square(data):
    """Take an array of shape (n, height, width) or (n, height, width, 3)
       and visualize each (height, width) thing in a grid of size approx. sqrt(n) by sqrt(n)"""

    # normalize data for display   # 数据正则化
    data = (data - data.min()) / (data.max() - data.min())

    # force the number of filters to be square
    # 此处目的是将一个个滤波器按照正方形的样子排列
    # 先对shape[0]也就是滤波器数量取平方根,然后取大于等于该结果的正整数
    # 比如40个卷积核,则需要7*7的正方形格子(虽然填不满)
    n = int(np.ceil(np.sqrt(data.shape[0])))
    padding = (((0, n ** 2 - data.shape[0]),
               (0, 1), (0, 1))
# add some space between filters # 在相邻的卷积核之间加入0进行padding
               + ((0, 0),) * (data.ndim - 3))
 # don't pad the last dimension (if there is one)   如果最后最后一维是1不进行扩充
    data = np.pad(data, padding, mode='constant', constant_values=1)
 # pad函数声明:pad(array, pad_width, mode, **kwargs),作用是把list在原维度上进行扩展;
    # pad_width是扩充参数,例如参数((3,2),(2,3));
    # 其中(3,2)为水平方向上,上面加3行,下面加2行;
    # (2,3)为垂直方向上,上面加2行,下面加3行;
    # constant是常数填充的意思。# pad with ones (white)

    # tile the filters into an image  # 将卷积核平铺成图片
    data = data.reshape((n, n) + data.shape[1:]).transpose((0, 2, 1, 3) + tuple(range(4, data.ndim + 1)))
    data = data.reshape((n * data.shape[1], n * data.shape[3]) + data.shape[4:])

    plt.imshow(data);pylab.show(); plt.axis('off')

保存退出,这代码的功能是用来显示每一层输出的图像。
然后在infer.py文件上添加模块

import vis_square
import pylab
  1. 可视化第一层卷积核图像

在代码的最后写上如下代码

filters = net.params['conv1_1'][0].data
vis_square.vis_square(filters.transpose(0, 2, 3, 1))

输出的是第一层卷积核模板的图像,这卷积核图像是通过训练模型得出来的。FCN的第一层共有64个卷积核,所以输出的是64个卷积核图像。
在这里插入图片描述

  1. 可视化第一层图像输出
    先将第4步的代码注释,然后在写上如下代码
feat = net.blobs['conv1_1'].data[0, :]
vis_square.vis_square(feat)

输出的结果为下图所示。因为有64个卷积核,所以输出的是64张特征图。
在这里插入图片描述

  1. 可视化第一层池化后的数据图像
    同样先注释第5步的代码,然后在写上如下代码。
feat = net.blobs['pool1'].data[0]
vis_square.vis_square(feat)
  1. 输出第一层图像的数据
    图像就是一组数据组成的,如果想要得出第一层数据的话,可以下上如下代码
print('conv1_1')
print net.blobs['conv1_1'].data[0]

输出的结果为如下图所示。
在这里插入图片描述

  1. 总结
    以上介绍的是第一层图像的可视化操作。如果想要其它层图像可视化操作,只需要修改net.blobs[‘ ’]中每层网络结构的名称即可。如查看第5层数据。代码为
feat = net.blobs['conv5_1'].data[0, :]
vis_square.vis_square(feat)

到此所有的可视化操作已经介绍完了,相信通过对每一层数据的可视化操作,能够更加深刻的理解FCN模型。

  • 5
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

花生米生花@

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

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

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

打赏作者

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

抵扣说明:

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

余额充值