【史诗巨作!!!历时三个月!!!】Yolov8毕设记录——从0到1

本文仅记录个人学习思考过程,不涉及具体论文内容或代码实现,仅供交流参考。
本文记录了本人从零基础学习并利用相关工具做深度学习毕设的过程,相信你也可以。

一、前置学习(必要理论基础等)

参考视频如下:

二、YOLO模型训练关键方法

1、 用YOLOv8训练自己数据集的步骤

若提前已经下载好了公开数据集,如果公开数据集内未划分好trainvaltest集首先用下面脚本划分。

划分数据集脚本

import cv2
import matplotlib.pyplot as plt
import numpy as np
import random
from tqdm import tqdm
import shutil
import os

def CollateDataset(image_dir, label_dir):
    valid_images = []
    valid_labels = []
    
    # 收集有效图片和标签
    for image_name in os.listdir(image_dir):
        image_path = os.path.join(image_dir, image_name)
        ext = os.path.splitext(image_name)[-1]
        label_name = image_name.replace(ext, ".txt")
        label_path = os.path.join(label_dir, label_name)
        
        if not os.path.exists(label_path):
            print(f"Label missing: {label_path}")
        else:
            valid_images.append(image_path)
            valid_labels.append(label_path)
    
    # 按比例分配数据集
    for i in tqdm(range(len(valid_images))):
        image_path = valid_images[i]
        label_path = valid_labels[i]
        r = random.random()
        
        # 修改后的比例判断逻辑 (8:1:1)
        if r < 0.1:
            destination = "C:/ultralytics-8.3.81/datasets/design_mian_data/test" #这里需要改,改成你需要保存test集的路径
        elif r < 0.2:
            destination = "C:/ultralytics-8.3.81/datasets/design_mian_data/val" #这里需要改,改成你需要保存val集的路径
        else:
            destination = "/ultralytics-8.3.81/datasets/design_mian_data/train" #这里需要改,改成你需要保存train集的路径
        
        # 创建目标目录
        os.makedirs(os.path.join(destination, "images"), exist_ok=True)
        os.makedirs(os.path.join(destination, "labels"), exist_ok=True)
        
        # 复制文件
        shutil.copy(image_path, os.path.join(destination, "images", os.path.basename(image_path)))
        shutil.copy(label_path, os.path.join(destination, "labels", os.path.basename(label_path)))

if __name__ == '__main__':
    CollateDataset(
        "C:/ultralytics-8.3.81/datasets/design_mian_data/images", #这里需要改,改成你的images的路径
        "C:/ultralytics-8.3.81/datasets/design_mian_data/labels"  #这里需要改,改成你的labels的路径
    )#改为下载好的公开数据集的images和labels路径

2、 如何对已经训练过的模型继续训练

下面是腾通元宝给出的代码。

# 加载模型和检查点
model = YOLO("runs/detect/train/weights/last.pt")

# 继续训练
model.train(
    data="data.yaml",
    epochs=300,
    resume=True,
    batch=16,
    imgsz=640,
    lr0=0.001,      # 可选:调整学习率
    flipud=0.5      # 可选:新增数据增强
)

3、 训练脚本

from ultralytics import YOLO
import torch
import cv2
import matplotlib.pyplot as plt
import os

os.environ['KMP_DUPLICATE_LIB_OK'] = 'True'


def train():
    # model = YOLO("./ultralytics/cfg/models/v8/mtyolov8.yaml")  #未预训练
    model = YOLO("./yolov8n.pt")  #官方模型,预训练过
    # model = YOLO('yolov8s-obb.yaml').load('yolov8s-obb.pt')
    # model = YOLO("runs/detect/train54/weights/last.pt") #继续训练
    model.train(data="./test2.yaml", epochs=500) #改为自己写的yaml文件路径
    result = model.val()

if __name__ == '__main__':
    train()

4、训练完后,如何进行预测?

下面是腾通元宝给出的代码。

from ultralytics import YOLO

# 加载模型
model = YOLO("runs/detect/train/weights/best.pt")  # 替换为你的权重路径

# 预测单张图像
results = model.predict("test.jpg", save=True)  # save=True 保存结果到 runs/detect/predict

# 预测文件夹内所有图像
results = model.predict("input_images/", save=True)

