• 人工智能基础 作业6


    本次来实现XO图形的识别

    数据集

    数据集要按照一定比例自行划分好训练集training_set和测试集test_set

    代码

    1. import torch
    2. from torch import nn, optim
    3. from torch.utils.data import DataLoader, Dataset
    4. from torchvision import datasets, transforms
    5. # 模型构建
    6. class Net(nn.Module):
    7. def __init__(self):
    8. super(Net, self).__init__()
    9. self.conv1 = nn.Conv2d(1, 9, 3)
    10. self.maxpool = nn.MaxPool2d(2, 2)
    11. self.conv2 = nn.Conv2d(9, 5, 3)
    12. self.relu = nn.ReLU()
    13. self.fc1 = nn.Linear(27 * 27 * 5, 1200)
    14. self.fc2 = nn.Linear(1200, 64)
    15. self.fc3 = nn.Linear(64, 2)
    16. def forward(self, x):
    17. x = self.maxpool(self.relu(self.conv1(x)))
    18. x = self.maxpool(self.relu(self.conv2(x)))
    19. x = x.view(-1, 27 * 27 * 5)
    20. x = self.relu(self.fc1(x))
    21. x = self.relu(self.fc2(x))
    22. x = self.fc3(x)
    23. return x
    24. # 数据集加载
    25. data_loader = DataLoader(
    26. dataset=datasets.ImageFolder(
    27. root='training_data_sm',
    28. transform=transforms.Compose([
    29. transforms.Grayscale(),
    30. transforms.ToTensor()
    31. ])
    32. ),
    33. batch_size=64,
    34. shuffle=True
    35. )
    36. # 实例化模型
    37. model = Net()
    38. # 损失函数
    39. criterion = torch.nn.CrossEntropyLoss()
    40. # 参数优化器
    41. optimizer = optim.SGD(model.parameters(), lr=0.1)
    42. # 开始训练
    43. epochs = 10
    44. for epoch in range(epochs):
    45. running_loss = 0.0
    46. for i, data in enumerate(data_loader):
    47. # 获取数据
    48. images, label = data # images.shape = (batch, 1, w, h)
    49. # 推理
    50. out = model(images)
    51. # 计算损失
    52. loss = criterion(out, label)
    53. # 清空梯度
    54. optimizer.zero_grad()
    55. # 反向传播
    56. loss.backward()
    57. # 更新参数
    58. optimizer.step()
    59. # 计算平均损失
    60. running_loss += loss.item()
    61. if (i + 1) % 10 == 0:
    62. print('[%d %5d] loss: %.3f' % (epoch + 1, i + 1, running_loss / 100))
    63. running_loss = 0.0
    64. print('finished train')
    65. # 保存模型
    66. torch.save(model, 'model_name.pth') # 保存的是模型, 不止是w和b权重值

     训练

    [1     10]   loss: 0.069
    [1     20]   loss: 0.068
    [1     30]   loss: 0.065
    [2     10]   loss: 0.057
    [2     20]   loss: 0.038
    [2     30]   loss: 0.016
    [3     10]   loss: 0.009
    [3     20]   loss: 0.007
    [3     30]   loss: 0.005
    [4     10]   loss: 0.037
    [4     20]   loss: 0.021
    [4     30]   loss: 0.007
    [5     10]   loss: 0.003
    [5     20]   loss: 0.003
    [5     30]   loss: 0.002
    [6     10]   loss: 0.002
    [6     20]   loss: 0.001
    [6     30]   loss: 0.002
    [7     10]   loss: 0.001
    [7     20]   loss: 0.001
    [7     30]   loss: 0.001
    [8     10]   loss: 0.000
    [8     20]   loss: 0.002
    [8     30]   loss: 0.000
    [9     10]   loss: 0.000
    [9     20]   loss: 0.001
    [9     30]   loss: 0.000
    [10     10]   loss: 0.000
    [10     20]   loss: 0.000
    [10     30]   loss: 0.001
    finished train

     测试

    1. images, labels = data_loader.__iter__().__next__()
    2. # 读取一张图片 images[0],测试
    3. print("labels[0] truth:\t", labels[0])
    4. x = images[0]
    5. # 读取模型
    6. model_load = torch.load('model_name.pth')
    7. predicted = torch.max(model_load(x), 1)
    8. print("labels[0] predict:\t", predicted.indices)
    9. img = images[0].data.squeeze().numpy() # 将输出转换为图片的格式
    10. plt.imshow(img, cmap='gray')
    11. plt.show()

     计算模型的准确率

    1. data_loader_test = DataLoader(
    2. dataset=datasets.ImageFolder(
    3. root='test_data_sm',
    4. transform=transforms.Compose([
    5. transforms.Grayscale(),
    6. transforms.ToTensor()
    7. ])
    8. ),
    9. batch_size=64,
    10. shuffle=True
    11. )
    12. # 读取模型
    13. model_load = torch.load('model_name.pth')
    14. correct = 0
    15. total = 0
    16. with torch.no_grad(): # 进行评测的时候网络不更新梯度
    17. for data in data_loader_test: # 读取测试集
    18. images, labels = data
    19. outputs = model_load(images)
    20. _, predicted = torch.max(outputs.data, 1) # 取出 最大值的索引 作为 分类结果
    21. total += labels.size(0) # labels 的长度
    22. correct += (predicted == labels).sum().item() # 预测正确的数目
    23. print('Accuracy of the network on the test images: %f %%' % (100. * correct / total))

    Accuracy of the network on the  test images: 99.550000 %

    查看训练好的模型特征图 

    1. # 看看每层的 卷积核 长相,特征图 长相
    2. # 获取网络结构的特征矩阵并可视化
    3. import torch
    4. import matplotlib.pyplot as plt
    5. import numpy as np
    6. from PIL import Image
    7. from torchvision import transforms, datasets
    8. import torch.nn as nn
    9. from torch.utils.data import DataLoader
    10. # 定义图像预处理过程(要与网络模型训练过程中的预处理过程一致)
    11. transforms = transforms.Compose([
    12. transforms.ToTensor(), # 把图片进行归一化,并把数据转换成Tensor类型
    13. transforms.Grayscale(1) # 把图片 转为灰度图
    14. ])
    15. path = r'training_data_sm'
    16. data_train = datasets.ImageFolder(path, transform=transforms)
    17. data_loader = DataLoader(data_train, batch_size=64, shuffle=True)
    18. for i, data in enumerate(data_loader):
    19. images, labels = data
    20. print(images.shape)
    21. print(labels.shape)
    22. break
    23. class Net(nn.Module):
    24. def __init__(self):
    25. super(Net, self).__init__()
    26. self.conv1 = nn.Conv2d(1, 9, 3) # in_channel , out_channel , kennel_size , stride
    27. self.maxpool = nn.MaxPool2d(2, 2)
    28. self.conv2 = nn.Conv2d(9, 5, 3) # in_channel , out_channel , kennel_size , stride
    29. self.relu = nn.ReLU()
    30. self.fc1 = nn.Linear(27 * 27 * 5, 1200) # full connect 1
    31. self.fc2 = nn.Linear(1200, 64) # full connect 2
    32. self.fc3 = nn.Linear(64, 2) # full connect 3
    33. def forward(self, x):
    34. outputs = []
    35. x = self.conv1(x)
    36. outputs.append(x)
    37. x = self.relu(x)
    38. outputs.append(x)
    39. x = self.maxpool(x)
    40. outputs.append(x)
    41. x = self.conv2(x)
    42. x = self.relu(x)
    43. x = self.maxpool(x)
    44. x = x.view(-1, 27 * 27 * 5)
    45. x = self.relu(self.fc1(x))
    46. x = self.relu(self.fc2(x))
    47. x = self.fc3(x)
    48. return outputs
    49. model1 = torch.load('model_name.pth')
    50. # 打印出模型的结构
    51. print(model1)
    52. x = images[0]
    53. # forward正向传播过程
    54. out_put = model1(x)
    55. for feature_map in out_put:
    56. # [N, C, H, W] -> [C, H, W] 维度变换
    57. im = np.squeeze(feature_map.detach().numpy())
    58. # [C, H, W] -> [H, W, C]
    59. im = np.transpose(im, [1, 2, 0])
    60. print(im.shape)
    61. # show 9 feature maps
    62. plt.figure()
    63. for i in range(9):
    64. ax = plt.subplot(3, 3, i + 1) # 参数意义:3:图片绘制行数,5:绘制图片列数,i+1:图的索引
    65. # [H, W, C]
    66. # 特征矩阵每一个channel对应的是一个二维的特征矩阵,就像灰度图像一样,channel=1
    67. # plt.imshow(im[:, :, i])
    68. plt.imshow(im[:, :, i], cmap='gray')
    69. plt.show()

    卷积后的特征图

    激活后的特征图

    池化后的特征图

     查看训练好的模型的卷积核

    1. # 看看每层的 卷积核 长相,特征图 长相
    2. # 获取网络结构的特征矩阵并可视化
    3. import torch
    4. import matplotlib.pyplot as plt
    5. import numpy as np
    6. from PIL import Image
    7. from torchvision import transforms, datasets
    8. import torch.nn as nn
    9. from torch.utils.data import DataLoader
    10. plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签
    11. plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号 #有中文出现的情况,需要u'内容
    12. # 定义图像预处理过程(要与网络模型训练过程中的预处理过程一致)
    13. transforms = transforms.Compose([
    14. transforms.ToTensor(), # 把图片进行归一化,并把数据转换成Tensor类型
    15. transforms.Grayscale(1) # 把图片 转为灰度图
    16. ])
    17. path = r'training_data_sm'
    18. data_train = datasets.ImageFolder(path, transform=transforms)
    19. data_loader = DataLoader(data_train, batch_size=64, shuffle=True)
    20. for i, data in enumerate(data_loader):
    21. images, labels = data
    22. # print(images.shape)
    23. # print(labels.shape)
    24. break
    25. class Net(nn.Module):
    26. def __init__(self):
    27. super(Net, self).__init__()
    28. self.conv1 = nn.Conv2d(1, 9, 3) # in_channel , out_channel , kennel_size , stride
    29. self.maxpool = nn.MaxPool2d(2, 2)
    30. self.conv2 = nn.Conv2d(9, 5, 3) # in_channel , out_channel , kennel_size , stride
    31. self.relu = nn.ReLU()
    32. self.fc1 = nn.Linear(27 * 27 * 5, 1200) # full connect 1
    33. self.fc2 = nn.Linear(1200, 64) # full connect 2
    34. self.fc3 = nn.Linear(64, 2) # full connect 3
    35. def forward(self, x):
    36. outputs = []
    37. x = self.maxpool(self.relu(self.conv1(x)))
    38. # outputs.append(x)
    39. x = self.maxpool(self.relu(self.conv2(x)))
    40. outputs.append(x)
    41. x = x.view(-1, 27 * 27 * 5)
    42. x = self.relu(self.fc1(x))
    43. x = self.relu(self.fc2(x))
    44. x = self.fc3(x)
    45. return outputs
    46. model1 = torch.load('model_name.pth')
    47. x = images[0]
    48. # forward正向传播过程
    49. out_put = model1(x)
    50. weights_keys = model1.state_dict().keys()
    51. for key in weights_keys:
    52. print("key :", key)
    53. # 卷积核通道排列顺序 [kernel_number, kernel_channel, kernel_height, kernel_width]
    54. if key == "conv1.weight":
    55. weight_t = model1.state_dict()[key].numpy()
    56. print("weight_t.shape", weight_t.shape)
    57. k = weight_t[:, 0, :, :] # 获取第一个卷积核的信息参数
    58. # show 9 kernel ,1 channel
    59. plt.figure()
    60. for i in range(9):
    61. ax = plt.subplot(3, 3, i + 1) # 参数意义:3:图片绘制行数,5:绘制图片列数,i+1:图的索引
    62. plt.imshow(k[i, :, :], cmap='gray')
    63. title_name = 'kernel' + str(i) + ',channel1'
    64. plt.title(title_name)
    65. plt.show()
    66. if key == "conv2.weight":
    67. weight_t = model1.state_dict()[key].numpy()
    68. print("weight_t.shape", weight_t.shape)
    69. k = weight_t[:, :, :, :] # 获取第一个卷积核的信息参数
    70. print(k.shape)
    71. print(k)
    72. plt.figure()
    73. for c in range(9):
    74. channel = k[:, c, :, :]
    75. for i in range(5):
    76. ax = plt.subplot(2, 3, i + 1) # 参数意义:3:图片绘制行数,5:绘制图片列数,i+1:图的索引
    77. plt.imshow(channel[i, :, :], cmap='gray')
    78. title_name = 'kernel' + str(i) + ',channel' + str(c)
    79. plt.title(title_name)
    80. plt.show()

  • 相关阅读:
    【机器学习可解释性】4.SHAP 值
    软件设计模式系列之六——单例模式
    【2023】Git版本控制-远程仓库详解
    在springboot中实现WebSocket协议通信
    QT实战项目1——无边框窗口拖拽和阴影
    leetcode 63. 不同路径 II
    NIFI集群_队列Queue中数据无法清空_清除队列数据报错_无法删除queue_解决_集群中机器交替重启删除---大数据之Nifi工作笔记0061
    微信小程序商城搭建步骤_我们来说说微信小程序商城开发的作用
    好物周刊#19:开源指北
    centos使用Iptables控制防火墙——使用
  • 原文地址:https://blog.csdn.net/Rabbit_Gray/article/details/124937776