当前位置:   article > 正文

Pytorch实战02——使用AlexNet网络,完成flower的识别_使用pytorch构建alexnet神经网络进行花卉识别

使用pytorch构建alexnet神经网络进行花卉识别

目录

AlexNet网络结构:

1、model模型搭建

2、train.py训练文件

3、predict.py预测文件

4、预测结果展示:​​​​​​​


AlexNet网络结构:

①AlexNet网络模型的亮点在于:

(1)首次使用GPU进行网络加速训练。

(2)使用了ReLU激活函数,而不是传统的Sigmoid激活函数以及Tanh激活函数。

(3)使用了LRN局部响应归一化。

(4)在全连接层的前两层中使用了Dropout随机失活神经元操作,以减少过拟合。

②使用Droptout:

1、model模型搭建

  1. import torch
  2. import torch.nn as nn
  3. '''
  4. AlexNet网络的亮点:
  5. ①首次利用GPU进行网络加速训练。(2012年)
  6. ②使用了RuLU激活函数,而不是传统的Sigmoid激活函数以及Tanh激活函数。
  7. ③使用了LRN局部响应归一化。
  8. ④在全连接层的前两层中使用了Dropout随机失活神经元操作,以减少过拟合!!!。
  9. '''
  10. class AlexNet(nn.Module):
  11. def __init__(self,num_classes=1000, init_weights=False): # init_weights=False 初始化权重
  12. super(AlexNet, self).__init__()
  13. self.features = nn.Sequential( # 将一系列打包nn.Sequential()精简代码
  14. nn.Conv2d(3, 48, kernel_size=11, stride=4, padding=2), # input[3,224,224] output[48,55,55]
  15. nn.ReLU(inplace=True), # inplace=True 增加计算量,减少内存使用
  16. nn.MaxPool2d(kernel_size=3, stride=2),
  17. nn.Conv2d(48, 128, kernel_size=5, padding=2),
  18. nn.ReLU(inplace=True),
  19. nn.MaxPool2d(kernel_size=3, stride=2),
  20. nn.Conv2d(128, 192, kernel_size=3, padding=1),
  21. nn.ReLU(inplace=True),
  22. nn.Conv2d(192,192,kernel_size=3,padding=1),
  23. nn.ReLU(inplace=True),
  24. nn.Conv2d(192,128,kernel_size=3,padding=1),
  25. nn.ReLU(inplace=True),
  26. nn.MaxPool2d(kernel_size=3, stride=2)
  27. )
  28. self.classifier = nn.Sequential(
  29. nn.Dropout(p=0.5), # p=0.5 随机失活的参数 ( 默认为0.5 )
  30. nn.Linear(128 * 6 * 6, 2048), # 全连接层
  31. nn.ReLU(inplace=True), # 激活函数
  32. nn.Dropout(p=0.5),
  33. nn.Linear(2048,2048),
  34. nn.ReLU(inplace=True),
  35. nn.Linear(2048, num_classes)
  36. )
  37. if init_weights: # 初始化权重函数
  38. self._initialize_weights()
  39. def forward(self,x):
  40. x = self.features(x)
  41. x = torch.flatten(x, start_dim=1) # 展平处理.
  42. x = self.classifier(x)
  43. return x
  44. def _initialize_weights(self): # 初始化权重的函数
  45. for m in self.modules(): # self.modules() 继承了nn.Module这个函数;会遍历每一个层结构
  46. if isinstance(m, nn.Conv2d): # 判断层结构是否是卷积层
  47. nn.init.kaiming_normal_(m.weight, mode='fan_in') # 使用kaiming_normal_()这个权重对w进行初始化
  48. if m.bias is not None: # 如果偏置不为空,就用0对其进行初始化
  49. nn.init.constant_(m.bias,0) # 对其偏置初始化为0
  50. elif isinstance(m, nn.Linear):
  51. nn.init.normal_(m.weight, 0, 0.01) # 通过正态分布,对其进行赋值;均值为0;方差为0.01
  52. nn.init.constant_(m.bias, 0) # 对其偏置,初始化为0

