FCN

原创 2018年04月15日 23:16:05

来源:https://blog.csdn.net/zhyj3038/article/details/71195262

1 实例分割,

对图像中的每一个像素点进行分类,同种物体的不同实例也用不同的类标进行标注,中间是实例分割,右图是语义分割.

2FCN与CNN区别

3CNN中Alexnet的代码:https://blog.csdn.net/akadiao/article/details/78592290?locationNum=10&fps=1

def AlexNet(images, classNum=None, dropoutrate=None):
    parameters = []

    # 卷积层1
    conv1, parameters = convLayer(images, name='conv1', kh=11, kw=11, n_out=64, dh=4, dw=4, p=parameters)
    # 添加LRN层和最大池化层
    # 对conv1进行LRN处理
    lrn1 = tf.nn.lrn(conv1, 4, bias=1.0, alpha=0.001/9, beta=0.75, name='lrn1')
    # 对lrn1进行最大池化处理,池化尺寸3*3,步长2*2,padding模式选VALID即取样不能超过边框
    pool1 = tf.nn.max_pool(lrn1, ksize=[1, 3, 3, 1], strides=[1, 2, 2, 1], padding='VALID', name='pool1')
    # 打印出结果pool1的结构
    print pool1.op.name, ' ', pool1.get_shape().as_list()

    # 卷积层2
    conv2, parameters = convLayer(pool1, name='conv2', kh=5, kw=5, n_out=192, dh=1, dw=1, p=parameters)
    # LRN处理
    lrn2 = tf.nn.lrn(conv2, 4, bias=1.0,alpha=0.001/9, beta=0.75, name='lrn2')
    # 最大池化处理
    pool2 = tf.nn.max_pool(lrn2, ksize=[1, 3, 3, 1], strides=[1, 2, 2, 1], padding='VALID', name='pool2')
    # 打印出结果pool2的结构
    print pool2.op.name, ' ', pool2.get_shape().as_list()

    # 卷积层3
    conv3, parameters = convLayer(pool2, name='conv3', kh=3, kw=3, n_out=384, dh=1, dw=1, p=parameters)

    # 卷积层4
    conv4, parameters = convLayer(conv3, name='conv4', kh=3, kw=3, n_out=256, dh=1, dw=1, p=parameters)

    # 卷积层5
    conv5, parameters = convLayer(conv4, name='conv5', kh=3, kw=3, n_out=256, dh=1, dw=1, p=parameters)
    pool5 = tf.nn.max_pool(conv5, ksize=[1, 3, 3, 1], strides=[1, 2, 2, 1], padding='VALID', name='pool5')
    print pool5.op.name, ' ', pool5.get_shape().as_list()

    fc_in = tf.reshape(pool5, [-1, 256*6*6])
    fc6 = fcLayer(fc_in, 256*6*6, 4096, True, 'fc6')
    dropout6 = tf.nn.dropout(fc6, dropoutrate)

    fc7 = fcLayer(dropout6, 4096, 4096,True, 'fc7')
    dropout7 = tf.nn.dropout(fc7, dropoutrate)

    fc8 = fcLayer(dropout7, 4096, classNum, True, 'fc8')

    return pool5, parameters

