RESNET19兵马俑图像分类python

摘要:兵马俑碎片是中国古代文化遗产的重要组成部分,其分类和识别对于文物修复、保护和研究具有重要意义。但兵马俑碎片匹配和拼接是一份十分耗费人工精力的工作,目前更多的计算机辅助技术引入兵马俑修复的工程中。本研究旨在设计和实现一种基于ResNet18架构的兵马俑碎片分类网络。采用深度学习的方法,通过对ResNet18进行参数调整和优化,构建了一种适用于兵马俑碎片分类的卷积神经网络(CNN)模型。在兵马俑碎片数据集上进行训练和验证后,实验证明该模型在兵马俑碎片分类任务上取得了准确率高达76%的分类效果。研究结果表明,基于ResNet18的兵马俑碎片分类网络在文物鉴定和保护方面具有潜在的应用前景,为文物研究领域提供了一种实用的技术手段。未来可进一步探索不同深度学习架构和优化方法,以进一步提升兵马俑碎片分类的准确率和鲁棒性。

引言

秦兵马俑被誉为世界“八大奇迹”之一,经过数千年的自然风化侵蚀和人为破环等因素,大多数破碎为碎片的形态,早期通过人工来拼接修复,不仅效率低下,并且有可能造成这些文物的二次破坏,修复兵马俑的工作流程一般包括碎片分类、碎片匹配和碎片拼接,随碎片匹配是其中整个工作中十分关键的技术之一,如何高效准确分类兵马俑碎片辅助人工拼接成完整的兵马俑是当今新的研究课题。随着计算视觉的日新月异的突破,更多的方法被应用到此领域,大大降低了后续修复工作的难度[1]。

在兵马俑分类方面,国内外专家学者分别进行了各类的方法的研究。针对传统机器视觉,通过提取碎片的几何形状[10]、颜色和纹理等特征来进行分类,而纹理特征提取一般采用Haar、LBP、HOG、SIFT 等算法,Hough 变换、角径向变换、傅里叶变换及 Hu 不变矩等方法可以对图像进行几何形状特征提取[6],最终利用SVM[5]或者其它分类器进行多特征分类,目前采用碎片纹理、形状和颜色等多特征融合分类的方法在实验中往往有着更佳分类的效果[6][7],但此种方法仍有一定的不足之处,合适特征的选定是一件十分复杂且耗时的人工工作。

卷积神经网络可以直接对图像操作,通过输入大量图像样本的训练,可以得到能够提取图像分类特征的卷积核,从而大大简化人为试验提取图像复杂特征的过程,卷积神经网络的精度往往取决于训练数据的质量、网络的深度和宽度[1],随着几十年深度学习的迅速发展,神经网络模型从最初的LeNet到 AlexNet、ZFNet 、VGGNet 、GoogleNet及 ResNet等,这些深度神经网络分别在图像分类、目标识别和图像分割等领域取得创新性的成果,现在这些模型已发展出多个变种,并且能对三维的图像数据进行处理[2][3]。而ResNet是卷积神经网络发展历程中的一次重大突破,一般来说,深度学习的模型准确率将随着网络深度的递增而提高,但实际实验中反而出现了衰退的现象,这困扰了深度学习领域相当一段时间,直到中国学者何恺明[4]等人在论文《Deep Residual Learning for Image Recognition》中首次提出了ResNet架构,并在当年的ImageNet竞赛中,ResNet模型在图像分类任务中取得了第一名的优异成绩,极大地推动了深度神经网络的发展。

本文建立的模型基于Resnet18框架,同时采用数据增强技术对有限的数据进行扩充,进一步提高数据集的数量和多样性,使得模型对兵马俑碎片分类的准确率和鲁棒性显著提升。

数据采集和处理

通过编写网络爬虫,搜集到大概200多张关于兵马俑的图片,通过进一步筛选,去除相似度高、画片内容不符和画质模糊等不良图片,之后分别裁剪、去噪等操作将图片规范化为统一大小和格式,人工附上标签将数据划分为四类,具体信息如下表1所示

1 数据信息

类别

数量/

Arm

48

Head

32

Legs

30

Trunk

41

All

141

为了进一步提高模型的泛化能力,我们在训练过程中采用了数据增强技术。数据增强是通过对训练数据进行随机变换,例如旋转、灰度和模糊等[1],以扩充训练集,帮助模型更好地学习鲁棒的特征。如下图(图1)所示:

图1 图像增强效果图

ResNet18模型搭建

