核心内容摘要
python宠物医院爱宠信息管理系统vue3
基于ResNet的图像分类--算法实现数据准备ResNet概述核心思想
ResNet-18/
ResNet-50/101/152网络架构ResNet-34 示例结构各版本详细配置ResNet34网络代码实现数据增强数据集封装Dataset类数据集封装DataLoader类数据准备导包fromPILimportImageimportcv2importnumpyasnpimportosfromsklearn.model_selectionimporttrain_test_splitfromsklearn.kernel_approximationimportAdditiveChi2Samplerimportrandomimportmathfromimutilsimportpaths读取数据# 图像数据data[]# 图像对应的标签labels[]# 储存标签信息的临时变量labels_tep[]# 数据集的地址# 请读者自行下载数据集并将数据集放在代码的同级目录下image_pathslist(paths.list_images(E:\\jupyterNotebook\\Hands-on-CV-main\\10classify\\caltech-
)forimage_pathinimage_paths:# 获取图像类别labelimage_path.split(os.path.sep)[-2]# 读取每个类别的图像imagecv
imread(image_path)# 将图像通道从BGR转换为RGBimagecv
cvtColor(image,cv
COLOR_BGR2RGB)# 统一输入图像的尺寸imagecv
resize(image,(200,
,interpolationcv
INTER_AREA)data.append(image)labels_tep.append(label)name2label{}tep{}foridx,nameinenumerate(labels_tep):tep[name]idxforidx,nameinenumerate(tep):name2label[name]idxforidx,image_pathinenumerate(image_paths):labels.append(name2label[image_path.split(os.path.sep)[-2]])datanp.array(data)labelsnp.array(labels)数据集划分(x_train,X,y_train,Y)train_test_split(data,labels,test_size
4,stratifylabels,random_state
(x_val,x_test,y_val,y_test)train_test_split(X,Y,test_size
5,random_state
print(fx_train examples:{x_train.shape}\n\ x_test examples:{x_test.shape}\n\ x_val examples:{x_val.shape})上面数据获取部分和前面一节是一致的不再赘述ResNet概述ResNetResidual Network残差网络是2015年由微软研究院的何恺明等人提出的一种深度卷积神经网络架构。
它通过引入残差学习Residual Learning解决了深度神经网络中的梯度消失/爆炸和退化问题使得可以训练非常深的网络超过100层。
核心思想残差块Residual BlockResNet的核心创新是残差块它通过跳跃连接skip connection将输入直接传递到输出输出 F(x) x其中x是输入F(x)是需要学习的残差映射F(x) x通过跳跃连接实现数学表达传统网络H(x) F(x)残差网络H(x) F(x) x目标学习F(x) H(x) - x残差
ResNet-18/34使用基本的残差块Conv 3×3 ReLU Conv 3×3跳跃连接如果输入输出维度相同直接相加如果维度不同使用1×1卷积调整维度。
ResNet-50/101/152使用瓶颈结构BottleneckConv 1×1, 减少通道数 Conv 3×3, 主要计算 Conv 1×1, 恢复通道数网络架构ResNet-34 示例结构输入 → Conv 7×7 → MaxPool ↓ [Residual Block ×3] 通道数:64 ↓ [Residual Block ×4] 通道数:128 ↓ [Residual Block ×6] 通道数:256 ↓ [Residual Block ×3] 通道数:512 ↓ 全局平均池化 → 全连接层 → 输出各版本详细配置网络层ResNet-18ResNet-34ResNet-50ResNet-101ResNet-152卷积层17×7,64,stride27×7,64,stride27×7,64,stride27×7,64,stride27×7,64,stride2池化层3×3 max pool, stride23×3 max pool, stride23×3 max pool, stride23×3 max pool, stride23×3 max pool, stride2卷积层2[3×3,64]×2[3×3,64]×3[1×1,643×3,641×1,256]×3[1×1,643×3,641×1,256]×3[1×1,643×3,641×1,256]×3卷积层3[3×3,128]×2[3×3,128]×4[1×1,1283×3,1281×1,512]×4[1×1,1283×3,1281×1,512]×4[1×1,1283×3,1281×1,512]×8卷积层4[3×3,256]×2[3×3,256]×6[1×1,2563×3,2561×1,1024]×6[1×1,2563×3,2561×1,1024]×23[1×1,2563×3,2561×1,1024]×36卷积层5[3×3,512]×2[3×3,512]×3[1×1,5123×3,5121×1,2048]×3[1×1,5123×3,5121×1,2048]×3[1×1,5123×3,5121×1,2048]×3参数数量
1
7M
2
8M
2
6M
4
5M
6
2MResNet34网络代码实现左图为传统网络结构右图为残差网络结构importtorchastfromtorchimportnnfromtorch.nnimportfunctionalasF# 残差结构classResidualBlock(nn.Module):# 深度学习中的图像和利用模型提取的特征图往往有很多通道channel# 比如RGB图像的通道为3即R通道、B通道与G通道def__init__(self,inchannel,outchannel,stride1,shortcutNone):super(ResidualBlock,self).__init__()# 观察图 不难发现残差结构可大致分为左右两部分# 左边是一系列的网络层级右边是一个跳跃连接# 定义左边self.leftnn.Sequential(# 对应图 中第一个权重层nn.Conv2d(inchannel,outchannel,3,stride,1,biasFalse),nn.BatchNorm2d(outchannel),# 对应图中的 RELUnn.ReLU(inplaceTrue),# 对应图中第二个权重层nn.Conv2d(outchannel,outchannel,3,1,1,biasFalse),nn.BatchNorm2d(outchannel))# 定义右边self.rightshortcut# forward()函数在网络结构中起到举足轻重的作用它决定着网络如何对数据进行传播defforward(self,x):outself.left(x)# 构建残差结构residualxifself.rightisNoneelseself.right(x)outresidualreturnF.relu(out)# 在这一模块中将实现 ResNet34classResNet(nn.Module):def__init__(self,num_classes
:super(ResNet,self).__init__()# 前几层图像转换self.prenn.Sequential(nn.Conv2d(3,64,7,2,3,biasFalse),nn.BatchNorm2d(
,nn.ReLU(inplaceTrue),nn.MaxPool2d(3,2,
,)# 重复的网络层分别有
3、
4、