您的位置 首页 电子

全卷积网络FCN进行图画切割

全卷积网络FCN进行图像分割-CNN能够对图片进行分类,可是怎么样才能识别图片中特定部分的物体,在2015年之前还是一个世界难题。神经网络大神Jonathan Long发表了《Fully Convol

CNN可以对图片进行分类,可是怎样样才干辨认图片中特定部分的物体,在2015年之前仍是一个国际难题。神经网络大神Jonathan Long宣布了《Fully ConvoluTIonal Networks for SemanTIc SegmentaTIon》在图画语义切割挖了一个坑,所以无穷无尽的人往坑里边跳。

全卷积网络 Fully ConvoluTIonal Networks

CNNFCN

一般CNN网络在卷积层之后会接上若干个全衔接层, 将卷积层发生的特征图(feature map)映射成一个固定长度的特征向量。以AlexNet为代表的经典CNN结构适合于图画级的分类和回归使命,由于它们终究都希望得到整个输入图画的一个数值描绘(概率),比方AlexNet的ImageNet模型输出一个1000维的向量表明输入图画归于每一类的概率(softmax归一化)。

栗子:下图中的猫, 输入AlexNet, 得到一个长为1000的输出向量, 表明输入图画归于每一类的概率, 其间在“tabby cat”这一类核算概率最高。

FCN对图画进行像素级的分类,然后处理了语义等级的图画切割(semantic segmentation)问题。与经典的CNN在卷积层之后运用全衔接层得到固定长度的特征向量进行分类(全联接层+softmax输出)不同,FCN可以承受恣意尺度的输入图画,选用反卷积层对终究一个卷积层的feature map进行上采样, 使它康复到输入图画相同的尺度,然后可以对每个像素都发生了一个猜测, 一起保存了原始输入图画中的空间信息, 终究在上采样的特征图上进行逐像素分类。

终究逐一像素核算softmax分类的丢掉, 相当于每一个像素对应一个练习样本。下图是Longjon用于语义切割所选用的全卷积网络(FCN)的结构示意图:

简略的来说,FCN与CNN的区域在把于CNN终究的全衔接层换成卷积层,输出的是一张现已Label好的图片。

其实,CNN的强壮之处在于它的多层结构能主动学习特征,而且可以学习到多个层次的特征:较浅的卷积层感知域较小,学习到一些部分区域的特征;较深的卷积层具有较大的感知域,可以学习到愈加笼统一些的特征。这些笼统特征对物体的巨细、方位和方向等灵敏性更低,然后有助于辨认功能的进步。下图CNN分类网络的示意图:

这些笼统的特征对分类很有协助,可以很好地判别出一幅图画中包括什么类别的物体,可是由于丢掉了一些物体的细节,不能很好地给出物体的详细概括、指出每个像素详细归于哪个物体,因而做到准确的切割就很有难度。

传统的依据CNN的切割办法:为了对一个像素分类,运用该像素周围的一个图画块作为CNN的输入用于练习和猜测。这种办法有几个缺陷:一是存储开支很大。例如对每个像素运用的图画块的巨细为15×15,然后不断滑动窗口,每次滑动的窗口给CNN进行判别分类,因而则所需的存储空间依据滑动窗口的次数和巨细急剧上升。二是核算功率低下。相邻的像素块基本上是重复的,针对每个像素块逐一核算卷积,这种核算也有很大程度上的重复。三是像素块巨细的约束了感知区域的巨细。一般像素块的巨细比整幅图画的巨细小许多,只能提取一些部分的特征,然后导致分类的功能受到约束。

而全卷积网络(FCN)则是从笼统的特征中康复出每个像素所属的类别。即从图画等级的分类进一步延伸到像素等级的分类。

全衔接层 -> 成卷积层

全衔接层和卷积层之间仅有的不同便是卷积层中的神经元只与输入数据中的一个部分区域衔接,而且在卷积列中的神经元同享参数。然而在两类层中,神经元都是核算点积,所以它们的函数方式是相同的。因而,将此两者彼此转化是或许的:

关于任一个卷积层,都存在一个能完结和它相同的前向传达函数的全衔接层。权重矩阵是一个巨大的矩阵,除了某些特定块,其余部分都是零。而在其间大部分块中,元素都是持平的。

相反,任何全衔接层都可以被转化为卷积层。比方,一个 K=4096 的全衔接层,输入数据体的尺度是 7?7?512,这个全衔接层可以被等效地看做一个 F=7,P=0,S=1,K=4096 的卷积层。换句话说,便是将滤波器的尺度设置为和输入数据体的尺度共同了。由于只要一个独自的深度列掩盖并滑过输入数据体,所以输出将变成 1?1?4096,这个成果就和运用初始的那个全衔接层相同了。

