昇思MindSpore学习总结九——FCN语义分割

1、语义分割

        图像语义分割(semantic segmentation)是图像处理和机器视觉技术中关于图像理解的重要一环,AI领域中一个重要分支,常被应用于人脸识别、物体检测、医学影像、卫星图像分析、自动驾驶感知等领域。

        语义分割的目的是对图像中每个像素点进行分类。 要识别出整张图片的每个部分,就意味着要精确到像素点,所以语义分割实际上是对图像中每一个像素点进行分类,确定每个点的类别(如属于背景、人、汽车、马等),从而进行区域划分。

        与普通的分类任务只输出某个类别不同,语义分割任务输出与输入大小相同的图像,输出图像的每个像素对应了输入图像每个像素的类别。语义在图像领域指的是图像的内容,对图片意思的理解,下图是一些语义分割的实例:

2、全卷积网络

        全卷积网络(Fully Convolutional Networks,FCN)是UC Berkeley的Jonathan Long等人于2015年在Fully Convolutional Networks for Semantic Segmentation[1]一文中提出的用于图像语义分割的一种框架。

核心思想:

1.不含全连接层(fc)的全卷积(fully conv)网络。可适应任意尺寸输入。 

2.增大数据尺寸的反卷积(deconv)层。能够输出精细的结果。 

3.结合不同深度层结果的跳级(skip)结构。同时确保鲁棒性和精确性。

FCN是首个端到端(end to end)进行像素级(pixel level)预测的全卷积网络。

 3、模型简介

FCN主要用于图像分割领域,是一种端到端的分割方法,是深度学习应用在图像语义分割的开山之作。通过进行像素级的预测直接得出与原图大小相等的label map。因FCN丢弃全连接层替换为全卷积层,网络所有层均为卷积层,故称为全卷积网络。

全卷积神经网络主要使用以下三种技术:

3.1 卷积化(Convolutional)

使用VGG-16作为FCN的backbone。VGG-16的输入为224*224的RGB图像,输出为1000个预测值。VGG-16只能接受固定大小的输入,丢弃了空间坐标,产生非空间输出。VGG-16中共有三个全连接层,全连接层也可视为带有覆盖整个区域的卷积。将全连接层转换为卷积层能使网络输出由一维非空间输出变为二维矩阵,利用输出能生成输入图片映射的heatmap。

 

 3*3 conv, 64:使用64个size是3*3,stride步长为1,padding填充为1的卷积核。

池化:最大池化,使用size是2*2,stride步长为2,padding填充为0进行池化。

第6层和第7层分别是一个长度为4096的一维向量,第8层是长度为1000的一维向量,分别对应1000个类别的概率。FCN将这3层表示为卷积层,卷积核的大小(通道数,宽,高)分别为(4096,7,7)、(4096,1,1)、(1000,1,1)。所有的层都是卷积层,故称为全卷积网络。

3.2 上采样(Upsample)

在卷积过程的卷积操作和池化操作会使得特征图的尺寸变小,为得到原图的大小的稠密图像预测,需要对得到的特征图进行上采样操作。使用双线性插值的参数来初始化上采样逆卷积的参数,后通过反向传播来学习非线性上采样。在网络中执行上采样,以通过像素损失的反向传播进行端到端的学习。

3.3 跳跃结构(Skip Layer)

利用上采样技巧对最后一层的特征图进行上采样得到原图大小的分割是步长为32像素的预测,称之为FCN-32s。由于最后一层的特征图太小,损失过多细节,采用skips结构将更具有全局信息的最后一层预测和更浅层的预测结合,使预测结果获取更多的局部细节。将底层(stride 32)的预测(FCN-32s)进行2倍的上采样得到原尺寸的图像,并与从pool4层(stride 16)进行的预测融合起来(相加),这一部分的网络被称为FCN-16s。随后将这一部分的预测再进行一次2倍的上采样并与从pool3层得到的预测融合起来,这一部分的网络被称为FCN-8s。 Skips结构将深层的全局信息与浅层的局部信息相结合。

 4、数据处理

        由于PASCAL VOC 2012数据集中图像的分辨率大多不一致,无法放在一个tensor中,故输入前需做标准化处理。

4.2 加载数据集

from download import download

url = "https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/notebook/datasets/dataset_fcn8s.tar"

download(url, "./dataset", kind="tar", replace=True)

4.2 数据预处理 

import numpy as np
import cv2
import mindspore.dataset as ds

class SegDataset:
    def __init__(self,
                 image_mean,  #图像的均值,用于图像标准化。通常是一个列表或数组,包含每个通道的均值值。
                 image_std,#图像的标准差,也用于图像标准化。通常是一个列表或数组,包含每个通道的标准差值。
                 data_file='',#数据文件的路径。这个参数默认是一个空字符串,表示可能的默认值或未提供文件路径。
                 batch_size=32,#批处理大小,表示一次训练中使用的样本数量。32是一个常见的默认值。
                 crop_size=512,#裁剪大小,表示图像在训练或测试时裁剪的尺寸。512通常用于高分辨率图像。
                 max_scale=2.0,#最大缩放比例,用于数据增强,通过随机缩放图像来增加模型的鲁棒性。
                 min_scale=0.5,#最小缩放比例,同样用于数据增强。
                 ignore_label=255,#忽略标签,通常用于语义分割任务,表示某些像素点不参与训练的标签值。
                 num_classes=21,#类别数量,表示数据集中不同类别的数量。21个类别可能用于某个特定的数据集,比如Pascal VOC。
                 num_readers=2,#读取器数量,表示用于读取数据文件的并行读取器数量,可以加快数据加载速度。
                 num_parallel_calls=4):#并行调用数量,用于数据预处理的并行调用次数,可以加快数据预处理过程。

        self.data_file = data_file
        self.batch_size = batch_size
        self.crop_size = crop_size
        self.image_mean = np.array(image_mean, dtype=np.float32)
        self.image_std = np.array(image_std, dtype=np.float32)
        self.max_scale = max_scale
        self.min_scale = min_scale
        self.ignore_label = ignore_label
        self.num_classes = num_classes
        self.num_readers = num_readers
        self.num_parallel_calls = num_parallel_calls
        max_scale > min_scale

    def preprocess_dataset(self, image, label):
        # np.frombuffer(image, dtype=np.uint8):将原始字节数据转换为NumPy数组,以便OpenCV可以处理。
        # cv2.imdecode(..., cv2.IMREAD_COLOR):使用OpenCV解码这个NumPy数组,并将其转换为一个图像矩阵,以便后续的图像处理操作。
        image_out = cv2.imdecode(np.frombuffer(image, dtype=np.uint8), cv2.IMREAD_COLOR)
        label_out = cv2.imdecode(np.frombuffer(label, dtype=np.uint8), cv2.IMREAD_GRAYSCALE)
        
        #生成一个在self.min_scale和self.max_scale之间的随机浮点数。
        sc = np.random.uniform(self.min_scale, self.max_scale)
        new_h, new_w = int(sc * image_out.shape[0]), int(sc * image_out.shape[1])
        
        #将图像 image_out 的大小调整为 new_w 宽和 new_h 高,并使用(nterpolation=cv2.INTER_CUBIC)双三次插值方法进行插值。
        image_out = cv2.resize(image_out, (new_w, new_h), interpolation=cv2.INTER_CUBIC)
        label_out = c
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值