# 预测视频文件
results = model.predict("video.mp4", save=True, imgsz=1280)

# 使用摄像头(ID=0表示默认摄像头)
results = model.predict(source=0, show=True, stream=True)  # stream=True 启用实时模式

# 按ESC退出
while True:
    for result in results:
        cv2.waitKey(1)
    if cv2.waitKey(1) == 27:  # ESC键
        break

5、预测脚本

from ultralytics import YOLO
import torch
import cv2
import matplotlib.pyplot as plt
import os

os.environ['KMP_DUPLICATE_LIB_OK'] = 'True'


def predict():
    model = YOLO("runs/detect/train55/weights/best.pt")  #改为训练好的best.pt文件路径
    results = model.predict("WPS拼图0.jpg", save=True)   #改为预测单张图片的路径

if __name__ == '__main__':
    predict()

6、如何进行数据扩充?

利用有限的数据集,经过图像变换获得大量数据集,更改range内的值就能获得不同数据量的数据。

# -*- coding: utf-8 -*-
import cv2
import os
import numpy as np
from albumentations import (
    HorizontalFlip, VerticalFlip, Rotate, RandomBrightnessContrast, 
    Compose, OneOf
)

# 配置路径(使用独立输出目录)
input_images_dir = r"D:\backup\images"
input_labels_dir = r"D:\backup\labels"
output_images_dir = r"D:\backup\images_aug"  # 新增目录防止覆盖
output_labels_dir = r"D:\backup\labels_aug"

# 创建输出目录(强制UTF-8编码)
os.makedirs(output_images_dir, exist_ok=True)
os.makedirs(output_labels_dir, exist_ok=True)

# 定义增强管道(YOLO格式专用)
aug = Compose([
    OneOf([
        HorizontalFlip(p=0.5),
        VerticalFlip(p=0.5),
        Rotate(limit=15, border_mode=cv2.BORDER_CONSTANT, p=0.5)
    ], p=0.8),
    RandomBrightnessContrast(brightness_limit=0.2, contrast_limit=0.2, p=0.5)
], bbox_params={'format': 'yolo', 'label_fields': ['class_labels']})

# 遍历处理文件
for img_name in os.listdir(input_images_dir):
    # 处理中文文件名乱码
    try:
        img_name_decoded = img_name.encode('cp1252').decode('gbk')
    except UnicodeDecodeError:
        img_name_decoded = img_name.encode('utf-8').decode('gbk', 'ignore')
    
    # 过滤非图片文件
    if not img_name_decoded.lower().endswith(('.jpg', '.jpeg', '.png')):
        continue
    
    # 生成路径
    base_name = os.path.splitext(img_name_decoded)[0]
    img_path = os.path.join(input_images_dir, img_name)
    label_path = os.path.join(input_labels_dir, f"{base_name}.txt")  # 关键修正
    
    # 检查文件存在性
    if not os.path.exists(img_path):
        print(f"图片不存在: {img_path}")
        continue
    if not os.path.exists(label_path):
        print(f"标签不存在: {label_path}")
        continue
    
    # 读取图片
    img = cv2.imread(img_path)
    if img is None:
        print(f"图片读取失败: {img_path}")
        continue
    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    
    # 解析YOLO标签
    with open(label_path, 'r') as f:
        lines = f.readlines()
    
    bboxes = []
    class_labels = []
    for line in lines:
        parts = line.strip().split()
        if len(parts) != 5:
            print(f"无效标签格式: {label_path}")
            continue
        class_id, x_center, y_center, width, height = map(float, parts)
        bboxes.append([x_center, y_center, width, height])
        class_labels.append(class_id)
    
    # 应用增强(每个样本生成35个增强版本)
    for aug_idx in range(35):
        try:
            augmented = aug(image=img, bboxes=bboxes, class_labels=class_labels)
        except Exception as e:
            print(f"增强失败: {img_path} - {str(e)}")
            continue
        
        aug_img = augmented['image']
        aug_bboxes = augmented['bboxes']
        aug_labels = augmented['class_labels']
        
        # 生成新文件名
        new_base_name = f"{base_name}_aug{aug_idx}"
        new_img_name = f"{new_base_name}.jpg"
        new_label_name = f"{new_base_name}.txt"
        
        # 保存增强图片
        aug_img_bgr = cv2.cvtColor(aug_img, cv2.COLOR_RGB2BGR)
        cv2.imwrite(os.path.join(output_images_dir, new_img_name), aug_img_bgr)
        
        # 保存新标签(过滤越界坐标)
        with open(os.path.join(output_labels_dir, new_label_name), 'w') as f:
            for label, bbox in zip(aug_labels, aug_bboxes):
                # 坐标合法性检查
                if any(coord < 0 or coord > 1 for coord in bbox):
                    continue
                line = f"{int(label)} {bbox[0]:.6f} {bbox[1]:.6f} {bbox[2]:.6f} {bbox[3]:.6f}\n"
                f.write(line)

