当前位置:   article > 正文

Python PyTorch6:卷积神经网络_self.conv1 = nn.sequential

self.conv1 = nn.sequential

1. CNN

卷积神经网络(CNN)是近年发展起来,并广泛应用于图像处理,NLP等领域的一 种多层神经网络。

如图,传统的神经网络使用全连接的策略进行极端,在处理较大的数据(如图像)时会遇到问题:权值太多,计算量太大;需要大量样本进行训练。

CNN通过局部感受野和权值共享减少了神经网络需要训练的参数个数。我们在观察一个图像的时候,不可能一眼看到图像的所有内容。这时候,CNN中隐藏层的每个神经元只和前一层的一个局部(卷积窗口,如5*5的窗口则有25个连接线)进行连接,称为局部感受野。这样,可以大大减少CNN需要训练的计算量。

2. 卷积

卷积计算时,需要使用一个卷积核,如图是一个3*3的卷积核:

这个卷积核在需要计算的矩阵上移动,每次覆盖3*3的格子时将对应位置的数字相乘再相加(如图),得到输出的3*3矩阵(特征图)。

可以设定卷积核跨越的格子数量(步长)。

3. 池化

卷积层做完卷积后,通常会在卷积后做一个池化(pooling)层。常用的池化计算包括最大池化(max-pooling)、平均池化(mean-pooling)、随机池化(stochastic pooling)等。

4. 填充

输入图像与卷积核进行卷积后的结果中损失了部分值。有时我们希望输入和输出的大小应该保持一致,为解决这个问题,可以在进行卷积操作前,对原矩阵进行边界填充(padding),也就是在矩阵的边界上填充一些值,以增加矩阵的大小,通常都用0来进行填充。

same padding: 可能将矩阵的若干圈边缘补上0,卷积窗口采样后得到一个跟原来大小相同的平面。

valid padding: 不会超出平面外部,卷积窗口采样后得到一个比原来平面小的平面。

5. LeNET-5

LeNet-5是一种用于手写体字符识别的非常高效的卷积神经网络,曾广泛用于美国银行。