ResNet(Residual Networks)是由Microsoft Research于2015年首次提出的深度卷积神经网络,它解决了由于网络深度增加而导致的梯度消失和梯度爆炸等训练问题。ResNet的创新核心思想在于引入了残差连接(如图2所示),通过跨层直接连接一些层,使得信息能够更快速地传播。这一设计带来了训练深度网络的显著改进,并成为当今深度学习领域的重要里程碑。

图2  ResNet经典残差块

随着时间的推移,ResNet不断发展演进,涌现出多个版本,其中网络层数已经达到上千。然而,考虑到自身计算机性能和训练时间成本,本文选择采用ResNet18模型,该模型在保持性能的同时具有相对较小的网络深度。模型架构图如下所示:

图3  ResNet18网络架构

ResNet18主要由18权重层构成,网络架构阐述:

  1. 输入层:输入层通常接受224x224x3大小的图像(3通道,通常为RGB图像)。
  2. 卷积层:第一个卷积层:使用大小为7x7,步幅为2,64个输出通道的卷积核,然后接Batch Normalization(BN)层和ReLU激活函数。紧接着,是一个最大池化层(max pooling),核大小为3x3,步幅为2。
  3. 残差块:接下来是一系列残差块(residual blocks)。每个残差块包括两个相同输出通道数的卷积层,每个卷积层后面都接一个Batch Normalization层和ReLU激活函数,残差块输入与输出跳跃连接。
  1. 2个残差块,每个块的卷积层输出通道数为64。
  2. 2个残差块,每个块的卷积层输出通道数为128,这里会使得特征图的大小减半(downsampling)。
  3. 2个残差块,每个块的卷积层输出通道数为256,同样,特征图大小减半。
  4. 2个残差块,每个块的卷积层输出通道数为512,特征图大小继续减半。
  1. 全局平均池化:对最后输出的每个特征图执行全局平均池化,将特征图的大小变为1x1。
  2. 全连接层:ResNet18 在全局平均池化层之后使用一个全连接层。全连接层将平均池化的输出映射到 1000 个类别的概率分布。
  3. Softmax层:全连接层之后通常接一个Softmax层,用于将输出转换为概率分布。

专业名词解释:

最大池化层:使用步幅为2的最大池化操作进行下采样,将特征图的尺寸减半。最大池化层有助于提取主要特征并减小特征图的空间维度。

跳跃连接(残差连接):在每个残差块中,将输入信号直接添加到残差块的输出中。这种跳跃连接允许信息在网络中直接跳过一些层,有助于解决梯度消失和梯度爆炸问题。

全局平均池化层:在最后一个残差块之后,使用全局平均池化操作将特征图转换为固定长度的向量。全局平均池化层对每个特征图进行平均操作,得到一个特征向量。

全连接层:将全局平均池化层的输出连接到全连接层,用于最终的分类任务。全连接层通过一系列的线性变换和非线性激活函数来进行特征映射和分类。

训练与测试

运行环境:

windows11,python 3.11,torch 2.1.1,matplotlib 3.7.1,torchvision 0.16.1,tensorflow 2.13.0

处理器:AMD Ryzen 7 6800H with Radeon Graphics  3.20 GHz   内存16.0 GB (15.2 GB 可用)

学习率:0.0001,训练次数:90,batch_size:8

图4  训练曲线

训练过程训练集损失整体上随着训练周期的增加逐步地下降,最后损失基本稳定在0.075以下,而训练集的准确率随训练次数一直稳逐次上升,保持在97%左右,但模型在测试集效果不太理想,但是最高的准确率依然达到了76%,而准确率平均稳定在61%左右

结论

针对传统人工修复兵马俑过程中效率低下的问题,本文将深度学习方法引入到兵马俑碎片分类工作中,并利用数据增强技术扩充数据集的数量和加强数据多样性,应用深度卷积神经网络ResNet18自动提取兵马俑碎片的图像特征进行碎片分类,并取得准确率高达76%的分类效果。相较于传统方法,本文提出一种高效率、高准确率的兵马俑碎片分类方法,有效地降低兵马俑修复过程中体力劳动的强度。

推测ResNet18在测试集上效果不佳的原因可能是出现了过拟合现象或者数据量太小导致训练出来的权重矩阵比较差,未来可能会进一步从数据量和网络的深度方向入手,进一步提升模型的分类准确率[8]。

参考文献

[1]        Y. Yuehua et al., “Data Enhanced Depth Classification Model for Terracotta Warriors Fragments,” Laser Optoelectron. Prog., vol. 59, no. 18, 2022, doi: 10.3788/LOP202259.1810010.

