PyTorch之ResNet101模型与示例
创始人
2024-11-19 09:07:23
0

【图书推荐】《PyTorch深度学习与企业级项目实战》-CSDN博客

ResNet101模型

ResNet101是一种深度残差网络,它是ResNet系列中的一种,下面详解ResNet101网络结构。

ResNet101网络结构中有101层,其中第一层是7×7的卷积层,然后是4个阶段(Stage),每个阶段包含若干残差块(Residual Block)。之后是全局平均池化(Global Average Pooling)层以及全连接层(Fully Connected Layer)。全连接层的作用是将全局平均池化层的输出展开成一个向量,并通过一个全连接层将其映射到类别数量的维度上。

ResNet101的每个残差块由两个3×3的卷积层组成,每个卷积层后面都跟有批量归一化(Batch Normalization)和ReLU激活函数。在残差块之间也有批量归一化和ReLU激活函数,但没有卷积层。每个阶段的第一个残差块使用1×1的卷积层将输入的通道数转换为输出的通道数,以便与后续的残差块进行加和操作。

ResNet101模型的主要贡献是引入了残差块的概念,使得网络可以更深,更容易训练。它在ImageNet数据集上的表现非常出色,达到了当时的最优水平。

实战项目代码分析

本项目使用的数据集是一个猴痘病毒分类的数据集,包含猴痘和其他病毒两类样本。数据集划分为训练集和验证集,猴痘类别的图片位于本书配套源码包的monkeypox目录下,其他病毒类别图片位于Others目录下。

本项目借鉴了迁移学习的思想,使用了在 ImageNet 上训练的 ResNet101 网络模型,ImageNet是供计算机视觉识别研究的大型可视化图像数据集,其中包含超过140万手动标注的图像数据,并包含1 000个图像类别,经过预训练的ResNet101网络的全连接层输出1 000个节点,在本实验中为了适应猴痘病数据集类别数,将节点数量由1 000改为2。但是注意需要冻结其他层的参数,防止训练过程中将其进行改动,然后训练微调最后一层即可。该方法既能提高模型的泛化能力和鲁棒性,也能够减少训练的时间,节约算力的开销。

我们知道损失函数是将随机事件或其有关随机变量的取值映射为非负实数,表示该随机事件的风险或损失的函数,在实际任务中则通过最小化损失函数求解和评估模型。本项目使用交叉熵损失表达预测值和真实值的不一致程度,交叉熵损失常用于在图像识别任务中作为损失函数,能够有效地衡量同一个随机变量中的两个不同概率分布的差异程度。

深度学习是以最小化损失函数为目标,其本质上是一种优化问题,目前应用于深度学习的优化算法均是由梯度下降算法发展而来的,其主要思想为利用链式求导法则计算损失函数值相对于神经网络中的每一个权重参数的梯度,通过更新权重参数达到降低损失函数值的效果。本项目使用的优化器Adam算法是一种基于梯度下降的优化算法。Adam算法的优点是收敛速度快,不需要手动调整学习率,兼顾了稳定性和速度。

我们使用PyTorch来搭建猴痘病毒识别模型,完整代码如下:

###############monkeypox.py####### import torchvision from torch import nn import os import pickle import torch from torchvision import transforms, datasets from tqdm import tqdm from PIL import Image  import matplotlib.pyplot as plt  epochs = 10 lr = 0.03 batch_size = 32 image_path = './monkeypoxdata' model_path = './chk/resnet101-cd907fc2.pth' save_path = './chk/monkeypox_model.pkl'  device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')  # 1.数据转换 data_transform = {     # 训练中的数据增强和归一化     'train': transforms.Compose([         transforms.RandomResizedCrop(224),  # 随机裁剪         transforms.RandomHorizontalFlip(),  # 左右翻转         transforms.ToTensor(),         transforms.Normalize([0.485, 0.456, 0.406],                              [0.229, 0.224, 0.225])         # 均值方差归一化     ]),     # 验证集不增强,仅进行归一化     'val': transforms.Compose([         transforms.Resize(256),         transforms.CenterCrop(224),         transforms.ToTensor(),         transforms.Normalize([0.485, 0.456, 0.406],                              [0.229, 0.224, 0.225])     ]), }  # 2.形成训练集 train_dataset = datasets.ImageFolder(root=os.path.join(image_path, 'train'),                                      transform=data_transform['train'])  # 3.形成迭代器 train_loader = torch.utils.data.DataLoader(train_dataset,                                            batch_size,                                            True)  print('using {} images for training.'.format(len(train_dataset)))  # 4.建立分类标签与索引的关系 cloth_list = train_dataset.class_to_idx class_dict = {} for key, val in cloth_list.items():     class_dict[val] = key with open('class_dict.pk', 'wb') as f:     pickle.dump(class_dict, f)  # 5.加载ResNet101模型 model = torchvision.models.resnet101(     weights=torchvision.models.ResNet101_Weights.DEFAULT) # 加载预训练好的ResNet模型 model.load_state_dict(torch.load(model_path, 'cpu')) # 冻结模型参数 for param in model.parameters():     param.requires_grad = False  # 修改最后一层的全连接层 model.fc = nn.Linear(model.fc.in_features, 2)  # 将模型加载到cpu中 model = model.to(device)  criterion = nn.CrossEntropyLoss()  # 损失函数 optimizer = torch.optim.Adam(model.parameters(), lr=0.01)  # 优化器  # 6.模型训练 best_acc = 0  			# 最优精确率 best_model = None  		# 最优模型参数  for epoch in range(epochs):     model.train()     running_loss = 0  	# 损失     epoch_acc = 0  		# 每个epoch的准确率     epoch_acc_count = 0 	# 每个epoch训练的样本数     train_count = 0  	# 用于计算总的样本数,方便求准确率     train_bar = tqdm(train_loader)     for data in train_bar:         images, labels = data         optimizer.zero_grad()         output = model(images.to(device))         loss = criterion(output, labels.to(device))         loss.backward()         optimizer.step()          running_loss += loss.item()         train_bar.desc = "train epoch[{}/{}] loss:{:.3f}".format(epoch + 1,                                                                  epochs,                                                                  loss)         # 计算每个epoch正确的个数         epoch_acc_count += (output.argmax(axis=1) == labels.view(-1)).sum()         train_count += len(images)      # 每个epoch对应的准确率     epoch_acc = epoch_acc_count / train_count      # 打印信息     print("【EPOCH: 】%s" % str(epoch + 1))     print("训练损失为%s" % str(running_loss))     print("训练精度为%s" % (str(epoch_acc.item() * 100)[:5]) + '%')      if epoch_acc > best_acc:         best_acc = epoch_acc         best_model = model.state_dict()      # 在训练结束保存最优的模型参数     if epoch == epochs - 1:         # 保存模型         torch.save(best_model, save_path)  print('Finished Training')  # 加载索引与标签映射字典 with open('class_dict.pk', 'rb') as f:     class_dict = pickle.load(f)  # 数据变换 data_transform = transforms.Compose(     [transforms.Resize(256),      transforms.CenterCrop(224),      transforms.ToTensor(),      transforms.Normalize([0.485, 0.456, 0.406],                           [0.229, 0.224, 0.225])])  # 图片路径 img_path = r'./monkeypoxdata/test/test_01.jpg'  # 打开图像 img = Image.open(img_path)  # 对图像进行变换 img = data_transform(img)  plt.imshow(img.permute(1, 2, 0)) plt.show()  # 将图像升维,增加batch_size维度 img = torch.unsqueeze(img, dim=0)  # 获取预测结果 pred = class_dict[model(img).argmax(axis=1).item()] print('【预测结果分类】:%s' % pred) 

运行结果如下:

using 2142 images for training. train epoch[1/10] loss:0.882: 100%|██████████| 67/67 [05:46<00:00,  5.17s/it] 【EPOCH: 】1 训练损失为38.31112961471081 训练精度为73.90% train epoch[2/10] loss:0.460: 100%|██████████| 67/67 [06:33<00:00,  5.88s/it] 【EPOCH: 】2 训练损失为37.73484416306019 训练精度为77.40% train epoch[3/10] loss:0.225: 100%|██████████| 67/67 [06:00<00:00,  5.38s/it]   0%|          | 0/67 [00:00

如图16-3所示,预测结果分类为Monkeypox。

图16-3

这个项目能够使有相关症状的感染者有效地识别出是否为猴痘病,提出了一种改进的基于迁移学习残差网络的图像自动识别方法。该方法使用了ResNet101网络并使用该网络预训练权重进行迁移学习,在猴痘病数据集上进行了网络的训练,可以增加训练轮次,最终达到了比较高的识别准确率。

《PyTorch深度学习与企业级项目实战(人工智能技术丛书)》(宋立桓,宋立林)【摘要 书评 试读】- 京东图书 (jd.com)

相关内容

热门资讯

新2024版措施!微扑克代打是... 新2024版措施!微扑克代打是真的的(辅助挂)指尖跑得快能控制输赢的(有挂技巧);人气非常高,ai更...
第三方介绍!wpk辅助机器人(... 【福星临门,好运相随】;第三方介绍!wpk辅助机器人(有科技)全民如意棋牌攻略(有挂手段);暗藏猫腻...
五分钟了解!wepoke软件机... 1、不需要AI权限,帮助你快速的进行wepoke计算辅助教程,沉浸在游戏的游玩之中。2、里面整个we...
科技分享!wepoke有规律的... 科技分享!wepoke有规律的(有挂的)星悦手机麻将是挂(有挂指点);wepoke软件透明挂作为一款...
一分钟教会你!微扑克德州专用辅... 1、不需要AI权限,帮助你快速的进行微扑克计算辅助教程,沉浸在游戏的游玩之中。2、里面整个微扑克黑科...
透视辅助!wpk辅助软件(软件... 1、完成算番宝典的残局,帮助玩家取得所有比赛的胜利,直登高塔的教程。2、多达1000个不同的游戏攻略...
黑客什么是渗透 黑客渗透是指黑客通过技术手段,利用系统的漏洞或弱点,非法进入目标计算机系统、网络或数据库,获取、篡改...
第三方规律!微扑克线上代打工具... 一、第三方规律!微扑克线上代打工具(软件透明挂)胡乐麻将有挂的(有挂指南)AI软件牌型概率发牌机制”...
oppo手机nfc在哪打开(如... 在OPPO手机上,通常可以在设置中找到NFC选项。进入“设置”-“连接与共享”-确定“NFC”为开启...
韩小陌百科 韩小陌,1994年2月10日出生于黑龙江省哈尔滨市,毕业于北京现代音乐学院,中国内地女演员、歌手。韩...