翼度科技»论坛 编程开发 python 查看内容

使用cnn,bpnn,lstm实现mnist数据集的分类

7

主题

7

帖子

21

积分

新手上路

Rank: 1

积分
21
1.cnn
  1. import torch
  2. import torch.nn as nn
  3. import torch.nn.functional as F
  4. import torch.optim as optim
  5. from torchvision import datasets, transforms
  6. # 设置随机数种子
  7. torch.manual_seed(0)
  8. # 超参数
  9. EPOCH = 1  # 训练整批数据的次数
  10. BATCH_SIZE = 50
  11. DOWNLOAD_MNIST = False  # 表示还没有下载数据集,如果数据集下载好了就写False
  12. # 加载 MNIST 数据集
  13. train_dataset = datasets.MNIST(
  14.     root="./mnist",
  15.     train=True,#True表示是训练集
  16.     transform=transforms.ToTensor(),
  17.     download=False)
  18. test_dataset = datasets.MNIST(
  19.     root="./mnist",
  20.     train=False,#Flase表示测试集
  21.     transform=transforms.ToTensor(),
  22.     download=False)
  23. # 将数据集放入 DataLoader 中
  24. train_loader = torch.utils.data.DataLoader(
  25.     dataset=train_dataset,
  26.     batch_size=100,#每个批次读取的数据样本数
  27.     shuffle=True)#是否将数据打乱,在这种情况下为True,表示每次读取的数据是随机的
  28. test_loader = torch.utils.data.DataLoader(dataset=test_dataset, batch_size=100, shuffle=False)
  29. # 为了节约时间, 我们测试时只测试前2000个
  30. test_x = torch.unsqueeze(test_dataset.test_data, dim=1).type(torch.FloatTensor)[
  31.          :2000] / 255.  # shape from (2000, 28, 28) to (2000, 1, 28, 28), value in range(0,1)
  32. test_y = test_dataset.test_labels[:2000]
  33. # 定义卷积神经网络模型
  34. class CNN(nn.Module):
  35.     def __init__(self):
  36.         super(CNN, self).__init__()
  37.         self.conv1 = nn.Conv2d(#输入图像的大小为(28,28,1)
  38.             in_channels=1,#当前输入特征图的个数
  39.             out_channels=32,#输出特征图的个数
  40.             kernel_size=3,#卷积核大小,在一个3*3空间里对当前输入的特征图像进行特征提取
  41.             stride=1,#步长:卷积窗口每隔一个单位滑动一次
  42.             padding=1)#如果希望卷积后大小跟原来一样,需要设置padding=(kernel_size-1)/2
  43.         #第一层结束后图像大小为(28,28,32)32是输出图像个数,28计算方法为(h-k+2p)/s+1=(28-3+2*1)/1 +1=28
  44.         self.pool = nn.MaxPool2d(kernel_size=2, stride=2)#可以缩小输入图像的尺寸,同时也可以防止过拟合
  45.         #通过池化层之后图像大小变为(14,14,32)
  46.         self.conv2 = nn.Conv2d(#输入图像大小为(14,14,32)
  47.             in_channels=32,#第一层的输出特征图的个数当做第二层的输入特征图的个数
  48.             out_channels=64,
  49.             kernel_size=3,
  50.             stride=1,
  51.             padding=1)#二层卷积之后图像大小为(14,14,64)
  52.         self.fc = nn.Linear(64 * 7 * 7, 10)#10表示最终输出的
  53.     # 下面定义x的传播路线
  54.     def forward(self, x):
  55.         x = self.pool(F.relu(self.conv1(x)))# x先通过conv1
  56.         x = self.pool(F.relu(self.conv2(x)))# 再通过conv2
  57.         x = x.view(-1, 64 * 7 * 7)
  58.         x = self.fc(x)
  59.         return x
  60. # 实例化卷积神经网络模型
  61. model = CNN()
  62. # 定义损失函数和优化器
  63. criterion = nn.CrossEntropyLoss()
  64. #lr(学习率)是控制每次更新的参数的大小的超参数
  65. optimizer = torch.optim.Adam(model.parameters(), lr=0.01)
  66. # 训练模型
  67. for epoch in range(1):
  68.     for i, (images, labels) in enumerate(train_loader):
  69.         outputs = model(images)  # 先将数据放到cnn中计算output
  70.         loss = criterion(outputs, labels)# 输出和真实标签的loss,二者位置不可颠倒
  71.         optimizer.zero_grad()# 清除之前学到的梯度的参数
  72.         loss.backward()  # 反向传播,计算梯度
  73.         optimizer.step()#应用梯度
  74.         if i % 50 == 0:
  75.             data_all = model(test_x)#不分开写就会出现ValueError: too many values to unpack (expected 2)
  76.             last_layer = data_all
  77.             test_output = data_all
  78.             pred_y = torch.max(test_output, 1)[1].data.numpy()
  79.             accuracy = float((pred_y == test_y.data.numpy()).astype(int).sum()) / float(test_y.size(0))
  80.             print('Epoch: ', epoch, '| train loss: %.4f' % loss.data.numpy(), '| test accuracy: %.4f' % accuracy)
  81. # print 10 predictions from test data
  82. data_all1 = model(test_x[:10])
  83. test_output = data_all1
  84. _ = data_all1
  85. pred_y = torch.max(test_output, 1)[1].data.numpy()
  86. print(pred_y, 'prediction number')
  87. print(test_y[:10].numpy(), 'real number')
