cifar10训练作业

main函数

import torch
from torch.utils.data import DataLoader   #多线程 方便一次加载多个
from torchvision import datasets
from torchvision import transforms       #转换函数包
from torch import nn ,optim         #optim 是优化器
from lenet5 import  Lenet5
# 全局取消证书验证

import ssl
ssl._create_default_https_context = ssl._create_unverified_context



def main():
    batchsz= 32          #批量加入图片的数量

    """
    'cifar' 就是在当前目录下面新建一个叫做cifar的文件夹,train=ture ??(是否训练嘛?)
    transform 就是对数据集做一些变换  
    resize 大小维度的转换
    totensor 转换成为 tensor
    """


    cifar_train  =datasets.CIFAR10('cifar',True,transform=transforms.Compose([
        transforms.Resize((32,32)),
        transforms.ToTensor()
    ]),download=True)
    cifar_train= DataLoader(cifar_train,batch_size=batchsz,shuffle=True)   #DataLoader允许一次加载多张照片(一定注意大小写) shuffle 参数为是否需要随机化

    cifar_test  =datasets.CIFAR10('cifar',False,transform=transforms.Compose([
        transforms.Resize((32,32)),
        transforms.ToTensor()
    ]),download=True)
    cifar_test= DataLoader(cifar_test,batch_size=batchsz,shuffle=True)



    x,label=iter(cifar_train).next()   #迭代器  没有搞懂iter函数的作用
    print('x:',x.shape,'label:',label.shape)  #简单的测试下是否成功

    device=torch.device('cuda')
    model=Lenet5().to(device)
    # CrossEntropyLoss里面已经包含了softmax函数,所以传入里面的是logits
    criteon=nn.CrossEntropyLoss().to(device)   #  .to(device) 是将运算转化到之前定义的设备上面去的(GPU)

    optimizer =optim.Adam(model.parameters(),lr=1e-3)       #里面传入需要优化的参数   lr 是learning  rate
    print(model)                      #方便打印出类的结构

    for epoch in range(1000):

        model.train()    #将模式设置为训练模式,因为有些函数(例如batchnormolize dropout计算方式)  注意拼写啊train train train train
        for batchsz,(x,label) in enumerate(cifar_train):
            # x:[b,3,32,32]
            # label :[b]
            x,label=x.to(device),label.to(device)

            logits=model(x)
            #logits:[b,10]
            #label:[b]
            #loss: tensor scalar  loss 是一个长度为零的标量
            loss=criteon(logits,label)

            #backprop  经典的三步
            optimizer.zero_grad()  #需要将梯度清零,如果不清零,则是累加的过程
            loss.backward()        #梯度计算
            optimizer.step()

        #
        print(epoch,loss.item())

        #test(测试的部分)
        model.eval()
        with torch.no_grad():   #由于这里是测试部分,不需要进行梯度更新,所以将其包裹再 torch.no_grad()函数里面
            total_num=0
            total_correct=0
            for x,label in cifar_test:
                # x:[b,3,32,32]
                # label :[b]
                x,label=x.to(device),label.to(device)   #注意拼写 label  label label label label
                #[b,10]
                logits=model(x) #modle是lenet5的实例化对象,送入里面返回处预测标签
                pred=logits.argmax(dim=1)   #注意 argmax 和max的区别   前者返回最大值索引下标,后者返回最大值的数值
                # """
                # [2       [2                 [1
                #  1  eq    0      返回值为: => 0     转换为浮点数(?)后 ,再用sum函数求和  =>2     item() 由tensor转化为numpy
                #  1]       1]                 1]
                # """
                total_correct+=torch.eq(pred,label).float().sum().item()
                total_num+=x.size(0)

            acc=total_correct/total_num
            print("当前epoch :{} ,当前准确率:{}".format(epoch,acc))



if __name__ == '__main__':
    main()

LENET文件

import torch
from torch import nn
from torch.nn import functional  as F


