当前位置:   article > 正文

Pytorch深度学习——用全连接神经网络实现MNIST数据集分类_利用多层全连接神经网络及简单卷积神经网络对mnist数据集分类

利用多层全连接神经网络及简单卷积神经网络对mnist数据集分类

目录

1 准备数据集

2 建立模型       

3 构建损失函数和优化器

4 训练+测试

5 完整代码+运行结果

6 遇到问题


       我们之前学习的案例中,输入x都是一个向量;在MNIST数据集中,我们需要输入的是一个图像,怎样,图像怎么才能输入到模型中进行训练呢?一种方法是我们可以把图像映射成一个矩向量,再输入到模型中进行训练。

        怎样将一个图像映射成一个向量?

        如图所示是MNIST数据集中一个方格的图像,它是由28x28=784个像素组成,其中越深的地方数值越接近0,越亮的地方数值越接近1。

         因此可以将此图像按照对应的像素和数值映射成一个28x28的一个矩阵,如下图所示:


1 准备数据集

具体代码如下:

  1. # 准备数据集
  2. batch_size = 64
  3. transform = transforms.Compose([
  4.     transforms.ToTensor(),
  5. #均值、标准差
  6.     transforms.Normalize((0.1307, ), (0.3081, ))
  7. ])
  8. train_dataset = datasets.MNIST(root='../dataset/mnist/',
  9.                                train=True,
  10.                                download=True,
  11.                                transform=transform)
  12. train_loader = DataLoader(train_dataset,
  13.                           shuffle=True,
  14.                           batch_size=batch_size)
  15. test_dataset = datasets.MNIST(root='../dataset/mnist',
  16.                               train=False,
  17.                               download=True,
  18.                               transform=transform)
  19. test_loader = DataLoader(test_dataset,
  20.                          shuffle=False,
  21.                          batch_size=batch_size)

注:

  1. 图像张量:灰度图(黑白图像)就是一个单通道的图像,彩色图像是多通道的图像(分别是R,G,B三个通道),一个通道具有高度——H,宽度——W,通道由——C表示。
  2. transform作用:再pytorch中读取图像时使用的是python的PIL,而由PIL读取的图像一般是由W x H x C组成,而在pytorch中为了进行更高效的图像处理,需要图像由C x W x H这样的顺序组成,因此transform的作用就是将PIL读取的图像顺序转换成C x W x H;像素值从0~255转换成0~1。


2 建立模型
       

       全连接网络中,要求输入的是一个矩阵,因此需要将1x28x28的这个三阶的张量变成一个一阶的向量,因此将图像的每一行的向量横着拼起来变成一串,这样就变成了一个维度为1x784的向量,一共输入N个手写数图,因此,输入矩阵维度为(N,784)。这样就可以设计我们的模型,如下图所示:

  具体代码:

  1. # 设计模型
  2. class Net(torch.nn.Module):
  3.     def __init__(self):
  4.         super(Net, self).__init__()
  5.         self.l1 = torch.nn.Linear(784, 512)
  6.         self.l2 = torch.nn.Linear(512, 256)
  7.         self.l3 = torch.nn.Linear(256, 128)
  8.         self.l4 = torch.nn.Linear(128, 64)
  9.         self.l5 = torch.nn.Linear(64, 10)
  10.  
  11.     def forward(self, x):
  12.         x = x.view(-1, 784)
  13.         x = F.relu(self.l1(x))
  14.         x = F.relu(self.l2(x))
  15.         x = F.relu(self.l3(x))
  16.         x = F.relu(self.l4(x))
  17.         return self.l5(x)
  18.  
  19.  
  20. model = Net()

3 构建损失函数和优化器

  1.   这里我们选择CrossEntropyLoss损失函数;
  2.   因为训练数据集有些大,所以优化器可以加上冲量参数。

  具体代码:

  1. # 构建损失函数和优化器
  2. criterion = torch.nn.CrossEntropyLoss()
  3. optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.5)

4 训练+测试

  1. 为了方便,这里我们将一轮训练循环封装成函数;
  2. test函数不需要反向传播,只用计算正向的就可以;
  3. torch.max的返回值有两个,第一个是每一行的最大值是多少,第二个是每一行最大值的下标(索引)是多少;
  4.  torch.no_grad() :不需要计算梯度;
  5. Python 各种下划线都是啥意思_、_xx、xx_、__xx、__xx__、_classname_ - 知乎

