当前位置:   article > 正文

基于卷积神经网络的猫狗识别-python实现_python猫狗识别

python猫狗识别

介绍

        文章内容来自我的《深度学习》课程作业实验报告。

        图像识别是在提取图像特征的基础上,对图像的各种不同模式目标和对象 进行识别的技术。本实验通过对 Kaggle 上的 Cats.vs.Dogs 图像数据集进行学习, 实现识别图片的猫狗类型。深度学习方法在图像识别中应用比较广泛。用于基于 卷积神经网络的图像识别方法有很多,常用的卷积神经网络模型有 LeNet、 AleXNet、GoogLeNet、VGGNet、ResNet 等模型。本实验使用 Kaggle 上的 Cats vs.Dogs 图像数据集的部分数据,采用了结构较为简单的 AleXNet 网络,并引入 了预训练模型,构建了算法构建一个卷积神经网络模型,解决了猫狗二分类图像识别问题。

解决方案

2.1 AlexNet 模型

        模型使用 AlexNet 模型进行猫狗分类。AlexNet 输入为 RGB 三通道的 224 × 224 × 3 大小的图像(也可填充为 227 × 227 × 3 )。AlexNet 共包含 5 个 卷积层(包含 3 个池化)和 3 个全连接层。其中,每个卷积层都包含卷积核、 偏置项、ReLU 激活函数和局部响应归一化(LRN)模块。第 1、2、5 个卷积层 后面都跟着一个最大池化层,后三个层为全连接层。最终输出层为 softmax,将 网络输出转化为概率值,用于预测图像的类别。模型结构如下:

2.2 损失函数

        使用交叉熵损失作为损失函数,计算公式如下:

2.3 评价指标

       使用精确度作为评价指标,计算公式如下:

其中:TP为真正例,TN为真负例,FP为假正例,FN为假负例。

 

实验结果和分析

3.1 数据集与工具

        Visual Studio Code

        PyTorch 1.13

        kaggle Dogs vs. Cats 数据集

3.2 训练过程及代码

       首先进行数据的预处理,将原始数据集中训练集里的猫狗图像人为重新划分训练集和测试集。其中,训练集2000张,测试集500张,猫狗各占50%。将数据的红绿蓝通道以均值0.485, 0.456, 0.406,标准差0.229, 0.224, 0.225进行归一化处理,并且依据概率对图片水平翻转,进行数据增强。

       构建模型AlexNet模型,这里使用了torchvision.models中的模型结构,参数初始化为AlexNet提供的参数,在此基础上进行微调,大大降低了训练时间。

  1. # 加载模型
  2. def get_model(path_state_dict, vis_model=False):
  3. """
  4. 创建模型,加载参数
  5. :param path_state_dict:
  6. :return:
  7. """
  8. model = alexnet()
  9. pretrained_state_dict = torch.load(path_state_dict)
  10. model.load_state_dict(pretrained_state_dict)
  11. if vis_model:
  12. print(model)
  13. return model

获取AlexNet模型,并对其结构进行修改。因为是二分类问题,所以将最后输出的类别,从1000改为2。

  1. # ============================ step 2/5 模型 ============================
  2. alexnet_model = get_model(path_state_dict, True)
  3. num_ftrs = alexnet_model.classifier._modules["6"].in_features
  4. alexnet_model.classifier._modules["6"] = nn.Linear(num_ftrs, num_classes)
  5. alexnet_model.to("cuda" if torch.cuda.is_available() else "cpu")

定义损失函数与优化器

  1. # ============================ step 3/5 损失函数 ============================
  2. criterion = nn.CrossEntropyLoss()
  3. # ============================ step 4/5 优化器 ============================
  4. optimizer = torch.optim.SGD(alexnet_model.parameters(), lr=LR, momentum=0.9) # 选择优化器
  5. scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=lr_decay_step, gamma=0.1) # 设置学习率下降策略

训练与测试过程

  1. # ============================ step 5/5 训练 ============================
  2. train_curve = []
  3. train_acc=[]
  4. valid_curve = []
  5. valid_acc=[]
  6. for epoch in range(start_epoch + 1, MAX_EPOCH):
  7. loss_mean = 0.
  8. correct = 0.
  9. total = 0.
  10. alexnet_model.train()
  11. for i, data in enumerate(train_loader):
  12. # forward
  13. inputs, labels = data
  14. inputs, labels = inputs.to(device), labels.to(device)
  15. outputs = alexnet_model(inputs)
  16. # backward
  17. optimizer.zero_grad()
  18. loss = criterion(outputs, labels)
  19. loss.backward()
  20. # update weights
  21. optimizer.step()
  22. # 统计分类情况
  23. predicted = torch.argmax(outputs.data, 1)
  24. total += labels.size(0)
  25. correct += torch.sum(predicted == labels)
  26. # 打印训练信息
  27. loss_mean += loss.item()
  28. train_curve.append(loss.item())
  29. train_acc.append(correct / total)
  30. if (i+1) % log_interval == 0:
  31. loss_mean = loss_mean / log_interval
  32. print("Training:Epoch[{:0>3}/{:0>3}] Iteration[{:0>3}/{:0>3}] Loss: {:.4f} Acc:{:.2%}".format(
  33. epoch, MAX_EPOCH, i+1, len(train_loader), loss_mean, correct / total))
  34. loss_mean = 0.
  35. scheduler.step() # 更新学习率
  36. # validate the model
  37. if (epoch+1) % val_interval == 0:
  38. correct_val = 0.
  39. total_val = 0.
  40. loss_val = 0.
  41. alexnet_model.eval()
  42. with torch.no_grad():
  43. for j, data in enumerate(valid_loader):
  44. inputs, labels = data
  45. inputs, labels = inputs.to(device), labels.to(device)
  46. bs, ncrops, c, h, w = inputs.size() # [4, 10, 3, 224, 224
  47. outputs = alexnet_model(inputs.view(-1, c, h, w))
  48. outputs_avg = outputs.view(bs, ncrops, -1).mean(1)
  49. loss = criterion(outputs_avg, labels)
  50. predicted = torch.argmax(outputs_avg.data, 1)
  51. total_val += labels.size(0)
  52. correct_val += torch.sum(predicted == labels)
  53. loss_val += loss.item()
  54. loss_val_mean = loss_val/len(valid_loader)
  55. valid_curve.append(loss_val_mean)
  56. valid_acc.append(correct_val / total_val)
  57. print("Valid:\t Epoch[{:0>3}/{:0>3}] Iteration[{:0>3}/{:0>3}] Loss: {:.4f} Acc:{:.2%}".format(
  58. epoch, MAX_EPOCH, j+1, len(valid_loader), loss_val_mean, correct_val / total_val))
  59. alexnet_model.train()

3.3 结果与分析

        迭代过程中,交叉熵损失与精确度变化情况如上图所示。训练和测试均设置batch为64。在训练过程中,每一个iteration,交叉熵损失与准确度进行一次计算。测试过程中,每一个epoch,交叉熵损失与准确度进行一次计算。整个过程设置了epoch=3。在图中可以看出,在第一个epoch后,模型逐渐趋于稳定,并且没有出现明显的过拟合或欠拟合现象。在最后一个epoch后,交叉熵损失为0.0765,准确率为96.60%。

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

闽ICP备14008679号