print(f"增强完成!结果保存在: {output_images_dir}")

将模型转换为onnx:yolo mode=export model=runs/detect/train72/weights/best.pt format=onnx simplify=True(注意改model后面的路径),参考:yolov8.1超简单环境搭建、标注、训练、转onnx、转输出维度

7、OCR入门

参考视频:Python 实现 OCR 识别提取图片文字,多语言支持,步骤简单小白也能学

二、YOLOv8改进

1.添加注意力机制模块

参考资料:YOLOv8模型改进 第九讲 添加EMAttention注意力机制

2.添加损失函数

参考资料:YOLOv8模型改进 第十一讲 添加自适应阈值焦点损失(ATFL)函数解决类别不平衡

3.替换优化器

参考资料:Yolov8目标检测模型改进 模型替换 优化器 一通百通

三、OCR模块改进

1. 智能倾斜旋转

2. 药品数据库辅助

3. 借助大模型纠正

四、SQLite

参考资料:世界上装机量最大的数据库SQLite,低调但不小众

五、论文图像绘制

参考资料:

六、问题记录

在这里插入图片描述

在这里插入图片描述

  • 训练模型是出现 WARNING NMS time limit 2.150s exceeded 解决方法
  • VSCode用jupyter绘图时出现例如<Figure size 600x600 with 1 Axes> 解决方法:在导入库的代码之后添加%matplotlib inline
  • 在VSCode中如果运行代码出现FileNotFoundError: [WinError 3] 系统找不到指定的路径。: './images'类似问题 解决方法:将./images路径改为绝对路径,具体方法:右键点击复制路径,注意将路径中的\改为/。 建议能使用绝对路径就尽量使用绝对路径(看需要,有的则只需要相对路径即可,具体问题具体分析)。
  • 报错OutOfMemoryError: CUDA out of memory. Tried to allocate 16.00 MiB (GPU 0; 4.00 GiB total capacity; 2.72 GiB already allocated; 0 bytes free; 2.81 GiB reserved in total by PyTorch) If reserved memory is >> allocated memory try setting max_split_size_mb to avoid fragmentation. See documentation for Memory Management and PYTORCH_CUDA_ALLOC_CONF 我是打开俩个VSCode进行跑了,有一个跑完没关,可能没释放内存,建议跑完一个训练模型后关掉再跑另一个,就正常训练了。
  • 下载公开数据集没有classes文件怎么知道分类,下面是腾通元宝给出的代码,可以知道分类。其实看labels文件夹里面的txt文件的命名方式即可。如 car_001.jpg, person_005.png (如果都是数字,则一般第一个数字是类别,结合具体图片了解后面数字代表含义)
  • 报错RuntimeError: DataLoader worker (pid(s) 43684, 32944, 31592) exited unexpectedly。解决方法:在命令行python下import torch torch.cuda.empty_cache() # 如果使用 GPU 可行 exit()重新运行训练代码即可(或者关闭一些无用的后台应用,减少内存占用)。
  • 数据集太大,需要自己手动标注,或者用自动标注后需要手动修改,记得一定要勾选自动保存,不然一切重头开始,真的很搞心态。
import os

def find_classes(label_dir):
    class_ids = set()
    
    # 遍历所有标签文件
    for label_file in os.listdir(label_dir):
        if not label_file.endswith(".txt"):
            continue  # 跳过非txt文件
            
        file_path = os.path.join(label_dir, label_file)
        with open(file_path, 'r') as f:
            for line in f:
                parts = line.strip().split()
                if len(parts) >= 5:  # YOLO格式至少5个值(class, cx, cy, w, h)
                    class_id = int(parts[0])
                    class_ids.add(class_id)
    
    return sorted(class_ids)