全衔接层转化为卷积层:在两种改换中,将全衔接层转化为卷积层在实践运用中愈加有用。假定一个卷积神经网络的输入是 224x224x3 的图画,一系列的卷积层和下采样层将图画数据变为尺度为 7x7x512 的激活数据体。AlexNet运用了两个尺度为4096的全衔接层,终究一个有1000个神经元的全衔接层用于核算分类评分。咱们可以将这3个全衔接层中的恣意一个转化为卷积层:

针对第一个衔接区域是[7x7x512]的全衔接层,令其滤波器尺度为F=7,这样输出数据体就为[1x1x4096]了。

针对第二个全衔接层,令其滤波器尺度为F=1,这样输出数据体为[1x1x4096]。

对终究一个全衔接层也做相似的,令其F=1,终究输出为[1x1x1000]

实践操作中,每次这样的改换都需要把全衔接层的权重W重塑成卷积层的滤波器。那么这样的转化有什么作用呢?它在下面的情况下可以更高效:让卷积网络在一张更大的输入图片上滑动,得到多个输出,这样的转化可以让咱们在单个向前传达的进程中完结上述的操作。

举个栗子:假如咱们想让224×224尺度的浮窗,以步长为32在384×384的图片上滑动,把每个经停的方位都带入卷积网络,终究得到6×6个方位的类别得分。上述的把全衔接层转化成卷积层的做法会更简洁。假如224×224的输入图片经过卷积层和下采样层之后得到了[7x7x512]的数组,那么,384×384的大图片直接经过相同的卷积层和下采样层之后会得到[12x12x512]的数组。然后再经过上面由3个全衔接层转化得到的3个卷积层,终究得到[6x6x1000]的输出((12 – 7)/1 + 1 = 6)。这个成果正是浮窗在原图经停的6×6个方位的得分!

面临384×384的图画,让(含全衔接层)的初始卷积神经网络以32像素的步长独立对图画中的224×224块进行屡次点评,其作用和运用把全衔接层改换为卷积层后的卷积神经网络进行一次前向传达是相同的。
Evaluating the original ConvNet (with FC layers) independently across 224×224 crops of the 384×384 image in strides of 32 pixels gives an identical result to forwarding the converted ConvNet one time.

如下图所示,FCN将传统CNN中的全衔接层转化成卷积层,对应CNN网络FCN把终究三层全衔接层转化成为三层卷积层。在传统的CNN结构中,前5层是卷积层,第6层和第7层别离是一个长度为4096的一维向量,第8层是长度为1000的一维向量,别离对应1000个不同类别的概率。FCN将这3层表明为卷积层,卷积核的巨细 (通道数,宽,高) 别离为 (4096,1,1)、(4096,1,1)、(1000,1,1)。看上去数字上并没有什么不同,可是卷积跟全衔接是不相同的概念和核算进程,运用的是之前CNN现已练习好的权值和偏置,可是不相同的在于权值和偏置是有自己的规模,归于自己的一个卷积核。因而FCN网络中一切的层都是卷积层,故称为全卷积网络。

下图是一个全卷积层,与上图不相同的是图画对应的巨细下标,CNN中输入的图画巨细是赞同固定resize成 227×227 巨细的图画,第一层pooling后为55×55,第二层pooling后图画巨细为27×27,第五层pooling后的图画巨细为13*13。而FCN输入的图画是H*W巨细,第一层pooling后变为原图巨细的1/4,第二层变为原图巨细的1/8,第五层变为原图巨细的1/16,第八层变为原图巨细的1/32(订正:其实真实代码傍边第一层是1/2,以此类推)。

经过屡次卷积和pooling今后,得到的图画越来越小,分辨率越来越低。其间图画到 H/32?W/32 的时分图片是最小的一层时,所发生图叫做heatmap热图,热图便是咱们最重要的高维特征图,得到高维特征的heatmap之后便是最重要的一步也是终究的一步对原图画进行upsampling,把图画进行扩大、扩大、扩大,到原图画的巨细。

终究的输出是1000张heatmap经过upsampling变为原图巨细的图片,为了对每个像素进行分类猜测label成终究现已进行语义切割的图画,这儿有一个小trick,便是终究经过逐一像素地求其在1000张图画该像素方位的最大数值描绘(概率)作为该像素的分类。因而发生了一张现已分类好的图片,如下图右侧有狗狗和猫猫的图。

upsampling

