LeNet图像分类网络二(Pytorch)

同样地,官方地址在这里https://pytorch.org/tutorials/beginner/blitz/cifar10_tutorial.html#sphx-glr-beginner-blitz-cifar10-tutorial-py
在正式训练网络之前,我们要下载数据集,用pythorch自带的库可以很方便的实现下载。下面是下载CIFAR10,并且展示图片的代码:

import torch
import torchvision      #torchvision是pytorch的一个图形库,主要用来构建计算机视觉模型,
                        # 可以用来下载数据
import torchvision.transforms as transforms #用于图形变换
import matplotlib.pyplot as plt
import numpy as np
if __name__ == '__main__':
        transform = transforms.Compose(    #用于串联多个图片变换的操作
            [transforms.ToTensor(),    #将图片转换为张量形式
             transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])  #归一化
        trainset = torchvision.datasets.CIFAR10(root='./data', train=True,     #下载训练集的数据
                                                download=True, transform=transform)
        #组合数据集和样本。数据集是trainset,每批次加载4张图,true表示重新混合,有2个子流程用于数据加载
        trainloader = torch.utils.data.DataLoader(trainset, batch_size=4,
                                                  shuffle=True, num_workers=2)
        testset = torchvision.datasets.CIFAR10(root='./data', train=False,      #下载测试集的数据
                                               download=True, transform=transform)
        testloader = torch.utils.data.DataLoader(testset, batch_size=4,
                                                 shuffle=False, num_workers=2)
        classes = ('plane', 'car', 'bird', 'cat',
                   'deer', 'dog', 'frog', 'horse', 'ship', 'truck')
        def imshow(img):       #用以展示图片的函数
            img = img / 2 + 0.5     # unnormalize,非规范化
            npimg = img.numpy()     #image转为numpy类
            plt.imshow(np.transpose(npimg, (1, 2, 0)))  #改变数组的排列顺序,这样才可以展示
            plt.show()   #显示图片,只用上面那一行是使用不了的
        # get some random training images
        dataiter = iter(trainloader)        #获取训练集的图像和标签
        images, labels = dataiter.next()
        # show images
        imshow(torchvision.utils.make_grid(images))   #输出图象
        # print labels
        print(' '.join('%5s' % classes[labels[j]] for j in range(4)))  #输出标签

如果下载失败,可以根据提示去网站上下载,放到程序中指定的位置就可以了。

结果:
在这里插入图片描述
在这里插入图片描述
训练网络的代码如下,是可以直接运行的。

import torch
import torch.nn as nn
import torch.nn.functional as F
import torchvision
import torchvision.transforms as transforms #用于图形变换
import torch.optim as optim
if __name__ == '__main__':
    #################前面是建立网络部分###################
    class Net(nn.Module):
        def __init__(self):
            super(Net,self).__init__()
            self.conv1 = nn.Conv2d(3,6,5)
            self.conv2 = nn.Conv2d(6,16,5)
            self.fc1 = nn.Linear(400,120)
            self.fc2 = nn.Linear(120,84)
            self.fc3 = nn.Linear(84,10)
        def forward(self,x):
            x = F.max_pool2d(F.relu(self.conv1(x)),(2,2))
            x = F.max_pool2d(F.relu(self.conv2(x)),(2,2))
            x = x.view(-1, self.num_flat_features(x))
            x = F.relu(self.fc1(x))
            x = F.relu(self.fc2(x))
            x = self.fc3(x)
            return x
        def num_flat_features(self,x):
            size = x.size()[1:]
            num_features = 1
            for s in size:
                num_features *= s
            return num_features
    net = Net()
    #定义损失函数和优化器
    criterion = nn.CrossEntropyLoss()    #定义损失函数的类型为cross-entorpy
    optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)  #优化器为SGD类型
    ###########################网络搭建成功##########################
    #加载数据集
    transform = transforms.Compose(  # 用于串联多个图片变换的操作
        [transforms.ToTensor(),  # 将图片转换为张量形式
         transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])  # 归一化
    trainset = torchvision.datasets.CIFAR10(root='./data', train=True,  # 下载训练集的数据
                                            download=True, transform=transform)
    # 组合数据集和样本。数据集是trainset,每批次加载4张图,true表示重新混合,有2个子流程用于数据加载
    trainloader = torch.utils.data.DataLoader(trainset, batch_size=4,
                                              shuffle=True, num_workers=2)
    testset = torchvision.datasets.CIFAR10(root='./data', train=False,  # 下载测试集的数据
                                           download=True, transform=transform)
    testloader = torch.utils.data.DataLoader(testset, batch_size=4,
                                             shuffle=False, num_workers=2)
    classes = ('plane', 'car', 'bird', 'cat',
               'deer', 'dog', 'frog', 'horse', 'ship', 'truck')
    #开始训练网络
    for epoch in range(2):  # 多次遍历数据集
        running_loss = 0.0
        for i, data in enumerate(trainloader, 0):
            # get the inputs; data is a list of [inputs, labels]
            inputs, labels = data
            # zero the parameter gradients
            optimizer.zero_grad()      #将梯度参数清零
            # forward + backward + optimize
            outputs = net(inputs)   #网络的输出
            loss = criterion(outputs, labels)   #计算误差
            loss.backward()            #反向传播
            optimizer.step()      #权重更新
            # print statistics
            running_loss += loss.item()
            if i % 2000 == 1999:    # print every 2000 mini-batches
                print('[%d, %5d] loss: %.3f' %
                      (epoch + 1, i + 1, running_loss / 2000))
                running_loss = 0.0
    print('Finished Training')
    #将训练好的网络参数保存起来
    PATH = './cifar_net.pth'
    torch.save(net.state_dict(), PATH)