# 使用示例
label_dir = "dataset/labels/"  # 根据实际情况修改路径
detected_classes = find_classes(label_dir)
print(f"数据集中存在的类别ID: {detected_classes}")

# 生成classes.txt(需手动映射ID到名称)
with open("dataset/classes.txt", 'w') as f:   # 根据实际情况修改路径
    f.write("\n".join(map(str, detected_classes)))
  • yaml文件修改后记得按ctrls保存,再训练,不然会报错。
  • 使用cursor提问chat修改代码时,最好给出文件给它提问,这样可能会更快达到预期。
  • 有时候不知道为什么无缘无故运行python代码会出现莫名其妙的语法错误,而且在cursor中不报错,在VsCode中就报错,没搞懂为什么?但是删了这个文件重建一个文件,把内容拷贝过去就可以了,懂的大佬可以评论解释一下。
  • Tensorrt部署问题:
  • 微信开发者工具真机调试报错:“errno“: 600001, “errMsg“: “request:fail -2:net::ERR_FAILED“,但是电脑端直接预览没有错,我搜了资料说是“手机和电脑不在同一个局域网,或者在了同一个局域网内IP地址没写对”,参考:解决微信小程序真机测试出现errno:600001错误,但我检查了,都是一致的。结果我发现我手机开的vpn,把vpn关掉就行了。
  • 不能语音播报?手机开静音模式了,笑了。

七、模型评价(性能指标)

参考:【YOLOv8小白入门09】目标检测模型性能指标深度学习实验部分常见疑问解答三!(怎么判断模型是否收敛?模型过拟合怎么办?)Yolov8网络模型训练参数详解
论文中图像绘制:手把手教你YOLOv8画对比图,画改进后的对比图,支持多个实验结果,写作和科研必备(全网最详细)

八、前端:微信小程序速成

建议:前后端开发同时进行,先完成接口,先完成再完善
参考视频及资料:

重点笔记及摘要:

  • app.json文件不能写任何注释

九、后端:Flask速成

建议:前后端开发同时进行,先完成接口,先完成再完善

十、云服务器的使用:部署后端代码

  • 为什么要用云服务器?:用Flask部署有网络IP限制:手机与电脑连接同一个网络或热点才能正常运行,若要解除这个限制,就用到了云服务器。
  • 如何上传自己电脑上的文件/项目到云服务器上?

使用 WinSCP(图形界面,更直观) (具体使用方法参考文件传输工具WinSCP安装与使用教程

  1. 下载并安装 WinSCP(官网下载太慢了,参考点这
  2. 打开 WinSCP 填写连接信息:
    • 主机名:你的服务器IP
    • 用户名:root
    • 密码:你的服务器密码
  3. 点击"登录"
  4. 左侧窗口是你的本地文件,右侧是服务器文件。找到你的项目文件,拖拽到右侧的目录中即可。

十一、好用工具

十二、参考视频及资料

最后

  • AIGC率到底应该怎么降?
    网上很多人说利用ai来降ai,但本人越降越高,所以放弃了该方法。若ai率很高,那么查重率应该很低,这两者需要有一个权衡,也就是可以通过提高查重率来降低ai率,本人是一段一段用自己的话来转述ai的话,同时引用文献进去,穿插到ai的话中,也要调整ai的句式结构,加些口语化的词这样。若是字数足够的话,直接删除ai率较高的段落是一种简单的降ai方法。(还有一种方法,但博主没实践过,就是通过往论文中添加代码从而增加论文字数,而代码很难增加查重率和ai率,由此降低ai率,理论上可行,但博主没实践过)

毕设闲暇之余或标图片期间,无聊可以看易中天教授、王立群教授、毕淑敏作家等所讲的百家讲坛,尤其推荐 易中天 教授,讲得十分生动有趣,十分有意思。
学习资料:YouTube CCTV百家讲坛官方频道

  • 最近在追 《棋士》,很好看。但我感觉:世界上只有一种病——穷病。
  • 《漫长的季节》 也不错,之前没看,现在补上。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Once_普通学生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值