相较于运用被转化前的原始卷积神经网络对一切36个方位进行迭代核算,运用转化后的卷积神经网络进行一次前向传达核算要高效得多,由于36次核算都在同享核算资源。这一技巧在实践中常常运用,一次来取得更好的成果。比方,一般将一张图画尺度变得更大,然后运用改换后的卷积神经网络来对空间上许多不同方位进行点评得到分类评分,然后在求这些分值的平均值。

终究,假如咱们想用步长小于32的浮窗怎样办?用屡次的向前传达就可以处理。比方咱们想用步长为16的浮窗。那么先运用原图在转化后的卷积网络履行向前传达,然后别离沿宽度,沿高度,终究一起沿宽度和高度,把原始图片别离平移16个像素,然后把这些平移之后的图别离带入卷积网络。

如下图所示,当图片在网络中经过处理后变成越小的图片,其特征也越显着,就像图画中色彩所示,当然啦,终究一层的图片不再是一个1个像素的图片,而是原图画 H/32xW/32 巨细的图,这儿为了简化而画成一个像素罢了。

如下图所示,对原图画进行卷积conv1、pool1后原图画缩小为1/2;之后对图画进行第2次conv2、pool2后图画缩小为1/4;接着持续对图画进行第三次卷积操作conv3、pool3缩小为原图画的1/8,此刻保存pool3的featureMap;接着持续对图画进行第四次卷积操作conv4、pool4,缩小为原图画的1/16,保存pool4的featureMap;终究对图画进行第五次卷积操作conv5、pool5,缩小为原图画的1/32,然后把本来CNN操作中的全衔接变成卷积操作conv6、conv7,图画的featureMap数量改动可是图画巨细仍然为原图的1/32,此刻图画不再叫featureMap而是叫heatMap。

现在咱们有1/32尺度的heatMap,1/16尺度的featureMap和1/8尺度的featureMap,1/32尺度的heatMap进行upsampling操作之后,由于这样的操作复原的图片仅仅是conv5中的卷积核中的特征,限于精度问题不可以很好地复原图画傍边的特征,因而在这儿向前迭代。把conv4中的卷积核对上一次upsampling之后的图进行反卷积弥补细节(相当于一个差值进程),终究把conv3中的卷积核对方才upsampling之后的图画进行再次反卷积弥补细节,终究就完结了整个图画的复原。

缺陷

在这儿咱们要注意的是FCN的缺陷:
1、是得到的成果仍是不行精密。进行8倍上采样尽管比32倍的作用好了许多,可是上采样的成果仍是比较含糊和滑润,对图画中的细节不灵敏。

2、是对各个像素进行分类,没有充分考虑像素与像素之间的联系。疏忽了在一般的依据像素分类的切割办法中运用的空间规整(spatial regularization)过程,缺少空间共同性。

实践

输入的图片是:

现在可以直接来点代码吗?
# import package
import numpy as np
from PIL import Image
import caffe

# 初始化地址
caffe_root = fcn.berkeleyvision.org-master/voc-fcn8s/
model_def = caffe_root + deploy.prototxt # 模型文件
model_weights = caffe_root + fcn8s-heavy-pascal.caffemodel #模型权重值
test_image = images/2007_000129.jpg #测验图片

# load image, switch to BGR, subtract mean, and make dims C x H x W for Caffe
im = Image.open(test_image)
in_ = np.array(im, dtype=np.float32)
in_ = in_[:,:,::-1] # change RGB image to BGR image
in_ -= np.array((104.00698793,116.66876762,122.67891434))
in_ = in_.transpose((2,0,1)) # Reshape the image from (500, 334, 3) to (3, 500, 334)

net = caffe.Net(model_def, model_weights, caffe.TEST) #导入模型
net.blobs[data].reshape(1, *in_.shape)
net.blobs[data].data[…] = in_ #读入图画
net.forward() #图片进入前馈卷积神经网络
out = net.blobs[score].data[0].argmax(axis=0) #终究得到的图片

print net.blobs[score].data[0].shape #(21, 500, 334)
print net.blobs[score].data[0].argmax(axis=0)

好了,现已用fcn模型练习网一张图片了,接着便是要看看图片到底是怎样样的楽
import matplotlib.pyplot as plt
# display plots in this notebook
%matplotlib inline

# set display defaults

print out.shape
plt.imshow(out)

输出是:

现在做图片切割的都是依据FCN的升级版、FCN超级升级版,FCN改版、FCN超级改版。。。个人觉得最难的、也是个人正在学习的是从怎样研讨自己的样本,什么样的样本集才干进步终究成果的精度和召回率;有了样本然后怎样给CNN练习,练习后怎样把CNN->FCN,然后到FCN可以对新的数据进行切割。整套流程可以主动化下来就愈加perfect了。

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/qiche/dianzi/183397.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部