例:使用卷积神经网络修改MNIST案例。

  1. import torch
  2. import torch.nn as nn
  3. import torch.optim as optim
  4. from torchvision import datasets, transforms
  5. from torch.utils.data import DataLoader
  6. # 下载训练集
  7. train_dataset = datasets.MNIST(root='./',
  8. train=True,
  9. transform=transforms.ToTensor(),
  10. download=True)
  11. # 下载测试集
  12. test_dataset = datasets.MNIST(root='./',
  13. train=False,
  14. transform=transforms.ToTensor(),
  15. download=True)
  16. # 批次大小
  17. batch_size = 64
  18. # 装载训练集
  19. train_loader = DataLoader(dataset=train_dataset,
  20. batch_size=batch_size,
  21. shuffle=True)
  22. # 装载测试集
  23. test_loader = DataLoader(dataset=test_dataset,
  24. batch_size=batch_size,
  25. shuffle=True)
  26. for i, data in enumerate(train_loader):
  27. # 获得数据和对应的标签
  28. inputs, labels = data
  29. print(inputs.shape)
  30. print(labels.shape)
  31. break
  32. # 定义网络结构
  33. class Net(nn.Module):
  34. def __init__(self):
  35. super(Net, self).__init__()
  36. # 卷积层1
  37. # Conv2d 参数1:输入通道数,黑白图片为1,彩色为3 参数2:输出通道数,生成32个特征图 参数3:5*5卷积窗口 参数4:步长1 参数5:padding补2圈0(3*3卷积窗口填充1圈0,5*5填充2圈0)
  38. # 使用ReLU激活函数 池化窗口大小2*2,步长2
  39. self.conv1 = nn.Sequential(nn.Conv2d(1, 32, 5, 1, 2), nn.ReLU(), nn.MaxPool2d(2, 2))
  40. # 卷积层2 输入32个特征图 输出64个特征图
  41. self.conv2 = nn.Sequential(nn.Conv2d(32, 64, 5, 1, 2), nn.ReLU(), nn.MaxPool2d(2, 2))
  42. # 全连接层1 输入64*7*7(原先为28,每次池化/2),1000
  43. self.fc1 = nn.Sequential(nn.Linear(64 * 7 * 7, 1000), nn.Dropout(p=0.4), nn.ReLU())
  44. # 全连接层2 输出10个分类,并转化为概率
  45. self.fc2 = nn.Sequential(nn.Linear(1000, 10), nn.Softmax(dim=1))
  46. def forward(self, x):
  47. # 卷积层使用4维的数据
  48. # 批次数量64 黑白1 图片大小28*28
  49. # ([64, 1, 28, 28])
  50. x = self.conv1(x)
  51. x = self.conv2(x)
  52. # 全连接层对2维数据进行计算
  53. x = x.view(x.size()[0], -1)
  54. x = self.fc1(x)
  55. x = self.fc2(x)
  56. return x
  57. LR = 0.0003
  58. # 定义模型
  59. model = Net()
  60. # 定义代价函数
  61. entropy_loss = nn.CrossEntropyLoss()
  62. # 定义优化器
  63. optimizer = optim.Adam(model.parameters(), LR)
  64. def train():
  65. model.train()
  66. for i, data in enumerate(train_loader):
  67. # 获得数据和对应的标签
  68. inputs, labels = data
  69. # 获得模型预测结果,(64,10)
  70. out = model(inputs)
  71. # 交叉熵代价函数out(batch,C),labels(batch)
  72. loss = entropy_loss(out, labels)
  73. # 梯度清0
  74. optimizer.zero_grad()
  75. # 计算梯度
  76. loss.backward()
  77. # 修改权值
  78. optimizer.step()
  79. def test():
  80. model.eval()
  81. correct = 0
  82. for i, data in enumerate(test_loader):
  83. # 获得数据和对应的标签
  84. inputs, labels = data
  85. # 获得模型预测结果
  86. out = model(inputs)
  87. # 获得最大值,以及最大值所在的位置
  88. _, predicted = torch.max(out, 1)
  89. # 预测正确的数量
  90. correct += (predicted == labels).sum()
  91. print("Test acc: {0}".format(correct.item() / len(test_dataset)))
  92. correct = 0
  93. for i, data in enumerate(train_loader):
  94. # 获得数据和对应的标签
  95. inputs, labels = data
  96. # 获得模型预测结果
  97. out = model(inputs)
  98. # 获得最大值,以及最大值所在的位置
  99. _, predicted = torch.max(out, 1)
  100. # 预测正确的数量
  101. correct += (predicted == labels).sum()
  102. print("Train acc: {0}".format(correct.item() / len(train_dataset)))
  103. for epoch in range(0, 10):
  104. print('epoch:', epoch)
  105. train()
  106. test()

输出:

torch.Size([64, 1, 28, 28])
torch.Size([64])
epoch: 0
Test acc: 0.9764
Train acc: 0.9738833333333333
epoch: 1
Test acc: 0.9813
Train acc: 0.9808166666666667
epoch: 2
Test acc: 0.9838
Train acc: 0.9848
epoch: 3
Test acc: 0.9874
Train acc: 0.9889
epoch: 4
Test acc: 0.9886
Train acc: 0.98935
epoch: 5
Test acc: 0.9904
Train acc: 0.9917333333333334
epoch: 6
Test acc: 0.9874
Train acc: 0.9913666666666666
epoch: 7
Test acc: 0.9901
Train acc: 0.9923166666666666
epoch: 8
Test acc: 0.9894
Train acc: 0.9933
epoch: 9
Test acc: 0.9917
Train acc: 0.9951

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

闽ICP备14008679号