基于Pytorch框架的深度学习Vision Transformer神经网络蝴蝶分类识别系统源码

news2025/1/19 23:10:02

 第一步:准备数据

6种蝴蝶数据:self.class_indict = ["曙凤蝶", "麝凤蝶", "多姿麝凤蝶", "旖凤蝶", "红珠凤蝶", "热斑凤蝶"],总共有900张图片,每个文件夹单独放一种数据

第二步:搭建模型

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

Vision Transformer(ViT)是一种基于Transformer架构的深度学习模型,用于图像识别和计算机视觉任务。与传统的卷积神经网络(CNN)不同,ViT直接将图像视为一个序列化的输入,并利用自注意力机制来处理图像中的像素关系。

ViT通过将图像分成一系列的图块(patches),并将每个图块转换为向量表示作为输入序列。然后,这些向量将通过多层的Transformer编码器进行处理,其中包含了自注意力机制和前馈神经网络层。这样可以捕捉到图像中不同位置的上下文依赖关系。最后,通过对Transformer编码器输出进行分类或回归,可以完成特定的视觉任务。

Vit model结构图
Vit的模型结构如下图所示。vit是将图像块应用于transformer。CNN是以滑窗的思想用卷积核在图像上进行卷积得到特征图。为了可以使图像仿照NLP的输入序列,我们可以先将图像分成块(patch),再将这些图像块进行平铺后输入到网络中(这样就变成了图像序列),然后通过transformer进行特征提取,最后再通过MLP对这些特征进行分类【其实就可以理解为在以往的CNN分类任务中,将backbone替换为transformer】。

第三步:训练代码

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

2)训练代码:

import os
import math
import argparse

import torch
import torch.optim as optim
import torch.optim.lr_scheduler as lr_scheduler
from torch.utils.tensorboard import SummaryWriter
from torchvision import transforms


from my_dataset import MyDataSet
from vit_model import vit_base_patch16_224_in21k as create_model
from utils import read_split_data, train_one_epoch, evaluate


def main(args):
    device = torch.device(args.device if torch.cuda.is_available() else "cpu")

    if os.path.exists("./weights") is False:
        os.makedirs("./weights")

    tb_writer = SummaryWriter()

    train_images_path, train_images_label, val_images_path, val_images_label = read_split_data(args.data_path)

    data_transform = {
        "train": transforms.Compose([transforms.RandomResizedCrop(224),
                                     transforms.RandomHorizontalFlip(),
                                     transforms.ToTensor(),
                                     transforms.Normalize([0.5, 0.5, 0.5], [0.5, 0.5, 0.5])]),
        "val": transforms.Compose([transforms.Resize(256),
                                   transforms.CenterCrop(224),
                                   transforms.ToTensor(),
                                   transforms.Normalize([0.5, 0.5, 0.5], [0.5, 0.5, 0.5])])}

    # 实例化训练数据集
    train_dataset = MyDataSet(images_path=train_images_path,
                              images_class=train_images_label,
                              transform=data_transform["train"])

    # 实例化验证数据集
    val_dataset = MyDataSet(images_path=val_images_path,
                            images_class=val_images_label,
                            transform=data_transform["val"])

    batch_size = args.batch_size
    nw = min([os.cpu_count(), batch_size if batch_size > 1 else 0, 8])  # number of workers
    print('Using {} dataloader workers every process'.format(nw))
    train_loader = torch.utils.data.DataLoader(train_dataset,
                                               batch_size=batch_size,
                                               shuffle=True,
                                               pin_memory=True,
                                               num_workers=nw,
                                               collate_fn=train_dataset.collate_fn)

    val_loader = torch.utils.data.DataLoader(val_dataset,
                                             batch_size=batch_size,
                                             shuffle=False,
                                             pin_memory=True,
                                             num_workers=nw,
                                             collate_fn=val_dataset.collate_fn)

    model = create_model(num_classes=args.num_classes, has_logits=False).to(device)

    if args.weights != "":
        assert os.path.exists(args.weights), "weights file: '{}' not exist.".format(args.weights)
        weights_dict = torch.load(args.weights, map_location=device)
        # 删除不需要的权重
        del_keys = ['head.weight', 'head.bias'] if model.has_logits \
            else ['pre_logits.fc.weight', 'pre_logits.fc.bias', 'head.weight', 'head.bias']
        for k in del_keys:
            del weights_dict[k]
        print(model.load_state_dict(weights_dict, strict=False))

    if args.freeze_layers:
        for name, para in model.named_parameters():
            # 除head, pre_logits外,其他权重全部冻结
            if "head" not in name and "pre_logits" not in name:
                para.requires_grad_(False)
            else:
                print("training {}".format(name))

    pg = [p for p in model.parameters() if p.requires_grad]
    optimizer = optim.SGD(pg, lr=args.lr, momentum=0.9, weight_decay=5E-5)
    # Scheduler https://arxiv.org/pdf/1812.01187.pdf
    lf = lambda x: ((1 + math.cos(x * math.pi / args.epochs)) / 2) * (1 - args.lrf) + args.lrf  # cosine
    scheduler = lr_scheduler.LambdaLR(optimizer, lr_lambda=lf)

    for epoch in range(args.epochs):
        # train
        train_loss, train_acc = train_one_epoch(model=model,
                                                optimizer=optimizer,
                                                data_loader=train_loader,
                                                device=device,
                                                epoch=epoch)

        scheduler.step()

        # validate
        val_loss, val_acc = evaluate(model=model,
                                     data_loader=val_loader,
                                     device=device,
                                     epoch=epoch)

        tags = ["train_loss", "train_acc", "val_loss", "val_acc", "learning_rate"]
        tb_writer.add_scalar(tags[0], train_loss, epoch)
        tb_writer.add_scalar(tags[1], train_acc, epoch)
        tb_writer.add_scalar(tags[2], val_loss, epoch)
        tb_writer.add_scalar(tags[3], val_acc, epoch)
        tb_writer.add_scalar(tags[4], optimizer.param_groups[0]["lr"], epoch)

        torch.save(model.state_dict(), "./weights/model-{}.pth".format(epoch))