class Lenet5(nn.Module):   #定义的一个类,继承自 nn.Module
    """
    for cifar10 dataset.
    """
    def __init__(self):
        super(Lenet5,self).__init__()   #继承  具体什么东西现在还没有搞明白

        self.conv_unit=nn.Sequential(  #将网络包在这个结构里面  卷积单元
            #前面输入的 x: [b,3,32,32]=>x: [b,6,28,28]
            nn.Conv2d(3,6,kernel_size=5,stride=1,padding=0),  #使用此方法来新建一个卷积层
            nn.AvgPool2d(kernel_size=2,stride=2,padding=0),
            #
            nn.Conv2d(6,16,kernel_size=5,stride=1,padding=0),
            nn.AvgPool2d(kernel_size=2,stride=2,padding=0),
            #根据Lenet的结构,下面的那一层是全连接层,需要打平的,所以将上面???的Module替换成为了conv_unit
            #为什么不在这里实现打平操作呢? 是因为nn.Sequential() 里面的操作都需要来自nn.里面的方法,而pytorch无打平操作
        )
        #flatten  打平操作 没写
        #fc unit
        self.fc_unit =nn.Sequential(
            nn.Linear(16*5*5,120),  #这里因为不知道上面输出的维度是多少,所以先填写2作为占位符
            nn.ReLU(),            #激活函数
            nn.Linear(120,84),
            nn.ReLU(),
            nn.Linear(84,10)
        )

        """
        下面这段代码用于测试conv_unit 的输出的维度形状
        [b,3,32,32]
        """
        tmp=torch.randn(2,3,32,32)
        out=self.conv_unit(tmp)
        #测试结果输出为[b,16,5,5]
        print("out.shape is:",out.shape)

        #use Cross Entropy Loss
        self.criteon =nn.CrossEntropyLoss   #交叉熵

    def forward(self,x):
        """
        :param x:[]
        :return:
        """
        batchsz=x.size(0)  # x.size()返回一个size表,而0号位置处就是图片的个数(batchsz)
        #[b,3,32,32]=>[b,16,5,5]
        x=self.conv_unit(x)
        #[b,16,5,5]=>[b,16*5*5]

        #第一次写时,这里出了大问题,维度转换view函数的用法 x=x.view()

        x=x.view(batchsz,-1) #view函数用于维度转换,相当于实现打平的操作,打平(flatten)后才能送入全连接层
        #送入全连接层,[b,16*5*5]=>[b,10]
        logits=self.fc_unit(x)  #在logits输入后,一般都还要送入一个softmax()函数,送入之前的tensor成为logits

        # #送入softmax函数,转换成标准概率
        # pred= F.softmax(logits,dim=1) #logits的格式是[b,10] 所以处理的维度是dim=1
        # loss=self.criteon(logits,y)

        return logits


def main():

    net=Lenet5()
    tmp = torch.randn(2, 3, 32, 32)
    out = net(tmp)
    print('lenet out:',out.shape)


if  __name__=='__main__':
    main()



----------------------------------------

----------------------------------------

----------------------------------------

----------------------------------------

运行结果:
0 1.2656571865081787
当前epoch :0 ,当前准确率:0.4524
1 1.4220787286758423
当前epoch :1 ,当前准确率:0.4927
2 0.9537531137466431
当前epoch :2 ,当前准确率:0.5178
3 1.113728404045105
当前epoch :3 ,当前准确率:0.5216
4 1.3806077241897583
当前epoch :4 ,当前准确率:0.5441
5 0.9763231873512268
当前epoch :5 ,当前准确率:0.5368
6 0.813972532749176
当前epoch :6 ,当前准确率:0.5436
7 0.949809193611145
当前epoch :7 ,当前准确率:0.5496
8 1.1697014570236206
当前epoch :8 ,当前准确率:0.538
9 1.0288864374160767
当前epoch :9 ,当前准确率:0.5554
10 1.2099034786224365
当前epoch :10 ,当前准确率:0.5553
11 2.150331497192383
当前epoch :11 ,当前准确率:0.5511
12 1.0876156091690063
当前epoch :12 ,当前准确率:0.5483
13 0.7157190442085266
当前epoch :13 ,当前准确率:0.5526
14 0.6226208806037903
当前epoch :14 ,当前准确率:0.5489
15 0.8635637164115906
当前epoch :15 ,当前准确率:0.5476
16 0.7294909954071045
当前epoch :16 ,当前准确率:0.552
17 1.023239254951477
当前epoch :17 ,当前准确率:0.5402
18 0.8226995468139648
当前epoch :18 ,当前准确率:0.5475
19 0.6349995732307434
当前epoch :19 ,当前准确率:0.5425
20 0.49438467621803284
当前epoch :20 ,当前准确率:0.5468
21 1.0320965051651
当前epoch :21 ,当前准确率:0.5395

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值