2、train.py训练文件

  1. import json
  2. import os.path
  3. import time
  4. import matplotlib.pyplot as plt
  5. import numpy as np
  6. import torch
  7. from torch import nn, optim
  8. from torchvision import datasets, utils
  9. from torchvision.transforms import transforms
  10. from model import AlexNet
  11. device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')
  12. print(device)
  13. data_transform = {
  14. 'train': transforms.Compose([transforms.RandomResizedCrop(224), # 随机裁剪224x224大小
  15. transforms.RandomHorizontalFlip(), # 水平方向上进行随机反转
  16. transforms.ToTensor(), # 转化成tensor
  17. transforms.Normalize((0.5,0.5,0.5),(0.5,0.5,0.5))]), # 标准化处理
  18. 'val': transforms.Compose([transforms.Resize((224,224)),
  19. transforms.ToTensor(),
  20. transforms.Normalize((0.5,0.5,0.5),(0.5,0.5,0.5))])
  21. }
  22. data_root = os.path.abspath(os.path.join(os.getcwd())) # 获取当前文件所在的目录
  23. image_path = data_root+'/flower_data/' # flower的路径地址
  24. print("image_path",image_path)
  25. # 获取训练集数据
  26. train_dataset = datasets.ImageFolder(root=image_path+'/train',
  27. transform=data_transform['train']) # transform数据预处理,上面定义的
  28. train_num = len(train_dataset) # 训练的数量个数
  29. flower_list = train_dataset.class_to_idx # {'daisy': 0, 'dandelion': 1, 'roses': 2, 'sunflowers': 3, 'tulips': 4}
  30. cla_dict = dict((val,key) for key,val in flower_list.items()) # 将其键值对反过来。 {0: 'daisy', 1: 'dandelion', 2: 'roses', 3: 'sunflowers', 4: 'tulips'}
  31. json_str = json.dumps(cla_dict, indent=4) # 转换成json的格式; indent=4 表示前面空4格
  32. with open('class_indices.json', 'w') as json_file: # 将上面生成的json_str 的格式,存入到class_indices.json文件中
  33. json_file.write(json_str)
  34. batch_size = 32
  35. # 加载训练集数据
  36. train_loader = torch.utils.data.DataLoader(train_dataset,
  37. batch_size=batch_size,
  38. shuffle=True,
  39. num_workers=0)
  40. # 获取测试集数据
  41. validate_dataset = datasets.ImageFolder(root=image_path+'/val',
  42. transform=data_transform['val'])
  43. val_num = len(validate_dataset) # 训练集的数量
  44. # 加载训练集数据
  45. validate_loader = torch.utils.data.DataLoader(validate_dataset,
  46. batch_size=batch_size,
  47. shuffle=False,
  48. num_workers=0)
  49. # # 测试查看下 数据集 → 把validate_loader里面的batch_size改为4
  50. # test_image,test_label = next(iter(validate_loader))
  51. #
  52. #
  53. # def imshow(img):
  54. # img = img / 2 + 0.5 # unnormalize
  55. # npimg = img.numpy()
  56. # plt.imshow(np.transpose(npimg,(1,2,0)))
  57. # plt.show()
  58. #
  59. # print(' '.join('%5s' % cla_dict[test_label[j].item()] for j in range(4)))
  60. # imshow(utils.make_grid(test_image))
  61. # 实例化
  62. net = AlexNet(num_classes=5, init_weights=True)
  63. net.to(device) # 将网络指定到,设置的device上面
  64. loss_function = nn.CrossEntropyLoss() # 定义损失函数(损失交叉熵函数)
  65. optimizer = optim.Adam(net.parameters(),lr=0.0002) # 定义优化器,使用Adam优化器,优化对象是网络中所有的可训练的参数
  66. save_path = './AlexNet.pth' # 保存地址
  67. best_acc = 0.0 # 保存学习率最高的那次训练的模型
  68. for epoch in range(10):
  69. # train
  70. net.train() # 使用net.train() 和net.eval()方法管理DropOut()方法; 调用net.train()会启动调用DropOut()方法; net.eval()关闭调用DropOut()方法
  71. running_loss = 0.0 # 计算训练过程中的损失
  72. t1 = time.perf_counter()
  73. for step, data in enumerate(train_loader, start=0):
  74. images, labels = data
  75. optimizer.zero_grad() # 清空梯度信息
  76. outputs = net(images.to(device)) # 将图片指定到device上
  77. loss = loss_function(outputs, labels.to(device))
  78. loss.backward() # 反向传播,到每个节点
  79. optimizer.step() # 更新参数
  80. running_loss += loss.item()
  81. # 打印训练过程的进度条
  82. rate = (step+1) / len(train_loader)
  83. a = '*'*int(rate*50)
  84. b = '.'*int((1-rate)*50)
  85. print("\rtrain loss:{:^3.0f}% [{}->{}]{:.3f}".format(int(rate*100), a, b, loss), end="")
  86. print()
  87. print(time.perf_counter()-t1)
  88. # validate 验证集
  89. net.eval() # 关闭调用DropOut()方法
  90. acc = 0.0
  91. with torch.no_grad():
  92. for data_test in validate_loader:
  93. test_images, test_labels = data_test
  94. outputs = net(test_images.to(device))
  95. predict_y = torch.max(outputs, dim=1)[1]
  96. acc += (predict_y == test_labels.to(device)).sum().item()
  97. accurate_test = acc / val_num
  98. if accurate_test > best_acc: # 获得最优准确率
  99. best_acc = accurate_test
  100. torch.save(net.state_dict(), save_path)
  101. print('[epoch %d] train_loss:%.3f test_accuracy:%.3f' % (epoch+1, running_loss/step, acc/val_num))
  102. print('Finished Training')

 训练文件运行结果:

结果展示,训练的损失在下降,测试的准确率最高达到72%。

3、predict.py预测文件

  1. import torch
  2. from model import AlexNet
  3. from PIL import Image
  4. from torchvision import transforms
  5. import matplotlib.pyplot as plt
  6. import json
  7. # 定义图片预处理函数
  8. data_transform = transforms.Compose(
  9. [transforms.Resize((224,224)), # 将图片缩放到224x224
  10. transforms.ToTensor(), # 转换成tensor格式
  11. transforms.Normalize((0.5,0.5,0.5),(0.5,0.5,0.5))] # 标准化处理
  12. )
  13. # 加载图片
  14. img = Image.open('./tulip.jpg')
  15. plt.imshow(img)
  16. # [N,C,H,W]
  17. img = data_transform(img) # 对图片进行预处理(上面定义的)
  18. # 扩充一个维度
  19. img = torch.unsqueeze(img, dim=0)
  20. # 读取之前保存的.json文件
  21. try:
  22. json_file = open('./class_indices.json', 'r')
  23. class_indict = json.load(json_file)
  24. except Exception as e:
  25. print(e)
  26. exit(-1)
  27. # 创建model
  28. model = AlexNet(num_classes=5)
  29. # 加载模型权重
  30. model_weight_path = './AlexNet.pth'
  31. model.load_state_dict(torch.load(model_weight_path))
  32. model.eval()
  33. # 不跟踪变量的损失梯度
  34. with torch.no_grad():
  35. output = torch.squeeze(model(img)) # 维度压缩
  36. predict = torch.softmax(output, dim=0)
  37. predict_cla = torch.argmax(predict).numpy() # 概率最大数
  38. print(class_indict[str(predict_cla)], predict[predict_cla].item()) # 打印预测名称,预测概率
  39. plt.show()

4、预测结果展示:

①给定的图片:

预测结果:(预测结果正确,显示87%的概率是郁金香

②给定图片:

预测结果:(预测结果正确,显示99.7%的概率为向日葵

至此,我们使用AlexNet搭建的神经网络结构,预测flower分类,就暂时到这里啦。

代码,我是在服务器上面跑的,我的本地实在带动不起来,电脑配置不给力。

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

闽ICP备14008679号