if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('--num_classes', type=int, default=6)
    parser.add_argument('--epochs', type=int, default=100)
    parser.add_argument('--batch-size', type=int, default=4)
    parser.add_argument('--lr', type=float, default=0.001)
    parser.add_argument('--lrf', type=float, default=0.01)

    # 数据集所在根目录
    # https://storage.googleapis.com/download.tensorflow.org/example_images/flower_photos.tgz
    parser.add_argument('--data-path', type=str,
                        default=r"G:\demo\data\Butterfly20")
    parser.add_argument('--model-name', default='', help='create model name')

    # 预训练权重路径,如果不想载入就设置为空字符
    parser.add_argument('--weights', type=str, default='./vit_base_patch16_224_in21k.pth',
                        help='initial weights path')
    # 是否冻结权重
    parser.add_argument('--freeze-layers', type=bool, default=True)
    parser.add_argument('--device', default='cuda:0', help='device id (i.e. 0 or 0,1 or cpu)')

    opt = parser.parse_args()

    main(opt)

第四步:统计正确率

第五步:搭建GUI界面

第六步:整个工程的内容

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

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1847783.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

重磅!2024年最新影响因子正式发布,附Excel下载

大家好,这里是专注表观组学十余年,领跑多组学科研服务的易基因。 激动人心的时刻终于来了,2024年影响因子已全面发布!废话不多说,大家一起来看看最新的发布的结果吧! 神刊:CA-A CANCER JOURNA…

go-admin-ui开源后台管理系统华为云部署

1.华为云开通8000与9527端口 2.编译 编译成功 3.发布到远程服务器 4.登陆华为云终端 5.安装Nginx 6.查看服务启动状态 7.添加网站 添加与修改配置www-data 改为 www 自定义日志输出格式 添加网站配置文件go_admin_ui.conf 添加如下内容: location 下的root指向网站文件夹 修…

java实现图片水印添加并自动上传七牛云

图片左下角水印添加 满足需求:可以对不同类型尺寸的照片、图片进行水印的添加,实现尺寸自适应添加水印。 水印效果 代码实现 Controller package com.wlh.zetc.restore.controller;import cn.hutool.core.date.DateUtil; import com.alibaba.nacos.c…

QT(超详细从0开始)

目录 1.2 Qt的优点 2.安装Qt 3.创建项目 4.解读Qt自动生成的代码 ​编辑 5.Qt Designer 6.Qt对象数 7.Qt乱码问题 8.Qt坐标系的认识 9.信号和槽 9.1 connect 9.2 自定义槽函数 9.3 自定义信号 9.4 断开信号链接(disconnect) 9.5.lambda表…

supOS浅度集成

一、浅度集成介绍 浅度集成是根据项目或者演示要求而做的集成工作,通过接入supOS的单点登录,UI调整,菜单栏的集成,从而达到客户使用supOS平台来使用各个应用的能力。 二、浅度集成的作用 通过较少的研发投入使APP应用浅度融入到…

2024年7月JLPT日语N1真题试卷和答案解析,《Navi日语社》小程序在线答题考试,你的专属考试助手,日语学习神器!

掌握日语,从日语社小程序开始。这款小程序专为日语学习者设计,提供全面的JLPT备考资源,包括日语N1至N5等级考试的历年真题和2024年最新题目。无论你是日语新手还是备考高手,都能在这里找到适合自己的学习路径。 核心功能&#xf…

数据资产在供应链管理中担当核心角色:利用数据驱动,显著提升运营效率,有效降低潜在风险,实现决策优化,为企业的可持续发展奠定坚实基础

