• 5、实战:CIFAR-10分类


    与其他教程不一样的地方是加载的本地已下载数据(代码中下载速度太慢)。关于数据集的说明点击此链接

    1、下载数据集,复制此链接到迅雷下载 http://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz

    2、解压到E:/data目录中,

    3、jupyter中撸代码

    【说明】

    ①   Dataloader是一个可迭代的对象,它将datasets返回的每一条数据样本拼接成一个batch,并可以多线程加速优化、数据打乱等操作。

      当datasets的所有数据遍历一遍之后,对Dataloader也完成了一次迭代。

    ②    Dataloader类型与datasets一样返回数据、标签索引,不过Dataloader是以batch为单位返回的,即batch_size个元素组成的向量。

    【步骤】

    1、使用torchvision加载并预处理数据集
    2、定义网络
    3、定义损失函数和优化器
    4、训练网络并更新网络参数
    5、测试网络

    ######################################## 1、使用torchvision加载并预处理数据集
    import torch as t
    import torchvision as tv
    import torchvision.transforms as transforms
    from torchvision.transforms import ToPILImage
    
    #定义对数据的预处理
    transform=transforms.Compose([
        transforms.ToTensor(), #转为Tensor
        transforms.Normalize((0.5,0.5,0.5),(0.5,0.5,0.5))]) #归一化,到[-1,1]
    #训练集
    #torchvision datasets 的输出是 PILImage 类型的 images, 像素取值范围在 [0, 1]。 
    #我们将其变换为归一化范围在[-1 , 1] 的 Tensors 类型
    trainset=tv.datasets.CIFAR10(
        root="E:/data", #注意我的路径
        train=True,
        download=False, #注意不下载
        transform=transform) #载入数据的时候,转换为Tensor类型,并归一化到[-1,1]
    trainloader=t.utils.data.DataLoader(
        trainset,
        batch_size=4, #batch大小
        shuffle=True, #打乱
        num_workers=2) #2个线程
    #测试集
    testset=tv.datasets.CIFAR10(
        root="E:/data",
        train=False,
        download=False,
        transform=transform)
    testloader=t.utils.data.DataLoader(
        testset,
        batch_size=4,
        shuffle=False,
        num_workers=2)
    #类别标签
    classes=("plane","car","bird","cat","deer","dog","frog","horse","ship","truck")

    显示datasets中的第一幅图

    (data,label)=trainset[0] #获取数据集的第一个元素,返回数据和标签索引
    print(classes[label]) #label是6
    show=ToPILImage() #把Tensor转成Image,方便可视化
    show((data+1)/2).resize((100,100)) #(data+1)/2反归一化[-1,1]为[0,1],resize把32×32图变为100×100

    显示Dataloader中的第一批图(4幅图为1个batch)

    # 随机获取4张训练集图片(trainloader中4个元素为一批(batch))
    dataiter = iter(trainloader)
    (images, labels) = dataiter.next() #以batch为单位,Dataloader类型与datasets一样返回数据、标签索引
    print(labels)
    # 输出对应的标签
    print(' '.join('%s' % classes[labels[j]] for j in range(4)))
    # 显示图像
    show(tv.utils.make_grid((images+1)/2)).resize((400,100)) #显示4个图
    #show((images[0]+1)/2).resize((100,100)) #显示第一个图

    ######################################## 2、定义网络
    import torch.nn as nn
    import torch.nn.functional as F
    
    class Net(nn.Module): #定义网络类,继承自nn.Module
        def __init__(self): #类的构造函数
            super(Net,self).__init__() #执行一次父类的构造函数(硬性要求),等价于 nn.Module.__init__(self)
            ## 卷积层
            self.conv1=nn.Conv2d(3,6,5) #输入图像 3 个通道, 6 个输出通道, 5x5 方形卷积核
            self.conv2=nn.Conv2d(6,16,5) #上层的6作为此层的输入,输出16通道,5x5
            ## 仿射层/全连接层,y=Wx+b
            self.fc1=nn.Linear(16*5*5,120)
            self.fc2=nn.Linear(120,84)
            self.fc3=nn.Linear(84,10)
            
        def forward(self, x): #卷积→激活→池化
            # 最大池化的窗口大小(2, 2)
            x = F.max_pool2d(F.relu(self.conv1(x)), (2, 2))
            # 如果池化窗口是方形的,你只需要指定单个数字
            x = F.max_pool2d(F.relu(self.conv2(x)), 2)
            #-1代表自适应,reshape
            x = x.view(x.size()[0],-1)
            x = F.relu(self.fc1(x))
            x = F.relu(self.fc2(x))
            x = self.fc3(x)
            return x
    
    net = Net()
    print(net)

    ######################################## 3、定义损失函数和优化器
    from torch import optim
    criterion=nn.CrossEntropyLoss() #交叉熵损失函数
    optimizer=optim.SGD(net.parameters(),lr=0.001,momentum=0.9) #随机梯度下降法,指定要调整的参数和学习率,动量算法加速更新权重

    所有网络的训练流程都类似,流程如下:

    输入数据
    前向传播+反向传播
    更新参数

    ######################################## 4、训练网络并更新网络参数
    for epoch in range(2):  # 在整个数据集上轮番训练多次,轮训一次叫一个回合(epoch)
    
        running_loss = 0.0
        for i, data in enumerate(trainloader, 0):
            
            # 输入数据
            inputs, labels = data
    
            # 梯度清零
            optimizer.zero_grad()
    
            # forward + backward
            outputs = net(inputs)
            loss = criterion(outputs, labels)
            loss.backward()
            
            #更新参数
            optimizer.step()
    
            # 打印一些关于训练的统计信息
            running_loss += loss.item()
            if i % 2000 == 1999:    # 每 2000 个batch打印一次
                print('[%d, %5d] loss: %.3f' %
                      (epoch + 1, i + 1, running_loss / 2000))
                running_loss = 0.0
    
    print('Finished Training')

    训练了2个回合,下面进行测试,输入图片,预测label与真实label比较

    ######################################## 5、测试网络
    #获取datasets测试集中的前4幅图,并输出标签 dataiter = iter(testloader) (images, labels) = dataiter.next() #返回1个batch(4张图) # 输出图像和正确的类标签 print('实际的label:', ' '.join('%5s' % classes[labels[j]] for j in range(4))) show(tv.utils.make_grid((images+1)/2)).resize((400,100))

    #测试上述的4幅图,并输出标签
    outputs = net(images) #预测上边得到的batch(4张图),返回得分(每一类都打分)
    _, predicted = t.max(outputs, 1) #每1张图得分最高的那个类的下标
    
    print(outputs)
    print(predicted)
    print('预测结果:', ' '.join('%5s' % classes[predicted[j]] for j in range(4)))

    #测试整个测试集
    correct = 0 #预测正确的图片数
    total = 0 #总共的图片数
    with t.no_grad():
        for data in testloader:
            images, labels = data
            outputs = net(images)
            _, predicted = t.max(outputs.data, 1)
            total += labels.size(0)
            correct += (predicted == labels).sum().item()
    
    print('10000张测试集中的准确率: %d %%' % (100 * correct / total))

    在GPU上训练

    ######################################## 在GPU上训练
    if t.cuda.is_available():
        net.cuda() #net、images、labels都要迁移到GPU上
        images=images.cuda()
        labels=labels.cuda()
        output=net(images)
        loss=criterion(output,labels) #用上文选定的损失函数计算损失
        print(loss)

  • 相关阅读:
    尚硅谷面试第一季-05递归与迭代
    尚硅谷面试第一季-04方法的参数传递机制
    尚硅谷面试第一季-03类初始化和实例初始化
    python爬爬爬之单网页html页面爬取
    python之花瓣美女下载
    (转载博文)VC++API速查
    (转载博文)MFC 窗口句柄获取
    全局变量的声明
    python图片小爬虫
    Opencv2.4.4作图像旋转和缩放
  • 原文地址:https://www.cnblogs.com/xixixing/p/12752024.html
Copyright © 2020-2023  润新知