程序会输出训练过程中网络的误差,可以看到它是在逐渐减小的。
在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用PyTorch实现LeNet图像分类算法的步骤: 1.导入必要的Python库和PyTorch库: ``` import torch import torch.nn as nn import torch.nn.functional as F import torch.optim as optim from torchvision import datasets, transforms ``` 2.定义LeNet模型的类: ``` class LeNet(nn.Module): def __init__(self): super(LeNet, self).__init__() self.conv1 = nn.Conv2d(1, 6, kernel_size=5) self.conv2 = nn.Conv2d(6, 16, kernel_size=5) self.fc1 = nn.Linear(16*4*4, 120) self.fc2 = nn.Linear(120, 84) self.fc3 = nn.Linear(84, 10) def forward(self, x): x = F.relu(self.conv1(x)) x = F.max_pool2d(x, 2) x = F.relu(self.conv2(x)) x = F.max_pool2d(x, 2) x = x.view(-1, 16*4*4) x = F.relu(self.fc1(x)) x = F.relu(self.fc2(x)) x = self.fc3(x) return F.log_softmax(x, dim=1) ``` 这个类定义了一个包含两个卷积层和三个全连接层的LeNet模型。在forward()函数中,图像首先经过两个卷积层和两个max-pooling层,然后被展平成一维张量,最后通过三个全连接层和一个log_softmax层输出概率分布。 3.加载数据集: ``` transform = transforms.Compose([ transforms.ToTensor(), transforms.Normalize(mean=(0.1307,), std=(0.3081,)) ]) train_dataset = datasets.MNIST('data', train=True, download=True, transform=transform) test_dataset = datasets.MNIST('data', train=False, download=True, transform=transform) train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=64, shuffle=True) test_loader = torch.utils.data.DataLoader(test_dataset, batch_size=1000, shuffle=True) ``` 这里使用PyTorch中的MNIST数据集,将图像转换为张量并进行归一化处理。数据集被拆分为训练集和测试集,并使用DataLoader将它们加载到内存中。训练集的batch size为64,测试集的batch size为1000。 4.定义优化器和损失函数: ``` model = LeNet() optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.5) criterion = nn.NLLLoss() ``` 这里使用随机梯度下降(SGD)作为优化器,学习率为0.01,动量为0.5。损失函数使用负对数似然损失(NLLLoss)。 5.训练模型: ``` epochs = 10 for epoch in range(epochs): for data, target in train_loader: optimizer.zero_grad() output = model(data) loss = criterion(output, target) loss.backward() optimizer.step() test_loss = 0 correct = 0 with torch.no_grad(): for data, target in test_loader: output = model(data) test_loss += criterion(output, target).item() pred = output.argmax(dim=1, keepdim=True) correct += pred.eq(target.view_as(pred)).sum().item() test_loss /= len(test_loader.dataset) accuracy = 100. * correct / len(test_loader.dataset) print('Epoch: {} | Test Loss: {:.4f} | Accuracy: {:.2f}%'.format(epoch+1, test_loss, accuracy)) ``` 在每个epoch中,对于训练集中的每个batch,使用前向传播计算输出,使用反向传播计算梯度并更新模型参数。对于测试集,使用前向传播计算输出并计算损失和准确率。最后将测试损失和准确率输出。 6.测试模型: ``` model.eval() with torch.no_grad(): for data, target in test_loader: output = model(data) pred = output.argmax(dim=1, keepdim=True) print(pred.view_as(target)[:10]) break ``` 这里使用model.eval()将模型切换到测试模式,然后对测试集中的第一个batch进行前向传播并输出前10个预测结果。 以上就是使用PyTorch实现LeNet图像分类算法的步骤。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值