一、引言 在当今全球化和数字化的时代,供应链管理已成为企业竞争力的关键要素之一。随着信息技术的高速发展,数据资产在供应链管理中扮演着越来越重要的角色。通过有效地利用数据资产,企业能够显著提升运营效率,降低潜在风险&…

Javase.String类的课后作业

String类的课后作业 1.题目12.题目23.题目34.选择题15.选择题26.选择题37.编程题18.编程题2 1.题目1 指出下列程序运行的结果为: public class Example {String str new String("good");char[] ch {a, b, c};public static void main(String args[]) …

cd 命令特殊路径符 mkdir命令

cd 特殊路径符 cd . 表示当前目录,比如 cd ./Desktop表示切换到当前目录下的Desktop目录内,和 cd Desktop效果一致。cd … 表示上一级目录,比如 cd … 即可切换到上一级目录,cd…/…切换到上二级目录。cd ~ 表示 HOME 目录&#…

MPLS-LDP(个人学习笔记)

定义 标签分发协议LDP(Label Distribution Protocol)是多协议标签交换MPLS的一种控制协议,负责转发等价类FEC的分类、标签的分配以及标签交换路径LSP的建立和维护等操作。LDP规定了标签分发过程中的各种消息以及相关处理过程 术语 LDP会话&a…

数据采集与预处理复习资料

目录 第一章 简答 1.简述Hadoop各个组件及其功能 2.Hadoop在大数据技术体系中的地位和作用(来自文心一言) 3.Hadoop 启动命令,停止命令 4.pig 加载HDFS 数据 5.数据采集的方法(来自ppt) 6.数据分析过程&#xf…

chrome的插件怎么获取到安装包

问: chrome的插件怎么获取到安装包 回答: 在chrome浏览器输入: chrome://version/ 复制: 个人资料路径, 打开这个路径, 在文件中打开Extensions这个文件夹, 这个文件夹就是存放插件安装包的文件夹.

@ModelAttribute

基础知识 1.ModelAttribute注解源码,从中可以知道,该注解可以标注在参数上和方法上 2.应用场景:先大致有个概念,可以用来存储项目根路径 3.介绍:ModelAttribute 是 Spring 框架中的一个注解,用于在 Spring …

Springboot 权限认证框架 -- SA-Token 简介(一)

引言 现今的软件开发中,权限认证与访问控制是每一个应用都必不可少的功能。SA-Token是一个简单、安全、易用的权限认证框架,它主要解决登录认证、权限认证、Session会话、单点登录等功能。SA-Token以其轻量级、零学习成本的特点,迅速赢得了开…

Redis 7.x 系列【4】命令手册

有道无术,术尚可求,有术无道,止于术。 本系列Redis 版本 7.2.5 源码地址:https://gitee.com/pearl-organization/study-redis-demo 文章目录 1. 说明2. 命令手册2.1 Generic2.2 数据类型2.2.1 String2.2.2 Hash2.2.3 List2.2.4 S…

生成式AI和LLM的一些基本概念和名词解释

1. Machine Learning 机器学习是人工智能(AI)的一个分支,旨在通过算法和统计模型,使计算机系统能够从数据中学习并自动改进。机器学习算法使用数据来构建模型,该模型可用于预测或决策。机器学习应用于各种领域&#x…

二本(三本)毕业、4年职场牛马----分享给计科专业男女孩或被迷茫、焦虑困扰的大学生们的一些感悟

背景 我不是一个贩卖焦虑的博主,博主二本(三本升上来)毕业,当年正逢2020疫情,一战考研失败,家里蹲到没有实习。靠关系进第一家公司做Python后端,然后第一家公司因为疫情黄了。二战考研又失败&a…

容器之滚动条窗体演示

代码; #include <gtk-2.0/gtk/gtk.h> #include <glib-2.0/glib.h> #include <gtk-2.0/gdk/gdkkeysyms.h> #include <stdio.h>int main(int argc, char *argv[]) {gtk_init(&argc, &argv);GtkWidget *window;window gtk_window_new(GTK_WINDO…

面试官:JavaScript执行机制中的闭包?

前言 JavaScript 中的闭包指的是一个函数以及其捆绑的周边环境状态的引用的组合。闭包可以让开发者从内部函数访问外部函数的作用域&#xff0c;即使外部函数已经执行完毕 今天我们通过JavaScript执行机制来聊聊闭包 正文 首先来分析这段代码的执行机制&#xff0c;这段代码…

<Rust><iced><resvg>基于rust使用iced构建GUI实例:使用resvg库实现svg转png

前言 本文是使用rust库resvg来将svg图片转为png图片。 环境配置 系统&#xff1a;windows 平台&#xff1a;visual studio code 语言&#xff1a;rust 库&#xff1a;resvg 代码分析 resvg是一个基于rust的svg渲染库&#xff0c;其官方地址&#xff1a; An SVG rendering li…