FCN网络结构的部分代码,将三个全连接换成了卷积层:
with tf.variable_scope("inference"):
    image_net = vgg_net(weights, processed_image)
    conv_final_layer = image_net["conv5_3"]

    pool5 = utils.max_pool_2x2(conv_final_layer)

    W6 = utils.weight_variable([7, 7, 512, 4096], name="W6")
    b6 = utils.bias_variable([4096], name="b6")
    conv6 = utils.conv2d_basic(pool5, W6, b6)
    relu6 = tf.nn.relu(conv6, name="relu6")
    if FLAGS.debug:
        utils.add_activation_summary(relu6)
        #根据给出的keep_prob参数,将输入tensor x按比例输出。
    relu_dropout6 = tf.nn.dropout(relu6, keep_prob=keep_prob)

    W7 = utils.weight_variable([1, 1, 4096, 4096], name="W7")#图片的尺寸变成1*1,卷积核的数量4096,输出的尺寸就是1*1*4096,最后额
    b7 = utils.bias_variable([4096], name="b7")
    conv7 = utils.conv2d_basic(relu_dropout6, W7, b7)
    relu7 = tf.nn.relu(conv7, name="relu7")
    if FLAGS.debug:
        utils.add_activation_summary(relu7)
    relu_dropout7 = tf.nn.dropout(relu7, keep_prob=keep_prob)

    W8 = utils.weight_variable([1, 1, 4096, NUM_OF_CLASSESS], name="W8")
    b8 = utils.bias_variable([NUM_OF_CLASSESS], name="b8")
    conv8 = utils.conv2d_basic(relu_dropout7, W8, b8)
    # annotation_pred1 = tf.argmax(conv8, dimension=3, name="prediction1")

    # now to upscale to actual image size 现在升级为实际的图像大小
    deconv_shape1 = image_net["pool4"].get_shape()
    W_t1 = utils.weight_variable([4, 4, deconv_shape1[3].value, NUM_OF_CLASSESS], name="W_t1")
    b_t1 = utils.bias_variable([deconv_shape1[3].value], name="b_t1")
    conv_t1 = utils.conv2d_transpose_strided(conv8, W_t1, b_t1, output_shape=tf.shape(image_net["pool4"]))
    fuse_1 = tf.add(conv_t1, image_net["pool4"], name="fuse_1")

    deconv_shape2 = image_net["pool3"].get_shape()
    W_t2 = utils.weight_variable([4, 4, deconv_shape2[3].value, deconv_shape1[3].value], name="W_t2")
    b_t2 = utils.bias_variable([deconv_shape2[3].value], name="b_t2")
    conv_t2 = utils.conv2d_transpose_strided(fuse_1, W_t2, b_t2, output_shape=tf.shape(image_net["pool3"]))
    fuse_2 = tf.add(conv_t2, image_net["pool3"], name="fuse_2")

    shape = tf.shape(image)
    deconv_shape3 = tf.stack([shape[0], shape[1], shape[2], NUM_OF_CLASSESS])
    W_t3 = utils.weight_variable([16, 16, NUM_OF_CLASSESS, deconv_shape2[3].value], name="W_t3")
    b_t3 = utils.bias_variable([NUM_OF_CLASSESS], name="b_t3")
    conv_t3 = utils.conv2d_transpose_strided(fuse_2, W_t3, b_t3, output_shape=deconv_shape3, stride=8)

    annotation_pred = tf.argmax(conv_t3, dimension=3, name="prediction")

return tf.expand_dims(annotation_pred, dim=3), conv_t3
#对conv8此时进行32倍的上采样可以得到原图大小,这个时候得到的结果就是叫做FCN-32s. 
#在FCN-32s的基础上进行fine tuning,把pool4层和conv8的2倍上采样结果相加之后进行一个16倍的上采样,得到的结果是FCN-16s.如conv_t1
#FCN-16s的基础上进行fine tuning,把pool3层和2倍上采样的pool4层和4倍上采样的conv8层加起来,进行一个8倍的上采样,得到的结果就是FCN-8s

4 FCN的优点和缺点:

FCN的优点,能够end-to-end, pixels-to-pixels,而且相比于传统的基于cnn做分割的网络更加高效,因为避免了由于使用像素块而带来的重复存储和计算卷积的问题。

FCN的缺点也很明显,首先是训练比较麻烦,需要训练三次才能够得到FCN-8s,而且得到的结果还是不精细,对图像的细节不够敏感,这是因为在进行decode,也就是恢复原图像大小的过程时,输入上采样层的label map太稀疏,而且上采样过程就是一个简单的deconvolution. 

