• 基于Pytorch框架的深度学习MobileViT神经网络鸟类识别分类系统源码


     第一步:准备数据

    25种鸟类数据:self.class_indict = ["非洲冠鹤", "灰顶火雀", "信天翁", "亚历山大鹦鹉", "褐胸反嘴鹬", "美洲麻鳽", "美洲骨顶", "美洲金翅雀", "美洲隼", "美洲鹨", "美洲红尾鸟", "美洲蛇鸟", "安式蜂鸟", "蚁鸟", "阿拉里皮娇鹟", "朱鹮", "白头鵰", "巴厘岛八哥", "摩金莺", "蕉林莺", "带斑阔嘴鸟", "斑尾塍鹬", "仓鸮", "燕子", "横斑蓬头䴕"]

    ,总共有3800张图片,每个文件夹单独放一种数据

    第二步:搭建模型

    本文选择一个MobileViT网络,其原理介绍如下:

            MobileViT是一种基于ViT(Vision Transformer)架构的轻量级视觉模型,旨在适用于移动设备和嵌入式系统。ViT是一种非常成功的深度学习模型,用于图像分类和其他计算机视觉任务,但通常需要大量的计算资源和参数。MobileViT的目标是在保持高性能的同时,减少模型的大小和计算需求,以便在移动设备上运行,据作者介绍,这是第一次基于轻量级CNN网络性能的轻量级ViT工作,性能SOTA。性能优于MobileNetV3、CrossviT等网络。

    Vision Transformer结构
    下图是MobileViT论文中绘制的Standard visual Transformer。首先将输入的图片划分成N个Patch,然后通过线性变化将每个Patch映射到一维向量中(Token),接着加上位置偏置信息(可学习参数),再通过一系列Transformer Block,最后通过一个全连接层得到最终预测输出。

    MobileViT结构

    上面展示是标准视觉ViT模型,下面来看下本次介绍的重点:Mobile-ViT网路结构,如下图所示:

    第三步:训练代码

    1)损失函数为:交叉熵损失函数

    2)训练代码:

    1. import os
    2. import argparse
    3. import torch
    4. import torch.optim as optim
    5. from torch.utils.tensorboard import SummaryWriter
    6. from torchvision import transforms
    7. from my_dataset import MyDataSet
    8. from model import mobile_vit_xx_small as create_model
    9. from utils import read_split_data, train_one_epoch, evaluate
    10. def main(args):
    11. device = torch.device(args.device if torch.cuda.is_available() else "cpu")
    12. if os.path.exists("./weights") is False:
    13. os.makedirs("./weights")
    14. tb_writer = SummaryWriter()
    15. train_images_path, train_images_label, val_images_path, val_images_label = read_split_data(args.data_path)
    16. img_size = 224
    17. data_transform = {
    18. "train": transforms.Compose([transforms.RandomResizedCrop(img_size),
    19. transforms.RandomHorizontalFlip(),
    20. transforms.ToTensor(),
    21. transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])]),
    22. "val": transforms.Compose([transforms.Resize(int(img_size * 1.143)),
    23. transforms.CenterCrop(img_size),
    24. transforms.ToTensor(),
    25. transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])])}
    26. # 实例化训练数据集
    27. train_dataset = MyDataSet(images_path=train_images_path,
    28. images_class=train_images_label,
    29. transform=data_transform["train"])
    30. # 实例化验证数据集
    31. val_dataset = MyDataSet(images_path=val_images_path,
    32. images_class=val_images_label,
    33. transform=data_transform["val"])
    34. batch_size = args.batch_size
    35. nw = min([os.cpu_count(), batch_size if batch_size > 1 else 0, 8]) # number of workers
    36. print('Using {} dataloader workers every process'.format(nw))
    37. train_loader = torch.utils.data.DataLoader(train_dataset,
    38. batch_size=batch_size,
    39. shuffle=True,
    40. pin_memory=True,
    41. num_workers=nw,
    42. collate_fn=train_dataset.collate_fn)
    43. val_loader = torch.utils.data.DataLoader(val_dataset,
    44. batch_size=batch_size,
    45. shuffle=False,
    46. pin_memory=True,
    47. num_workers=nw,
    48. collate_fn=val_dataset.collate_fn)
    49. model = create_model(num_classes=args.num_classes).to(device)
    50. if args.weights != "":
    51. assert os.path.exists(args.weights), "weights file: '{}' not exist.".format(args.weights)
    52. weights_dict = torch.load(args.weights, map_location=device)
    53. weights_dict = weights_dict["model"] if "model" in weights_dict else weights_dict
    54. # 删除有关分类类别的权重
    55. for k in list(weights_dict.keys()):
    56. if "classifier" in k:
    57. del weights_dict[k]
    58. print(model.load_state_dict(weights_dict, strict=False))
    59. if args.freeze_layers:
    60. for name, para in model.named_parameters():
    61. # 除head外,其他权重全部冻结
    62. if "classifier" not in name:
    63. para.requires_grad_(False)
    64. else:
    65. print("training {}".format(name))
    66. pg = [p for p in model.parameters() if p.requires_grad]
    67. optimizer = optim.AdamW(pg, lr=args.lr, weight_decay=1E-2)
    68. best_acc = 0.
    69. for epoch in range(args.epochs):
    70. # train
    71. train_loss, train_acc = train_one_epoch(model=model,
    72. optimizer=optimizer,
    73. data_loader=train_loader,
    74. device=device,
    75. epoch=epoch)
    76. # validate
    77. val_loss, val_acc = evaluate(model=model,
    78. data_loader=val_loader,
    79. device=device,
    80. epoch=epoch)
    81. tags = ["train_loss", "train_acc", "val_loss", "val_acc", "learning_rate"]
    82. tb_writer.add_scalar(tags[0], train_loss, epoch)
    83. tb_writer.add_scalar(tags[1], train_acc, epoch)
    84. tb_writer.add_scalar(tags[2], val_loss, epoch)
    85. tb_writer.add_scalar(tags[3], val_acc, epoch)
    86. tb_writer.add_scalar(tags[4], optimizer.param_groups[0]["lr"], epoch)
    87. if val_acc > best_acc:
    88. best_acc = val_acc
    89. torch.save(model.state_dict(), "./weights/best_model.pth")
    90. torch.save(model.state_dict(), "./weights/latest_model.pth")
    91. if __name__ == '__main__':
    92. parser = argparse.ArgumentParser()
    93. parser.add_argument('--num_classes', type=int, default=25)
    94. parser.add_argument('--epochs', type=int, default=100)
    95. parser.add_argument('--batch-size', type=int, default=4)
    96. parser.add_argument('--lr', type=float, default=0.0002)
    97. # 数据集所在根目录
    98. # https://storage.googleapis.com/download.tensorflow.org/example_images/flower_photos.tgz
    99. parser.add_argument('--data-path', type=str,
    100. default=r"G:\demo\data\Bird_Dataset\birds\train")
    101. # 预训练权重路径,如果不想载入就设置为空字符
    102. parser.add_argument('--weights', type=str, default='./mobilevit_xxs.pt',
    103. help='initial weights path')
    104. # 是否冻结权重
    105. parser.add_argument('--freeze-layers', type=bool, default=False)
    106. parser.add_argument('--device', default='cuda:0', help='device id (i.e. 0 or 0,1 or cpu)')
    107. opt = parser.parse_args()
    108. main(opt)

    第四步:统计正确率

    第五步:搭建GUI界面

    第六步:整个工程的内容

    有训练代码和训练好的模型以及训练过程,提供数据,提供GUI界面代码

    代码的下载路径(新窗口打开链接):基于Pytorch框架的深度学习MobileViT神经网络鸟类识别分类系统源码

    有问题可以私信或者留言,有问必答

  • 相关阅读:
    Nexus 私服资源的上传下载
    2022/8/9
    【微信小程序】实现页面跳转功能
    Java——包装类
    关于 PropertyOverrideConfigurer PropertySourcesPlaceholderConfigurer
    一周技术学习笔记(第91期)-产品经理在做什么
    C++ 练气期之函数探幽
    pandas plot函数:数据可视化的快捷通道
    查看双翌视觉软件版本号
    What I Read(2) 地理空间数据库原理(B) 三维地理数据模型
  • 原文地址:https://blog.csdn.net/m0_59023219/article/details/139635036