《计算机视觉之PyTorch数字图像处理》--图像分类与分割
[复制链接]
本篇讲述基于深度学习的图像分类与图像分割。
图像分类
图像分类是模式识别、机器学习和人工智能的重要任务之一。
图像分类及其进展:早前图像分类的主要方法是先由人工设计特征,把图像从图像空间转换到特征空间,随后在特征空间中进行分类。后来卷积神经网络一路突飞猛进, 在图像分类上迅速达到了人的识别精度,并在其他的图像和非图像任务上也取得了极大的进步。最早的卷积神经网络是LeCun发明的LeNet系列网络。微软亚洲研究院提出的ResNet使得分类精度达与人的分类精度相同,在一定程度上解决了图像分类问题。自动搜索最优网络结构的方法(NAS),把所有的神经网络模型当做可选空间,通过算法从大量的模型中选出最优的模型,可以以更快的速度、更高的效率对模型进行验证。
预训练模型的使用:对于完成一个分类任务来说,从头开始模型的构建和训练并不是一个好的方法。充分利用已有的模型,进行评估后,再进行调节和修改才更合理。在torchvision库中,已经集成了许多经典的分类网络模型,可以通过函数的调用即可创建相应的模型,免去了自行搭建的麻烦,这些模型都位于torchvision.models包下。下面是预训练模型检测树懒代码,展示三个模型(resnet18、shufflenet、mobilenetv3)的预测结果与置信度。
import torch as tc
import torchvision as tvs
from imagenetlabels import imagenet_lb1000
def createmodel():
vgg11 = tvs.models.vgg11()
resnet18 = tvs.models.resnet18()
shufflenet = tvs.models.shufflenet_v2_x1_0()
mobilenetv3 = tvs.models.mobilenet_v3_small()
img=tc.rand((1,3,224,224))
with tc.no_grad():
r0=vgg11(img)
r1=resnet18(img)
r2=shufflenet(img)
r3=mobilenetv3(img)
print(r0.shape,r1.shape,r2.shape)
tc.max(r0,dim=1) #得到vgg11的最终结果,返回最大概率和索引
#vgg11 = tvs.models.vgg11(pretrained=True).eval()
resnet18 = tvs.models.resnet18(pretrained=True).eval()
shufflenet = tvs.models.shufflenet_v2_x1_0(pretrained=True).eval()
mobilenetv3 = tvs.models.mobilenet_v3_small(pretrained=True).eval()
from imageio import loadimage
img=loadimage('3.jpg') #1.png
img=tvs.transforms.Resize((224,224))(img)
img=img/255.0
img=tvs.transforms.Normalize((0.485, 0.456, 0.406), (0.229, 0.224, 0.225))(img)
img=img.unsqueeze(0)
with tc.no_grad():
r1=resnet18(img)
r2=shufflenet(img)
r3=mobilenetv3(img)
r1=tc.softmax(r1,dim=1).max(dim=1)
r2=tc.softmax(r2,dim=1).max(dim=1)
r3=tc.softmax(r3,dim=1).max(dim=1)
print('resnet18的预测结果是:{},置信度是:{:.2%}'.format(imagenet_lb1000[r1[1].item()],r1[0].item()))
print('shufflenet的预测结果是:{},置信度是:{:.2%}'.format(imagenet_lb1000[r2[1].item()],r2[0].item()))
print('mobilenetv3的预测结果是:{},置信度是:{:.2%}'.format(imagenet_lb1000[r3[1].item()],r3[0].item()))
下面是预测结果。可以看到三个模型预测置信度还是挺高的。
经典卷积神经网络:VGGNet和ResNet
整个VGGNet继续加深了卷积网络的层数,从网络的层数从11层至19层,表明了网络的深度的越大精度就越高。从网络的结构上来看,只包含了3×3卷积层,最大池化层,ReLU激活函数,全连接层和Dropout层几种结构,并且通过简单结构单元的堆叠,组合成不同复杂程度的VGGNet。
ResNet通过对VGGNet的改进引入了残差模块和BN层,基本解决了梯度消失和梯度爆炸问题,使得几十层、上百层,甚至上千层的卷积神经网络得以训练,展示了卷积神经网络的强大能力。
卷积神经网络的训练与评估
在完成卷积神经网络的设计和创建后,使用准备好的数据集,就可以进行模型的训练和精度的评估。卷积神经网络的训练是通过标注的数据,在损失函数的引导下用优化器进行网络参数的学习,使得神经网络的分类能力提高。神经网络的训练是数据集和神经网络的结合,需要准备好的数据集以及神经网络的模型。
网络的训练主要包括,数据变换方法的选择、数据集的创建、网络的创建、损失函数的创建或加载、优化器的创建等几个准备步骤,以及数据集的遍历、前向传播、损失计算、后向传播、参数更新、统计损失和测试精度等几个训练步骤。
训练模式和评估模式的区别在于BN和Dropout等层是否发挥作用。网络的评估是使用训练好的模型进行图像类别的推理,主要包括数据的加载、数据的变换、模型的加载、结果预测和结果输出等几个步骤。
迁移学习
对于一个新的问题,如果能借助现有模型中已经训练得到的权重,用于新的任务,在新的任务上进行微调,就可以在小样本的数据集上加速新任务训练的方法,就称为迁移学习(Transfer Learning)。
迁移学习在卷积神经网络中应用的方式主要可分为两种:将网络做为特征提取器和微调卷积网络。
图像分割
在经典的图像处理中,图像分割一般基于单个像素值或包含一定邻域内的全部像素进行类别的判断。经典方法存在的问题主要表现为分割结果较为破碎,边界不够圆滑,分割结果不准确。
随着深度学习在分类上的成功,表明深度神经网络是一种很好的特征提取器,能够生成比像素值更好的识别特征。因此,通过对分类神经网络的结构进行改进后,直接输出一张与输入图像宽高尺寸相同的张量,从而完成端到端的训练。
图像分割通常可以分为两种类型,一种称为语义分割,另一种称为实例分割。
深度神经网络对于图像分割的研究主要使用PASCAL VOC2012数据集。该数据集由一些来自实际场景下的图像组成,每幅图像都经过详细的标注,可以用于分类,检测和分割。该数据集总共有4个大类,20个小类组成。对于图像分割来说,还需要加入背景类,总共就是21个类别。
在进行分割模型的建立前,需要完成数据集的准备。分割数据集与分类数据集最大的差异在于标签的不同,分类数据集返回的训练样本对的标签是类别编号,分割数据集返回的训练样本对的标签是一个张量,其中每个元素都是对应输入图像像素的类别。分割数据集的另一个特点就是在做数据增强时,原图像像素的空间位置在发生变化时,需要同时对标签张量也要进行相似的变换,并且要保持标签的不变。
FCN(Fully Convolutional Network,全卷积神经网络)是第一个将卷积神经网络用于图像分割任务的模型。FCN直接来自于对分类网络的改进。FCN第一次把卷积神经网络用于图像分割,不仅证明了卷积神经网络能够用于图像主义分割,而且在性能上也超越了传统的图像分割方法。
FCN分割模型的核心思想是以下几点:特征复用;将全连接层替换为卷积层;上采样(Upsampling);融合高低层特征;
在PyTorch中提供了以ResNet作为特征提取器的FCN:fcn_resnet50和fcn_resnet101。以上两种FCN都可以加载预训练的参数,可以直接用于PASCAL VOC分割任务中的类别,同样也可以改变输出层,使用迁移学习用于其他数据的语义分割。
UNet图像分割网络,主要用于细胞的分割。UNet名称中的字母“U”形象表示了该网络的结构,表示整个网络由左右两个对称的部分构成。UNet继承并发展了FCN,UNet的优点是该模型可以在小样本的情况下,无需对分类模型的特征进行迁移,只需使用端到端的方式进行分割模型的训练,就可以得到精度很高的分割模型。
在PyTorch中并没有提供完整的UNet模型,需要自行根据UNet的结构自行定义。由于PyTorch提供了UNet内部各组成部分的运算,只需要按照UNet模型的结构进行组合即可完成创建。
与创建分类网络相似,UNet分割网络的创建也要继承自torch.nn.Module,相对于直接将卷积,池化进行构造,可以按照UNet的结构,划分为5个编码模块和4个解码模块,先对每个模块进行构造,再对各模块按照数据的流动进行结合,完成整个网络的构建。
与分类网络的训练相似,分割网络的训练同样也需要创建优化器、定义损失函数、反向传播梯度等,将分割网络的训练看作是逐像素的分类训练,但是在具体的计算形式上会稍有不同。在训练完成后,分割网络的评估具有自己的特点,与分类网络考虑准确率不同,分割网络通常会存在大量的背景类,准确率不能很好的反映真实的分割效果,需要使用一些其他的一些指标。
损失函数不论二类还是多类都可以使用交叉熵损失。分割网络的最后一层输出层是卷积层,并没有包含Softmax操作,也就是说需要在计算损失函数前,先要对网络的输出计算Softmax,再进行交叉熵损失的计算,或者直接使用带有Softmax的交叉熵损失函数。
PyTorch中提供了上述交叉损失函数的两种构造方法:分步计算;合并计算。
优化器对网络参数的优化提供了方便接口,能够完成网络参数的学习。一般使用下面两种优化器:optim.SGD提供了使用随机梯度下降算法的优化器;optim.Adam提供了使用Adam算法的优化器。
评价指标:
混淆矩阵(Confusion Matrix)是一个误差矩阵, 最详细地记录了监督学习算法的性能,许多其他评价指标都能依据混淆矩阵计算得到。
像素准确率(Pixel Accuracy):是最常用的一种评价指标,常用于分类模型的性能评价,能够反映总体的分割精度。
平均交并比(MIoU, Mean Intersection over Union):是一种更严格的评价指标,对于分割结果的评价更为精准,能够更好的反映分割效果。
本篇梳理学习图像分类与分割,是深度学习图像处理的一次初探,对知识点学习强化,通过实践也有所收获。
|