具体代码:

  1. # 定义训练函数
  2. def train(epoch):
  3.     running_loss = 0.0
  4.     for batch_idx, data in enumerate(train_loader, 0):
  5.         inputs, target = data
  6.         optimizer.zero_grad()
  7.         # 前馈+反馈+更新
  8.         outputs = model(inputs)
  9.         loss = criterion(outputs, target)
  10.         loss.backward()
  11.         optimizer.step()
  12.  
  13.         running_loss += loss.item()
  14.         # 每300次迭代输出一次
  15.         if batch_idx % 300 == 299:
  16.             print('[%d,%5d] loss:%.3f' % (epoch + 1, batch_idx + 1, running_loss / 300))
  17.             running_loss = 0.0
  18.  
  19.  
  20. # 定义测试函数
  21. def test():
  22.     correct = 0
  23.     total = 0
  24.     with torch.no_grad():
  25.         for data in test_loader:
  26.             images, labels = data
  27.             outputs = model(images)
  28.             # 沿着第一维度找最大值的下标
  29.             _, predicted = torch.max(outputs.data, dim=1)
  30.             total += labels.size(0)
  31.             correct += (predicted == labels).sum().item()
  32.     print('Accuracy on test set:%d %%' % (100 * correct / total))
  33.  
  34.  
  35.  
  36. # 实例化训练和测试
  37. if __name__ == '__main__':
  38.     # 训练10轮
  39.     for epoch in range(10):
  40.         train(epoch)
  41.         test()

5 完整代码+运行结果

完整代码:

  1. import torch
  2. from torchvision import transforms
  3. from torchvision import datasets
  4. from torch.utils.data import DataLoader
  5. import torch.nn.functional as F
  6. import torch.optim as optim
  7.  
  8. # 准备数据集
  9. batch_size = 64
  10. transform = transforms.Compose([
  11.     transforms.ToTensor(),
  12.     transforms.Normalize((0.1307, ), (0.3081, ))
  13. ])
  14. train_dataset = datasets.MNIST(root='../dataset/mnist/',
  15.                                train=True,
  16.                                download=True,
  17.                                transform=transform)
  18. train_loader = DataLoader(train_dataset,
  19.                           shuffle=True,
  20.                           batch_size=batch_size)
  21. test_dataset = datasets.MNIST(root='../dataset/mnist',
  22.                               train=False,
  23.                               download=True,
  24.                               transform=transform)
  25. test_loader = DataLoader(test_dataset,
  26.                          shuffle=False,
  27.                          batch_size=batch_size)
  28.  
  29.  
  30. # 设计模型
  31. class Net(torch.nn.Module):
  32.     def __init__(self):
  33.         super(Net, self).__init__()
  34.         self.l1 = torch.nn.Linear(784, 512)
  35.         self.l2 = torch.nn.Linear(512, 256)
  36.         self.l3 = torch.nn.Linear(256, 128)
  37.         self.l4 = torch.nn.Linear(128, 64)
  38.         self.l5 = torch.nn.Linear(64, 10)
  39.  
  40.     def forward(self, x):
  41.         x = x.view(-1, 784)
  42.         x = F.relu(self.l1(x))
  43.         x = F.relu(self.l2(x))
  44.         x = F.relu(self.l3(x))
  45.         x = F.relu(self.l4(x))
  46.         return self.l5(x)
  47.  
  48.  
  49. model = Net()
  50.  
  51. # 构建损失函数和优化器
  52. criterion = torch.nn.CrossEntropyLoss()
  53. optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.5)
  54.  
  55.  
  56. # 定义训练函数
  57. def train(epoch):
  58.     running_loss = 0.0
  59.     for batch_idx, data in enumerate(train_loader, 0):
  60.         inputs, target = data
  61.         optimizer.zero_grad()
  62.         # 前馈+反馈+更新
  63.         outputs = model(inputs)
  64.         loss = criterion(outputs, target)
  65.         loss.backward()
  66.         optimizer.step()
  67.  
  68.         running_loss += loss.item()
  69.         if batch_idx % 300 == 299:
  70.             print('[%d,%5d] loss:%.3f' % (epoch + 1, batch_idx + 1, running_loss / 300))
  71.             running_loss = 0.0
  72.  
  73.  
  74. # 定义测试函数
  75. def test():
  76.     correct = 0
  77.     total = 0
  78.     with torch.no_grad():
  79.         for data in test_loader:
  80.             images, labels = data
  81.             outputs = model(images)
  82.             _, predicted = torch.max(outputs.data, dim=1)
  83.             total += labels.size(0)
  84.             correct += (predicted == labels).sum().item()
  85.     print('Accuracy on test set:%d %%' % (100 * correct / total))
  86.  
  87.  
  88.  
  89. # 实例化训练和测试
  90. if __name__ == '__main__':
  91.     for epoch in range(10):
  92.         train(epoch)
  93.         test()

运行截图如下:


 6 遇到问题

       运行时遇到警告:The given NumPy array is not writeable,and PyTorch does not support non-writeable tensor,如图:

        按照路径找到mnist.py文件:

 点开修改:删除copy+False,就没有报错,程序可以继续运行了

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/235384
推荐阅读
相关标签
  

闽ICP备14008679号