复制代码
2.bpnn
  1. import torch
  2. from torch.autograd import Variable
  3. import torch.nn as nn
  4. import torch.nn.functional as func
  5. #import matplotlib.pyplot as plt
  6. import torch.utils.data as Data
  7. import torchvision
  8. # 超参数
  9. EPOCH = 2 # 训练一个回合
  10. BATCH_SIZE = 50 # 每次取样50个进行训练
  11. LR = 0.001 # 学习率0.01
  12. # DOWNLOAD_MNIST = False
  13. # 提取训练数据
  14. # 将图像格式转为tensor格式
  15. train_data = torchvision.datasets.MNIST(
  16.     root='./mnist',
  17.     train=True,
  18.     transform=torchvision.transforms.ToTensor(),
  19.     # download = DOWNLOAD_MNIST,
  20. )
  21. # 选取相应批次的图像
  22. train_loader = Data.DataLoader(dataset=train_data, batch_size=BATCH_SIZE, shuffle=True)
  23. # 加载测试图像
  24. test_data = torchvision.datasets.MNIST(
  25.     root='./mnist',
  26.     train=False,
  27.     transform=torchvision.transforms.ToTensor(),
  28. )
  29. test_loader = Data.DataLoader(dataset=test_data,batch_size=BATCH_SIZE)
  30. class BPNN(nn.Module):
  31.     def __init__(self):
  32.         super(BPNN, self).__init__()
  33.         # 创建容器
  34.         # 按照sequential内模块的顺序执行
  35.         self.conv1 = nn.Sequential(
  36.             # 二维卷积
  37.             nn.Linear(28,64),
  38.             nn.ReLU(),
  39.         )
  40.         self.conv2 = nn.Sequential(
  41.             nn.Linear(64,128),
  42.             nn.ReLU(),
  43.         )
  44.         self.conv3 = nn.Sequential(
  45.             nn.Linear(128, 32),
  46.             nn.ReLU(),
  47.         )
  48.         # 全连接层
  49.         self.out = nn.Linear(32 * 28, 10)
  50.     def forward(self, x):
  51.         x = self.conv1(x)
  52.         x = self.conv2(x)
  53.         x = self.conv3(x)
  54.         x = x.view(x.size(0), -1)  # 相当于维度转换,这里保留0维(batch_size),将后面的三个维度展平
  55.         output = self.out(x)
  56.         return output
  57. bpnn = BPNN()
  58. # Adam优化器
  59. optimizer = torch.optim.Adam(bpnn.parameters(), lr=LR)
  60. # loss函数
  61. loss_func = nn.CrossEntropyLoss()
  62. # 迭代训练
  63. for epoch in range(EPOCH):
  64.     for step, (batch_x, batch_y) in enumerate(train_loader):
  65.         # b_x = Variable(batch_x)
  66.         # b_y = Variable(batch_y)
  67.         out = bpnn(batch_x)
  68.         loss = loss_func(out, batch_y)
  69.         optimizer.zero_grad()  # 梯度降为0
  70.         loss.backward()  # 误差反向传递
  71.         optimizer.step()  # 以学习效率优化梯度
  72. equal = 0
  73. i = 0
  74. for step,(test_x,test_y) in enumerate(test_loader):
  75.     if step % 10 == 0:
  76.         i += 1
  77.         test_output = bpnn(test_x)
  78.         pred_y = torch.max(test_output, 1)[1].data.squeeze()
  79.         acc = (pred_y == test_y).sum().float() / test_y.size(0)
  80.         print('Epoch: ', epoch, '| train loss: %.4f' % loss.data.float(), 'test acc: ', acc.numpy())
  81.         equal += acc.numpy()
  82. print(equal/i)
  83. test_output = bpnn(test_x[:10])
  84. pred_y = torch.max(test_output, 1)[1].data.squeeze()
  85. print(pred_y, 'prediction number')
  86. print(test_y[:10].numpy(), 'real number')
