• 图像处理8-CNN图像分类


    图像处理系列

    图像处理1-经典空间域增强——灰度映射

    图像处理2-经典空间域增强——直方图均衡化

    图像处理3-经典空间域增强——空域滤波

    图像处理4-图像的傅里叶变换

    图像处理5-图片加噪

    图像处理6-大津法图像阈值分切

    图像处理7-图像增强

    一、内容

    (1)利用Pytorch搭建简单的CNN网络实现图像分类,并测试分类效果(更多步骤可参考https://www.stefanfiott.com/machine-learning/cifar-10-classifier-using-cnn-in-pytorch/);

    (2)修改网络模型,进行新的训练,并测试分类效果;

    (3)撰写实验报告。

    二、使用简单的CNN网络进行图像分类

    1.导入包

           使用图2.1的代码导入包。

     

    图2.1 导入包

    2.数据下载、增强和划分

           使用图2.2的代码进行数据下载、增强和划分数据集。

     

    图2.2 数据下载、增强、划分

    3.神经网络定义

           使用图2.3的代码定义一个简单的CNN神经网络。

     

    图2.3 定义简单的CNN神经网络

    4.定义优化器

           使用图2.4的代码定义优化器。

    图2.4 定义优化器

    5.训练和保存神经网络

           使用图2.5的代码训练定义的模型,并保存,输出如图2.6。

     

    图2.5 神经网络训练与保存

     

    图2.6 模型训练输出

    6.测试神经网络

    a.准确率

           使用图2.7的代码,计算准去率,最后得到准确率为62.17%

     

    图2.7 计算模型准确率

    b.计算每一类的分类准确率

           使用图2.8的代码计算每类分类的准确率,结果见图2.9。

     

    图2.8 计算每类分类的准确率

     

    图2.9 每类分类的准确率

    c.绘制实际实际类别和预测分类曲线

           使用图2.10的代码进行绘制,并输出每个值得大小,如图2.11,曲线如图2.12。

     

    图2.11 绘制实际实际类别和预测分类曲线

     

    图2.12 绘制实际实际类别和预测分类值的大小

     

    图2.13 绘制实际实际类别和预测分类值曲线

    三、Geogle Net图片分类

    1.导入包

           使用图3.1的代码导入包。

     

    图3.1 导入包

    2.数据导入、增强和划分

           使用图3.2的代码进行参数定义,数据导入、增强和划分。

     

    图3.2 参数定义,数据导入、增强和划分

    3.定义网络

           使用图3.3的代码进行网络定义。

     

     

     

     

    图3.3 网络定义

    4.训练网络

           使用图3.4的代码进行网络训练,输出如图3.5。

     

    图3.4 网络训练

     

    图3.5 训练输出

    5.计算精度

           使用图3.6的代码计算精度,精度为80.43%.

     

    图3.6 计算精度

    四、总结

           使用pytorch,搭建了简单的CNN网络和Geogle Net网络,对Cifar10进行了图像分类,并计算了相应的模型校验参数。

    五、源码

    1.简单CNN源码

    1. '''
    2. 简单CNN图片分类
    3. '''
    4. import torch
    5. import torchvision
    6. import torchvision.transforms as transforms
    7. import matplotlib.pyplot as plt
    8. import numpy as np
    9. import torch.nn as nn
    10. import torch.nn.functional as F
    11. import torch.optim as optim
    12. import os
    13. #下载数据并进行数据增强和划分
    14. transform = transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])
    15. trainset = torchvision.datasets.CIFAR10('./data', train=True,download=True, transform=transform)
    16. trainloader = torch.utils.data.DataLoader(trainset, batch_size=4,num_workers=4,shuffle=True)
    17. testset = torchvision.datasets.CIFAR10('./data', train=False,download=True, transform=transform)
    18. testloader = torch.utils.data.DataLoader(testset, batch_size=4,num_workers=4,shuffle=False)
    19. classes = ('plane', 'car', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck')
    20. dataiter = iter(trainloader)
    21. images, labels = dataiter.next()
    22. #定义网络结构
    23. class Net(nn.Module):
    24. def __init__(self):
    25. super(Net, self).__init__()
    26. self.conv1 = nn.Conv2d(3, 6, 5)
    27. self.pool = nn.MaxPool2d(2, 2)
    28. self.conv2 = nn.Conv2d(6, 16, 5)
    29. self.fc1 = nn.Linear(16 * 5 * 5, 120)
    30. self.fc2 = nn.Linear(120, 84)
    31. self.fc3 = nn.Linear(84, 10)
    32. def forward(self, x):
    33. x = self.pool(F.relu(self.conv1(x)))
    34. x = self.pool(F.relu(self.conv2(x)))
    35. x = x.view(-1, 16 * 5 * 5)
    36. x = F.relu(self.fc1(x))
    37. x = F.relu(self.fc2(x))
    38. x = self.fc3(x)
    39. return x
    40. net = Net()
    41. #定义优化器
    42. criterion = nn.CrossEntropyLoss()
    43. optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)
    44. #训练网络
    45. model_directory_path = './model、'
    46. model_path = model_directory_path + 'cifar-10-cnn-model-oralcnn.pt'
    47. if not os.path.exists(model_directory_path):
    48. os.makedirs(model_directory_path)
    49. if os.path.isfile(model_path):
    50. # load trained model parameters from disk
    51. net.load_state_dict(torch.load(model_path))
    52. print('Loaded model parameters from disk.')
    53. else:
    54. for epoch in range(10): # loop over the dataset multiple times
    55. running_loss = 0.0
    56. for i, data in enumerate(trainloader, 0):
    57. # get the inputs
    58. inputs, labels = data
    59. # zero the parameter gradients
    60. optimizer.zero_grad()
    61. # forward + backward + optimize
    62. outputs = net(inputs)
    63. loss = criterion(outputs, labels)
    64. loss.backward()
    65. optimizer.step()
    66. # print statistics
    67. running_loss += loss.item()
    68. if i % 2000 == 1999: # print every 2000 mini-batches
    69. print('[%d, %5d] loss: %.3f' %
    70. (epoch + 1, i + 1, running_loss / 2000))
    71. running_loss = 0.0
    72. print('Finished Training.')
    73. torch.save(net.state_dict(), model_path)
    74. print('Saved model parameters to disk.')
    75. #网络测试
    76. dataiter = iter(testloader)
    77. images, labels = dataiter.next()
    78. outputs = net(images)
    79. sm = nn.Softmax(dim=1)
    80. sm_outputs = sm(outputs)
    81. probs, index = torch.max(sm_outputs, dim=1)
    82. total_correct = 0
    83. total_images = 0
    84. confusion_matrix = np.zeros([10,10], int)
    85. with torch.no_grad():
    86. for data in testloader:
    87. images, labels = data
    88. outputs = net(images)
    89. _, predicted = torch.max(outputs.data, 1)
    90. total_images += labels.size(0)
    91. total_correct += (predicted == labels).sum().item()
    92. for i, l in enumerate(labels):
    93. confusion_matrix[l.item(), predicted[i].item()] += 1
    94. model_accuracy = total_correct / total_images * 100
    95. print('Model accuracy on {0} test images: {1:.2f}%'.format(total_images, model_accuracy))
    96. print('{0:10s} - {1}'.format('Category','Accuracy'))
    97. for i, r in enumerate(confusion_matrix):
    98. print('{0:10s} - {1:.1f}'.format(classes[i], r[i]/np.sum(r)*100))
    99. fig, ax = plt.subplots(1,1,figsize=(8,6))
    100. ax.matshow(confusion_matrix, aspect='auto', vmin=0, vmax=1000, cmap=plt.get_cmap('Blues'))
    101. plt.ylabel('Actual Category')
    102. plt.yticks(range(10), classes)
    103. plt.xlabel('Predicted Category')
    104. plt.xticks(range(10), classes)
    105. plt.show()
    106. print('actual/pred'.ljust(16), end='')
    107. for i,c in enumerate(classes):
    108. print(c.ljust(10), end='')
    109. print()
    110. for i,r in enumerate(confusion_matrix):
    111. print(classes[i].ljust(16), end='')
    112. for idx, p in enumerate(r):
    113. print(str(p).ljust(10), end='')
    114. print()
    115. r = r/np.sum(r)
    116. print(''.ljust(16), end='')
    117. for idx, p in enumerate(r):
    118. print(str(p).ljust(10), end='')
    119. print()

    2.Geogle Net

    1. '''
    2. geoglenet图片分类
    3. '''
    4. import torch
    5. import torchvision
    6. import torchvision.transforms as transforms
    7. import matplotlib.pyplot as plt
    8. import numpy as np
    9. import torch.nn as nn
    10. import torch.nn.functional as F
    11. import torch.optim as optim
    12. import os
    13. import gc
    14. ##定义参数
    15. num_epochs = 40
    16. batch_size = 100
    17. num_classes = 10
    18. learning_rate = 0.0006
    19. device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
    20. #下载数据并进行数据增强和划分
    21. transform = transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])
    22. train_dataset = torchvision.datasets.CIFAR10('./data', download=False, train=True, transform=transform)
    23. test_dataset = torchvision.datasets.CIFAR10('./data', download=False, train=False, transform=transform)
    24. train_loader = torch.utils.data.DataLoader(dataset=train_dataset, batch_size=batch_size, shuffle=True)
    25. test_loader = torch.utils.data.DataLoader(dataset=test_dataset, batch_size=batch_size, shuffle=False)
    26. classes = ('plane', 'car', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck')
    27. dataiter = iter(train_loader)
    28. images, labels = dataiter.next()
    29. #定义网络
    30. class BasicConv2d(torch.nn.Module):
    31. def __init__(self, in_channels, out_channels, **kwargs):
    32. super(BasicConv2d, self).__init__()
    33. self.conv = torch.nn.Conv2d(in_channels, out_channels, **kwargs)
    34. self.batchnorm = torch.nn.BatchNorm2d(out_channels)
    35. self.relu = torch.nn.ReLU(inplace=True)
    36. def forward(self, x):
    37. x = self.conv(x)
    38. x = self.batchnorm(x)
    39. x = self.relu(x)
    40. return x
    41. # Define InceptionAux.
    42. class InceptionAux(torch.nn.Module):
    43. def __init__(self, in_channels, num_classes):
    44. super(InceptionAux, self).__init__()
    45. self.avgpool = torch.nn.AvgPool2d(kernel_size=2, stride=2)
    46. self.conv = BasicConv2d(in_channels, 128, kernel_size=1)
    47. self.fc1 = torch.nn.Sequential(torch.nn.Linear(2 * 2 * 128, 256))
    48. self.fc2 = torch.nn.Linear(256, num_classes)
    49. def forward(self, x):
    50. out = self.avgpool(x)
    51. out = self.conv(out)
    52. out = out.view(out.size(0), -1)
    53. out = torch.nn.functional.dropout(out, 0.5, training=self.training)
    54. out = torch.nn.functional.relu(self.fc1(out), inplace=True)
    55. out = torch.nn.functional.dropout(out, 0.5, training=self.training)
    56. out = self.fc2(out)
    57. return out
    58. class Inception(torch.nn.Module):
    59. def __init__(self, in_channels, ch1x1, ch3x3red, ch3x3, ch5x5red, ch5x5, pool_proj):
    60. super(Inception, self).__init__()
    61. self.branch1 = BasicConv2d(in_channels, ch1x1, kernel_size=1)
    62. self.branch2 = torch.nn.Sequential(BasicConv2d(in_channels, ch3x3red, kernel_size=1),
    63. BasicConv2d(ch3x3red, ch3x3, kernel_size=3, padding=1))
    64. self.branch3 = torch.nn.Sequential(BasicConv2d(in_channels, ch5x5red, kernel_size=1),
    65. BasicConv2d(ch5x5red, ch5x5, kernel_size=5, padding=2))
    66. self.branch4 = torch.nn.Sequential(torch.nn.MaxPool2d(kernel_size=3, stride=1, padding=1),
    67. BasicConv2d(in_channels, pool_proj, kernel_size=1))
    68. def forward(self, x):
    69. branch1 = self.branch1(x)
    70. branch2 = self.branch2(x)
    71. branch3 = self.branch3(x)
    72. branch4 = self.branch4(x)
    73. outputs = [branch1, branch2, branch3, branch4]
    74. return torch.cat(outputs, 1)
    75. # Define GooLeNet.
    76. class GoogLeNet(torch.nn.Module):
    77. def __init__(self, num_classes, aux_logits=True, init_weights=False):
    78. super(GoogLeNet, self).__init__()
    79. self.aux_logits = aux_logits
    80. self.conv1 = BasicConv2d(3, 64, kernel_size=4, stride=2, padding=3)
    81. self.maxpool1 = torch.nn.MaxPool2d(kernel_size=2, stride=2, ceil_mode=True)
    82. self.conv2 = BasicConv2d(64, 64, kernel_size=1)
    83. self.conv3 = BasicConv2d(64, 192, kernel_size=3, padding=1)
    84. self.maxpool2 = torch.nn.MaxPool2d(kernel_size=2, stride=1, ceil_mode=True)
    85. self.inception3a = Inception(192, 64, 96, 128, 16, 32, 32)
    86. self.inception3b = Inception(256, 128, 128, 192, 32, 96, 64)
    87. self.maxpool3 = torch.nn.MaxPool2d(kernel_size=2, stride=2, ceil_mode=True)
    88. self.inception4a = Inception(480, 192, 96, 208, 16, 48, 64)
    89. self.inception4b = Inception(512, 160, 112, 224, 24, 64, 64)
    90. self.inception4c = Inception(512, 128, 128, 256, 24, 64, 64)
    91. self.inception4d = Inception(512, 112, 144, 288, 32, 64, 64)
    92. self.inception4e = Inception(528, 256, 160, 320, 32, 128, 128)
    93. self.maxpool4 = torch.nn.MaxPool2d(kernel_size=2, stride=2, ceil_mode=True)
    94. self.inception5a = Inception(832, 256, 160, 320, 32, 128, 128)
    95. self.inception5b = Inception(832, 384, 192, 384, 48, 128, 128)
    96. if self.aux_logits:
    97. self.aux1 = InceptionAux(512, num_classes)
    98. self.aux2 = InceptionAux(528, num_classes)
    99. self.avgpool = torch.nn.AdaptiveAvgPool2d((1, 1))
    100. self.dropout = torch.nn.Dropout(0.4)
    101. self.fc = torch.nn.Linear(1024, num_classes)
    102. if init_weights:
    103. self._initialize_weights()
    104. def forward(self, x):
    105. x = self.conv1(x)
    106. x = self.maxpool1(x)
    107. x = self.conv2(x)
    108. x = self.conv3(x)
    109. x = self.maxpool2(x)
    110. x = self.inception3a(x)
    111. x = self.inception3b(x)
    112. x = self.maxpool3(x)
    113. x = self.inception4a(x)
    114. if self.training and self.aux_logits: # eval model lose this layer
    115. aux1 = self.aux1(x)
    116. x = self.inception4b(x)
    117. x = self.inception4c(x)
    118. x = self.inception4d(x)
    119. if self.training and self.aux_logits: # eval model lose this layer
    120. aux2 = self.aux2(x)
    121. x = self.inception4e(x)
    122. x = self.maxpool4(x)
    123. x = self.inception5a(x)
    124. x = self.inception5b(x)
    125. x = self.avgpool(x)
    126. x = torch.flatten(x, 1)
    127. x = self.dropout(x)
    128. x = self.fc(x)
    129. if self.training and self.aux_logits: # eval model lose this layer
    130. return x, aux2, aux1
    131. return x
    132. def _initialize_weights(self):
    133. for m in self.modules():
    134. if isinstance(m, torch.nn.Conv2d):
    135. torch.nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu')
    136. if m.bias is not None:
    137. torch.nn.init.constant_(m.bias, 0)
    138. elif isinstance(m, torch.nn.Linear):
    139. torch.nn.init.normal_(m.weight, 0, 0.01)
    140. torch.nn.init.constant_(m.bias, 0)
    141. net = GoogLeNet(10, False, True).to(device)
    142. criterion = nn.CrossEntropyLoss()
    143. optimizer = torch.optim.Adam(net.parameters(), lr=0.001, betas=(0.9, 0.999), eps=1e-08, weight_decay=0)
    144. def update_lr(optimizer, lr):
    145. for param_group in optimizer.param_groups:
    146. param_group['lr'] = lr
    147. #训练网络
    148. total_step = len(train_loader)
    149. curr_lr = learning_rate
    150. for epoch in range(num_epochs):
    151. gc.collect()
    152. torch.cuda.empty_cache()
    153. net.train()
    154. for i, (images, labels) in enumerate(train_loader):
    155. images = images.to(device)
    156. labels = labels.to(device)
    157. outputs = net(images)
    158. loss = criterion(outputs, labels)
    159. optimizer.zero_grad()
    160. loss.backward()
    161. optimizer.step()
    162. if (i+1) % 100 == 0:
    163. print ('Epoch [{}/{}], Step [{}/{}], Loss {:.4f}'.format(epoch+1, num_epochs, i+1, total_step, loss.item()))
    164. if (epoch+1) % 20 == 0:
    165. curr_lr /= 3
    166. update_lr(optimizer, curr_lr)
    167. torch.save(net.state_dict(), './model/cifar-10-cnn-geoglenet.pt')
    168. #计算精度
    169. net.eval()
    170. with torch.no_grad():
    171. correct = 0
    172. total = 0
    173. for images, labels in test_loader:
    174. images = images.to(device)
    175. labels = labels.to(device)
    176. outputs = net(images)
    177. _, predicted = torch.max(outputs.data, 1)
    178. total += labels.size(0)
    179. correct += (predicted == labels).sum().item()
    180. print('Accuracy of the model on the test images: {} %'.format(100 * correct / total))

  • 相关阅读:
    “一万字”动静图生动结合详解:快速排序
    醋氯芬酸小鼠血清白蛋白纳米粒Aceclofenac-MSA|利凡诺大鼠血清白蛋白纳米粒Ethacridine-RSA
    【AGC】集成华为AGC崩溃服务实用教程
    教你如何搭建一个大学生查题公众号
    Java日志门面框架--SLF4J
    常用adb 命令
    bootstrap-datepicker实现只能选择每一年的某一个月份
    R语言中的prophet预测时间序列数据模型
    架构的未来——End
    zabbix监控安装-linux
  • 原文地址:https://blog.csdn.net/Hunter_xiaotan/article/details/125541178