其次是对各个像素进行分类,没有考虑到像素之间的关系.忽略了在通常的基于像素分类的分割方法中使用的空间规整步骤,缺乏空间一致性.

5 FCN的实施过程中的跳跃连接的理解

  这个结构的作用就在于优化结果,因为如果将全卷积之后的结果直接上采样得到的结果是很粗糙的,所以作者将不同池化层的结果进行上采样之后来优化输出。具体结构如下:


6 U-net:

和FCN相比,结构上比较大的改动在上采样阶段,上采样层也包括了很多层的特征.

还有一个比FCN好的地方在于,Unet只需要一次训练,FCN需要三次训练.



fcn模型训练问题

  • 2017年07月01日 14:48
  • 378KB
  • 下载

FCN 简单梳理

FCN 简单梳理全卷积网络(Fully Convolutional Network)将CNN应用到了图像语义分割领域。 图像语义分割,就是对一张图片上的所有像素点进行分类。以往的CNN都是对整张图片...
  • xg123321123
  • xg123321123
  • 2016-11-09 00:09:09
  • 6681

图像语义分割(1)- FCN

在图像处理领域,图像的分割主要考虑像素灰度的变化,区分不同的前后景。之前的一个系列《图像分割技术(1)》对主流算法做了概述图像的语义分割则不仅是区分每个像素的前后景,更需要将其所属类别预测出来,属于计...
  • zizi7
  • zizi7
  • 2017-08-11 15:12:37
  • 3891

关于FCN代码实现(实践篇)

1.FCN做图像语义分割--测试和训练(matlab) http://blog.csdn.net/zhjm07054115/article/details/51569450 2.使用FCN做图像语义...
  • irlwh
  • irlwh
  • 2016-10-14 15:14:19
  • 6079

新版caffe FCN的使用教程

引言FCN的出现,大幅度改变了近两年来的CNN方向。之前我曾写过caffe版本FCN的使用。最近做实验正好要用到FCN,发现FCN的code已有较大改动。因此,记录一下新版FCN的使用和需要注意的地方...
  • u013059662
  • u013059662
  • 2016-07-07 15:44:10
  • 10858

FCN网络训练 终极版

前言之前写过两个版本的FCN网络训练,一个是基于caffe-future(原博地址),一个是基于官方Caffe的FCN(原博地址)。结果有很多人都咨询一些问题,由于一直有项目和论文的任务,因此一直没有...
  • u013059662
  • u013059662
  • 2016-10-09 20:33:34
  • 21819

使用FCN做图像语义分割(实践篇)

FCN原理原理我已经在上篇博客说过,大家可以参考FCN原理篇代码FCN有官方的代码,具体地址是FCN官方代码 不过我用的不是这个代码,我用的是别人修改官方的版本的代码,使用Chainer框架实现的,...
  • Gavin__Zhou
  • Gavin__Zhou
  • 2016-08-07 15:25:10
  • 31548

fcn训练时网络权重修改文件

  • 2017年11月03日 15:35
  • 2KB
  • 下载

卷积神经网络CNN(3)—— FCN(Fully Convolutional Networks)要点解释

FCN作为图像语义分割的先河,实现像素级别的分类(即end to end,pixel-wise),作者尽量用浅白的方式讲述FCN的原理与过程。...
  • Fate_fjh
  • Fate_fjh
  • 2016-12-03 18:18:08
  • 15875

使用caffe-future完成FCN网络的训练

FCN算是当前最火的一个深度网络了,目的在与解决密集估计(Dense prediction)(例如语义分割/显著性检测等任务)问题。自从去年11月提出之后,就广受欢迎,并且获得了CVPR2015最佳论...
  • u013059662
  • u013059662
  • 2016-07-07 20:44:52
  • 8864
收藏助手
不良信息举报
您举报文章:FCN
举报原因:
原因补充:

(最多只允许输入30个字)