复制代码
3.lstm
  1. import torch
  2. from torch import nn
  3. import torchvision.datasets as dsets
  4. import torchvision.transforms as transforms
  5. import matplotlib.pyplot as plt
  6. import numpy as np
  7. torch.manual_seed(1)  # reproducible
  8. # Hyper Parameters
  9. EPOCH = 1  # 训练整批数据多少次, 为了节约时间, 我们只训练一次
  10. BATCH_SIZE = 64
  11. TIME_STEP = 28  # rnn 时间步数 / 图片高度
  12. INPUT_SIZE = 28  # rnn 每步输入值 / 图片每行像素
  13. LR = 0.01  # learning rate
  14. DOWNLOAD_MNIST = False  # 如果你已经下载好了mnist数据就写上 Fasle
  15. # Mnist 手写数字
  16. train_data = dsets.MNIST(
  17.     root='./mnist/',  # 保存或者提取位置
  18.     train=True,  # this is training data
  19.     transform=transforms.ToTensor(),  # 转换 PIL.Image or numpy.ndarray 成
  20.     # torch.FloatTensor (C x H x W), 训练的时候 normalize 成 [0.0, 1.0] 区间
  21.     download=DOWNLOAD_MNIST,  # 没下载就下载, 下载了就不用再下了
  22. )
  23. test_data = dsets.MNIST(root='./mnist/', train=False)
  24. # 批训练 50samples, 1 channel, 28x28 (50, 1, 28, 28)
  25. train_loader = torch.utils.data.DataLoader(dataset=train_data, batch_size=BATCH_SIZE, shuffle=True)
  26. # 为了节约时间, 我们测试时只测试前2000个
  27. test_x = torch.unsqueeze(test_data.test_data, dim=1).type(torch.FloatTensor)[
  28.          :2000] / 255.  # shape from (2000, 28, 28) to (2000, 1, 28, 28), value in range(0,1)
  29. test_y = test_data.test_labels[:2000]
  30. class RNN(nn.Module):
  31.     def __init__(self):
  32.         super(RNN, self).__init__()
  33.         self.rnn = nn.LSTM(  # LSTM 效果要比 nn.RNN() 好多了
  34.             input_size=28,  # 图片每行的数据像素点
  35.             hidden_size=64,  # rnn hidden unit
  36.             num_layers=1,  # 有几层 RNN layers
  37.             batch_first=True,  # input & output 会是以 batch size 为第一维度的特征集 e.g. (batch, time_step, input_size)
  38.         )
  39.         self.out = nn.Linear(64, 10)  # 输出层,接入线性层
  40.     def forward(self, x):  # 必须有这个方法
  41.         # x shape (batch, time_step, input_size)
  42.         # r_out shape (batch, time_step, output_size)
  43.         # h_n shape (n_layers, batch, hidden_size)   LSTM 有两个 hidden states, h_n 是分线, h_c 是主线
  44.         # h_c shape (n_layers, batch, hidden_size)
  45.         r_out, (h_n, h_c) = self.rnn(x, None)  # None 表示 hidden state 会用全0的 state
  46.         # 当RNN运行结束时刻,(h_n, h_c)表示最后的一组hidden states,这里用不到
  47.         # 选取最后一个时间点的 r_out 输出
  48.         # 这里 r_out[:, -1, :] 的值也是 h_n 的值
  49.         out = self.out(r_out[:, -1, :])  # (batch_size, time step, input),这里time step选择最后一个时刻
  50.         # output_np = out.detach().numpy()  # 可以使用numpy的sciview监视每次结果
  51.         return out
  52. rnn = RNN()
  53. print(rnn)
  54. optimizer = torch.optim.Adam(rnn.parameters(), lr=LR)  # optimize all parameters
  55. loss_func = nn.CrossEntropyLoss()  # the target label is not one-hotted
  56. # training and testing
  57. for epoch in range(EPOCH):
  58.     for step, (x, b_y) in enumerate(train_loader):  # gives batch data
  59.         b_x = x.view(-1, 28, 28)  # reshape x to (batch, time_step, input_size)
  60.         output = rnn(b_x)  # rnn output
  61.         loss = loss_func(output, b_y)  # cross entropy loss
  62.         optimizer.zero_grad()  # clear gradients for this training step
  63.         loss.backward()  # backpropagation, compute gradients
  64.         optimizer.step()  # apply gradients
  65.         # output_np = output.detach().numpy()
  66.         if step % 50 == 0:
  67.             test_x = test_x.view(-1, 28, 28)
  68.             test_output = rnn(test_x)
  69.             pred_y = torch.max(test_output, 1)[1].data.squeeze()
  70.             acc = (pred_y == test_y).sum().float() / test_y.size(0)
  71.             print('Epoch: ', epoch, '| train loss: %.4f' % loss.data.float(), 'test acc: ', acc.numpy())
  72. test_output = rnn(test_x[:10].view(-1, 28, 28))
  73. pred_y = torch.max(test_output, 1)[1].data.numpy().squeeze()
  74. print(pred_y, 'prediction number')
  75. print(test_y[:10], 'real number')
复制代码
来源:https://www.cnblogs.com/twq46/p/17115263.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

举报 回复 使用道具