- 前言:这个博客是在学习完哔哩哔哩up主小土堆的pytorch教学视频后,根据个人理解来完成的学习笔记,如果需要系统的pytorch入门,请点击PyTorch深度学习快速入门教程(绝对通俗易懂!)【小土堆】_哔哩哔哩_bilibili。本系列博客的目的是给个人学习做笔记,如有学术问题欢迎私信随时交流探讨。
- 背景:
- 机器学习是一门多领域交叉学科,涉及概率论、统计学、逼近论、凸分析、算法复杂度理论等多门学科。专门研究计算机怎样模拟或实现人类的学习行为,以获取新的知识或技能,重新组织已有的知识结构使之不断改善自身的性能。(来源百度百科)
- 搭建一个机器学习的框架:以CIFAR10分类为例
- (注:选择这个分类算法的原因是在哔哩哔哩up主我是土堆刚好学完分类算法的模型搭建,第一篇文章就从比较熟悉的流程说起)
- 前提:anaconda,pycharm的安装,如有不会的可以在CSDN中找相关帖子或推荐UP主视频。
- conda环境搭建
- conda env list#查看安装的环境
- activate CIFAR10 #激活环境
- conda create -n CIFAR10 python==3.7#创建环境
- activate CIFAR10 #激活环境
- conda deactivate #退出环境
- conda install package_name #在当前环境中安装包
- 2 在pycharm中创建CIFAR10环境的项目.
- 选择合适的环境即可
- 搭建学习框架
- 回到原始论文中学习框架。
- 导入训练数据,其中LeNet-5是3@28*28的图像,CIFAR10-quick是3@32*32的图像。意思是LeNet-5是三通道(RGB),图像大小为28*28个像素
- 导入训练数据
- 首先安装pytorch包
- 找到Command Prompt,进入CIFAR10的环境即可
- pip install torch等包
- 加载数据
-
#准备数据集 dataset= torchvision.datasets.CIFAR10("../dataset/CIFAR10",train=True,transform=torchvision.transforms.ToTensor(),download=True) testset =torchvision.datasets.CIFAR10("../dataset/CIFAR10",train=False,transform=torchvision.transforms.ToTensor(),download=True) # 训练集中的80%作为训练集,20%作为验证集 train_size = int(0.8*len(dataset)) test_size = len(dataset) - train_size lengths = [train_size, test_size] train_dataset, valid_dataset = torch.utils.data.dataset.random_split(dataset, lengths) # 加载数据 trainloader = DataLoader(train_dataset, batch_size=64, shuffle=True) validloader = DataLoader(valid_dataset, batch_size=64, shuffle=True)
- 搭建模型
-
参数含义解释:padding计算按照下方公式
from torch import nn
class CIFAR10_model(nn.Module):
def __init__(self):
super(CIFAR10_model, self).__init__()#sequent中为网络架构
#模型架构
# img = torchvision.io.read_image("./img.png")
# print(img)
self.CIFmodel =nn.Sequential(#CIFAR10模型
nn.Conv2d(3,32,(5,5),stride=1,padding=2,dilation=1),
nn.MaxPool2d((2,2),2),
nn.Conv2d(32,32,(5,5),stride=1,padding=2),
nn.MaxPool2d((2,2),stride=2),
nn.Conv2d(32,64,kernel_size=(5,5),stride=1,padding=2),
nn.MaxPool2d((2,2),2),
nn.Flatten(),
nn.Linear(64*4*4,64),
nn.Linear(64,10)
)
self.LENETmodel=nn.Sequential(#LENET模型
nn.Conv2d(in_channels=3, out_channels=20, kernel_size=(5, 5), stride=1, dilation=1),
nn.MaxPool2d((2, 2), 2, 0),
nn.Conv2d(20, 50, 5, 1, 0),
nn.MaxPool2d(2),
nn.Flatten(),
nn.Linear(50 * 4 * 4, 500),
nn.Linear(500, 10)
)
def forward(self,x,model_type):#x为传入的参数,调用CIFAR10类的时候会调用forward函数,在forward中将参数传入到模型中
#对传入的模型种类做个判断
if model_type=="CIFAR10":
x=self.CIFmodel(x)
else:
x= self.LENETmodel(x)
return x
# model = CIFAR10_model()
# data = torch.ones((1,3,28,28))
# print(data.shape)
# output = model(data,"LT")
# print(output.shape)
- 设置损失函数
- 设置优化器
- 设置训练次数
- 模型训练开始
-
#构建损失函数 loss_fun = nn.CrossEntropyLoss() loss_fun.to(device) #learnrate, 优化器设置 learningrate=0.01 momentum=0.01 optimizer=torch.optim.SGD(model.parameters(),lr=learningrate,momentum=momentum) #设置训练次数 total_train_step=0 total_test_step=0 epoch = 100 for i in range(epoch): print("---------------第{}轮训练开始---------".format(i + 1)) for data in trainloader: #定义一次的训练 imgs,targets = data imgs=imgs.to(device) targets=targets.to(device) output=model(imgs,model_type) loss=loss_fun(output,targets) optimizer.zero_grad() loss.backward() optimizer.step() #一次训练完成 total_train_step=total_train_step+1 if total_train_step%100==0: print("第{}次训练结束,loss是:{}".format(total_train_step,loss)) total_test_loss=0 total_accuracy = 0 with torch.no_grad: for data in testloader: imgs, targets = data imgs = imgs.to(device) targets = targets.to(device) output = model(imgs,model_type) loss = loss_fun(output,targets) total_test_loss=total_test_loss+loss accuracy = (output.argmax(1)==targets).sum() total_accuracy = total_accuracy+accuracy print("整体测试集中的loss:{}".format(total_test_loss.item())) print("整体测试集中的准确率:{}".format(total_accuracy /total_test_size)) total_test_step = total_test_step + 1