版权说明:此文章为本人原创内容,转载请注明出处,谢谢合作!


Pytorch实战2:ResNet-18实现Cifar-10图像分类

实验环境:

  1. Pytorch 0.4.0
  2. torchvision 0.2.1
  3. Python 3.6
  4. CUDA8+cuDNN v7 (可选)
  5. Win10+Pycharm

整个项目代码:点击这里

ResNet-18网络结构:


ResNet全名Residual Network残差网络。Kaiming He 的《Deep Residual Learning for Image Recognition》获得了CVPR最佳论文。他提出的深度残差网络在2015年可以说是洗刷了图像方面的各大比赛,以绝对优势取得了多个比赛的冠军。而且它在保证网络精度的前提下,将网络的深度达到了152层,后来又进一步加到1000的深度。论文的开篇先是说明了深度网络的好处:特征等级随着网络的加深而变高,网络的表达能力也会大大提高。因此论文中提出了一个问题:是否可以通过叠加网络层数来获得一个更好的网络呢?作者经过实验发现,单纯的把网络叠起来的深层网络的效果反而不如合适层数的较浅的网络效果。因此何恺明等人在普通平原网络的基础上增加了一个shortcut, 构成一个residual block。此时拟合目标就变为F(x),F(x)就是残差:
!

Pytorch上搭建ResNet-18:

'''ResNet-18 Image classfication for cifar-10 with PyTorch Author 'Sun-qian'.'''
import torch
import torch.nn as nn
import torch.nn.functional as Fclass ResidualBlock(nn.Module):def __init__(self, inchannel, outchannel, stride=1):super(ResidualBlock, self).__init__()self.left = nn.Sequential(nn.Conv2d(inchannel, outchannel, kernel_size=3, stride=stride, padding=1, bias=False),nn.BatchNorm2d(outchannel),nn.ReLU(inplace=True),nn.Conv2d(outchannel, outchannel, kernel_size=3, stride=1, padding=1, bias=False),nn.BatchNorm2d(outchannel))self.shortcut = nn.Sequential()if stride != 1 or inchannel != outchannel:self.shortcut = nn.Sequential(nn.Conv2d(inchannel, outchannel, kernel_size=1, stride=stride, bias=False),nn.BatchNorm2d(outchannel))def forward(self, x):out = self.left(x)out += self.shortcut(x)out = F.relu(out)return outclass ResNet(nn.Module):def __init__(self, ResidualBlock, num_classes=10):super(ResNet, self).__init__()self.inchannel = 64self.conv1 = nn.Sequential(nn.Conv2d(3, 64, kernel_size=3, stride=1, padding=1, bias=False),nn.BatchNorm2d(64),nn.ReLU(),)self.layer1 = self.make_layer(ResidualBlock, 64,  2, stride=1)self.layer2 = self.make_layer(ResidualBlock, 128, 2, stride=2)self.layer3 = self.make_layer(ResidualBlock, 256, 2, stride=2)self.layer4 = self.make_layer(ResidualBlock, 512, 2, stride=2)self.fc = nn.Linear(512, num_classes)def make_layer(self, block, channels, num_blocks, stride):strides = [stride] + [1] * (num_blocks - 1)   #strides=[1,1]layers = []for stride in strides:layers.append(block(self.inchannel, channels, stride))self.inchannel = channelsreturn nn.Sequential(*layers)def forward(self, x):out = self.conv1(x)out = self.layer1(out)out = self.layer2(out)out = self.layer3(out)out = self.layer4(out)out = F.avg_pool2d(out, 4)out = out.view(out.size(0), -1)out = self.fc(out)return outdef ResNet18():return ResNet(ResidualBlock)

Pytorch上训练:

所选数据集为Cifar-10,该数据集共有60000张带标签的彩色图像,这些图像尺寸32*32,分为10个类,每类6000张图。这里面有50000张用于训练,每个类5000张,另外10000用于测试,每个类1000张。训练时人为修改学习率,当epoch:[1-135] ,lr=0.1;epoch:[136-185], lr=0.01;epoch:[186-240] ,lr=0.001。训练代码如下:

import torch
import torch.nn as nn
import torch.optim as optim
import torchvision
import torchvision.transforms as transforms
import argparse
from resnet import ResNet18
import os# 定义是否使用GPU
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")# 参数设置,使得我们能够手动输入命令行参数,就是让风格变得和Linux命令行差不多
parser = argparse.ArgumentParser(description='PyTorch CIFAR10 Training')
parser.add_argument('--outf', default='./model/', help='folder to output images and model checkpoints') #输出结果保存路径
args = parser.parse_args()# 超参数设置
EPOCH = 135   #遍历数据集次数
pre_epoch = 0  # 定义已经遍历数据集的次数
BATCH_SIZE = 128      #批处理尺寸(batch_size)
LR = 0.01        #学习率# 准备数据集并预处理
transform_train = transforms.Compose([transforms.RandomCrop(32, padding=4),  #先四周填充0,在吧图像随机裁剪成32*32transforms.RandomHorizontalFlip(),  #图像一半的概率翻转,一半的概率不翻转transforms.ToTensor(),transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010)), #R,G,B每层的归一化用到的均值和方差
])transform_test = transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010)),
])trainset = torchvision.datasets.CIFAR10(root='./data', train=True, download=True, transform=transform_train) #训练数据集
trainloader = torch.utils.data.DataLoader(trainset, batch_size=BATCH_SIZE, shuffle=True, num_workers=2)   #生成一个个batch进行批训练,组成batch的时候顺序打乱取testset = torchvision.datasets.CIFAR10(root='./data', train=False, download=True, transform=transform_test)
testloader = torch.utils.data.DataLoader(testset, batch_size=100, shuffle=False, num_workers=2)
# Cifar-10的标签
classes = ('plane', 'car', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck')# 模型定义-ResNet
net = ResNet18().to(device)# 定义损失函数和优化方式
criterion = nn.CrossEntropyLoss()  #损失函数为交叉熵,多用于多分类问题
optimizer = optim.SGD(net.parameters(), lr=LR, momentum=0.9, weight_decay=5e-4) #优化方式为mini-batch momentum-SGD,并采用L2正则化(权重衰减)# 训练
if __name__ == "__main__":if not os.path.exists(args.outf):os.makedirs(args.outf)best_acc = 85  #2 初始化best test accuracyprint("Start Training, Resnet-18!")  # 定义遍历数据集的次数with open("acc.txt", "w") as f:with open("log.txt", "w")as f2:for epoch in range(pre_epoch, EPOCH):print('\nEpoch: %d' % (epoch + 1))net.train()sum_loss = 0.0correct = 0.0total = 0.0for i, data in enumerate(trainloader, 0):# 准备数据length = len(trainloader)inputs, labels = datainputs, labels = inputs.to(device), labels.to(device)optimizer.zero_grad()# forward + backwardoutputs = net(inputs)loss = criterion(outputs, labels)loss.backward()optimizer.step()# 每训练1个batch打印一次loss和准确率sum_loss += loss.item()_, predicted = torch.max(outputs.data, 1)total += labels.size(0)correct += predicted.eq(labels.data).cpu().sum()print('[epoch:%d, iter:%d] Loss: %.03f | Acc: %.3f%% '% (epoch + 1, (i + 1 + epoch * length), sum_loss / (i + 1), 100. * correct / total))f2.write('%03d  %05d |Loss: %.03f | Acc: %.3f%% '% (epoch + 1, (i + 1 + epoch * length), sum_loss / (i + 1), 100. * correct / total))f2.write('\n')f2.flush()# 每训练完一个epoch测试一下准确率print("Waiting Test!")with torch.no_grad():correct = 0total = 0for data in testloader:net.eval()images, labels = dataimages, labels = images.to(device), labels.to(device)outputs = net(images)# 取得分最高的那个类 (outputs.data的索引号)_, predicted = torch.max(outputs.data, 1)total += labels.size(0)correct += (predicted == labels).sum()print('测试分类准确率为:%.3f%%' % (100 * correct / total))acc = 100. * correct / total# 将每次测试结果实时写入acc.txt文件中print('Saving model......')torch.save(net.state_dict(), '%s/net_%03d.pth' % (args.outf, epoch + 1))f.write("EPOCH=%03d,Accuracy= %.3f%%" % (epoch + 1, acc))f.write('\n')f.flush()# 记录最佳测试分类准确率并写入best_acc.txt文件中if acc > best_acc:f3 = open("best_acc.txt", "w")f3.write("EPOCH=%d,best_acc= %.3f%%" % (epoch + 1, acc))f3.close()best_acc = accprint("Training Finished, TotalEPOCH=%d" % EPOCH)

实验结果:best_acc= 95.170%


(损失图是matlab画的,用保存下来的txt日志)

Pytorch实战2:ResNet-18实现Cifar-10图像分类(测试集分类准确率95.170%)相关推荐

  1. Pytorch实战:8层神经网络实现Cifar-10图像分类验证集准确率94.71%

    实验环境: Pytorch 1.7.0 torchvision 0.8.2 Python 3.8 CUDA10.2 + cuDNN v7.6.5 Win10 + Pycharm GTX1660, 6G ...

  2. PyTorch实战使用Resnet迁移学习

    PyTorch实战使用Resnet迁移学习 项目结构 项目任务 项目代码 网络模型测试 项目结构 数据集存放在flower_data文件夹 cat_to_name.json是makejson文件运行生 ...

  3. [深度学习-TF2实践]应用Tensorflow2.x训练ResNet,SeNet和Inception模型在cifar10,测试集上准确率88.6%

    环境 tensorflow 2.1 最好用GPU Cifar10数据集 CIFAR-10 数据集的分类是机器学习中一个公开的基准测试问题.任务的目标对一组32x32 RGB的图像进行分类,这个数据集涵 ...

  4. [深度学习-实践]Tensorflow 2.x应用ResNet SeNet网络训练cifar10数据集的模型在测试集上准确率 86%-87%,含完整代码

    环境 tensorflow 2.1 最好用GPU Cifar10数据集 CIFAR-10 数据集的分类是机器学习中一个公开的基准测试问题.任务的目标对一组32x32 RGB的图像进行分类,这个数据集涵 ...

  5. pytorch MNIST 手写数字识别 + 使用自己的测试集 + 数据增强后再训练

    文章目录 1. MNIST 手写数字识别 2. 聚焦数据集扩充后的模型训练 3. pytorch 手写数字识别基本实现 3.1完整代码及 MNIST 测试集测试结果 3.1.1代码 3.1.2 MNI ...

  6. 黑客攻防技术宝典Web实战篇第2版—第10章 测试后端组件

    10.1 注入操作系统命令 1.许多时候,开发者直接向服务器发送操作系统指令,但如果应用程序向操作系统发送用户输入指令,可能受到命令注入攻击.通常所有的注入命令都可在Web服务器的进程中安全运行,使得 ...

  7. 基于SVM的思想做CIFAR 10图像分类

    #SVM 回顾一下之前的SVM,找到一个间隔最大的函数,使得正负样本离该函数是最远的,是否最远不是看哪个点离函数最远,而是找到一个离函数最近的点看他是不是和该分割函数离的最近的. 使用large ma ...

  8. 【Pytorch实战4】基于CIFAR10数据集训练一个分类器

    参考资料: <深度学习之pytorch实战计算机视觉> Pytorch官方教程 Pytorch中文文档 先是数据的导入与预览. import torch import torchvisio ...

  9. [NLP]基于IMDB影评情感分析之BERT实战-测试集上92.24%

    系列文章目录 深度学习NLP(一)之Attention Model; 深度学习NLP(二)之Self-attention, Muti-attention和Transformer; 深度学习NLP(三) ...

最新文章

  1. 独家 | 用spaCy蒸馏BERT模型
  2. linux 搭建Tomcat
  3. 移动端微信页面的一些自己爬的坑
  4. C++ Opengl 绘制图像字符源码
  5. 20165313 《Java程序设计》第七周学习总结
  6. 天线接收功率计算公式_对讲机天线到底有多重要?通信效果好不好全靠它了!...
  7. koa2 仿知乎笔记
  8. 机器学习系列(九)【最大熵模型】
  9. Linux的shell中echo改变输出显示样式
  10. gotoxy函数定义
  11. java bat运行jar文件_利用.bat文件运行jar文件
  12. 高阶的Parser:可变运算优先级
  13. bandicom录屏音画不同步_bandicam录屏工具
  14. CRM客户管理系统搭建
  15. 异地如何在北京换驾照
  16. matlab实现色彩迁移,图像的色彩风格迁移
  17. 独立键盘检测,矩阵键盘检测
  18. 前端学习——HTML初学__6 HTML常用标签(3)
  19. 中国程序员最容易读错的70个英文单词,非常值得一看!
  20. 简单服务端和客户端的开发

热门文章

  1. ug11许可证文件路径安装在哪_UG NX10.0建模模板文件路径在什么位置可以找到?...
  2. Spring--基于AOP实现事务控制
  3. jrebel热部署插件激活密钥
  4. 喊话程序员:Sketch设计作图切图利器,你值得拥有。
  5. mysql返回值concat函数拼接,if函数,CASE WHEN函数条件判断。
  6. WMS仓库管理系统---(13)订单管理--创建订单
  7. 前端项目写入数据库中文乱码
  8. 如何在淘宝发起知识产权投诉?
  9. 36匹马赛跑,跑道同时只能容许6匹马。而且36匹马速度不同,但是每次跑的速度恒定。 问跑多少次可以选出第一,第二,第三名?
  10. C语言编程——输入三个整数x,y,z,请把这三个数由小到大输出