[2]        H. Gao and G. Geng, “Classification of 3D Terracotta Warrior Fragments Based on Deep Learning and Template Guidance,” IEEE Access, vol. 8, 2020, doi: 10.1109/ACCESS.2019.2962791.

[3]        J. Liu et al., “UMA-Net: an unsupervised representation learning network for 3D point cloud classification,” J. Opt. Soc. Am. A, vol. 39, no. 6, 2022, doi: 10.1364/josaa.456153.

[4]        K. He, X. Zhang, S. Ren, and J. Sun, “Deep residual learning for image recognition,” Proc. IEEE Comput. Soc. Conf. Comput. Vis. Pattern Recognit., vol. 2016-Decem, pp. 770–778, 2016, doi: 10.1109/CVPR.2016.90.

[5]    魏阳,周明全,耿国华等.基于多特征和SVM的兵马俑碎片分类[J].西北大学学报(自然科学版),2017,47(04):497-504.DOI:10.16152/j.cnki.xdxbzr.2017-04-006

[6]        魏阳.基于多特征的兵马俑碎片图像分类及检索技术研究[D].西北大学,2018.

[7]        赵思仲,侯妙乐,李爱群等.融合多特征的兵马俑碎片分类技术研究[J].地理信息世界,2019,26(05):14-21.

[8]        王瑶瑶.基于卷积神经网络优化模型的兵马俑碎片分类方法研究[D].西北大学,2019.

[9]        陆正杰.文物碎片特征提取与分类算法研究[D].西北大学,2020.DOI:10.27405/d.cnki.gxbdu.2020.000915

[10]      康馨月,周明全,耿国华.基于显著几何特征的文物碎片分类[J].图学学报,2015,36(04):551-556.

附录

主要代码:

#resnet18
class BasicBlock(nn.Module):
    def __init__(self, in_channels, out_channels, stride=1):
        super(BasicBlock, self).__init__()
        self.conv1 = nn.Conv2d(in_channels, out_channels, kernel_size=3, stride=stride, padding=1, bias=False)
        self.bn1 = nn.BatchNorm2d(out_channels)
        self.relu = nn.ReLU(inplace=True)  

        self.conv2 = nn.Conv2d(out_channels, out_channels, kernel_size=3, stride=1, padding=1, bias=False)
        self.bn2 = nn.BatchNorm2d(out_channels)
        
        self.shortcut = nn.Sequential()
        if stride != 1 or in_channels != out_channels:
            self.shortcut = nn.Sequential(nn.Conv2d(in_channels, out_channels, kernel_size=1, stride=stride, bias=False),
                                        nn.BatchNorm2d(out_channels))
    def forward(self, x):
        idendty = x
        out = self.conv1(x)
        out = self.bn1(out)
        out = self.relu(out)

        out = self.conv2(out)
        out = self.bn2(out) 

        out += self.shortcut(idendty)
        out = self.relu(out)

        return out
ResNet18:
class ResNet18(nn.Module):
    def __init__(self, num_classes=10):
        super(ResNet18, self).__init__()
        self.conv1 = nn.Conv2d(3, 64, kernel_size=7, stride=2, padding=3, bias=False)
        self.bn1 = nn.BatchNorm2d(64)
        self.relu = nn.ReLU(inplace=True)
        self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)

        self.layer1 = self._make_layer(64, 64, 2, stride=1)
        self.layer2 = self._make_layer(64, 128, 2, stride=2)
        self.layer3 = self._make_layer(128, 256, 2, stride=2)
        self.layer4 = self._make_layer(256, 512, 2, stride=2)
        
        self.avgpool = nn.AdaptiveAvgPool2d((1,1))
        self.fc = nn.Linear(512, num_classes)

    def _make_layer(self,in_channels, out_channels, blocks, stride=1):
        layers = []
        layers.append(BasicBlock(in_channels, out_channels, stride))
        for _ in range(1, blocks):
            layers.append(BasicBlock(out_channels, out_channels))

        return nn.Sequential(*layers)

    def forward(self, x):
        out = self.conv1(x)
        out = self.bn1(out)
        out = self.relu(out)
        out = self.maxpool(out)

        out = self.layer1(out)
        out = self.layer2(out)
        out = self.layer3(out)
        out = self.layer4(out)

        out = self.avgpool(out)
        out = torch.flatten(out,1)
        out = self.fc(out)
        return out

想要数据集和完整代码可以私信我。

  • 22
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值