手把手教你 Aancond 的下载与 YOLOV13 部署(环境的创建及配置下载)以及使用方法,连草履虫都能学会的目标检测实验!
😶🌫️😶🌫️😶🌫️😶🌫️Take your time ! 😶🌫️😶🌫️😶🌫️😶🌫️
💥个人主页:🔥🔥🔥大魔王🔥🔥🔥
💥所属专栏:🔥魔王的修炼之路–Computer vision🔥
如果你觉得这篇文章对你有帮助,请在文章结尾处留下你的点赞👍和关注💖,支持一下博主。同时记得收藏✨这篇文章,方便以后重新阅读。
文章目录
- 说明
- Anaconda 下载
- 下载
- 安装
- 配置环境变量
- 验证
- 使用
- YOLOV13环境创建及下载配置文件
- 下载源码
- 创建虚拟环境
- 下载 pytorch 配置文件
- 查看自己的 cuda 支持的最高版本
- 下载 pytorch
- 安装 pytorch
- 安装其他依赖
- flash_attn
- YOLOv13 使用
- 下载官网提供的与训练模型权重文件
- 推理
- 准备数据集
- 划分
- 训练
- 验证
- 代码总结
- voc 转 yolo 数据格式
- 划分
- 训练
- 验证
- 配置文件
- 推理
说明
博主自己是零基础部署,所以写的文章很适合零基础,在最后会附上运行需要的代码,如果觉得哪里没看懂,可以去下面博客看一下,他可能会说的更清楚。
博主就是参照博主
挂科边缘的这篇文章,进行部署的,本篇附上的代码也基本来自这个博主。只需要在代码上修改一下模型权重文件和一些文件的路径即可使用。
Anaconda 下载
下载
- 首先下载 Anaconda,推荐在 清华大学开源镜像网站 下载,点击跳转即可,下载速度比较快。
进入如图路径及下载即可。
安装
路径建议不要装 C盘,解压缩后有十几G。
其余不动即可,如图,其余一样,都默认。
配置环境变量
win + r 进入 windows 的命令提示符终端,输入 conda 你会发现其不是一个命令,需要配置环境变量,如下:
首先进入 Path 的编辑页面
然后点击新建,找到 Anaconda 目录下的这三个文件路径添加上去即可。
验证
win + r 输入 cmd 打开命令提示符终端,输入 conda 将成功显示内容。
使用
选择一个可以选择解释器的编程软件,我用 pycharm 了,新建项目,选择刚才的下载的 Anaconda 的路径,其目录下有一个 python.exe 的文件即可。
如图:右下角,就是你刚才创建的虚拟环境里的解释器。
YOLOV13环境创建及下载配置文件
下载源码
首先可以去官网下载源码 源码
创建虚拟环境
然后用 Anaconda 创建一个虚拟环境,win + r 输入 cmd 打开终端,创建过程中遇到询问输入 y 即可:
激活虚拟环境
下载 pytorch 配置文件
查看自己的 cuda 支持的最高版本
查看自己的显卡
按 win 键,搜索设备管理器,然后如下:
终端输入:nvidia-smi 查看自己支持的最高 CUDA,接下来要下载的 pytorch 配置文件需要根据这个来,只要是自己支持的版本以下就可以用
下载 pytorch
因为在终端很多电脑都安装不了,所以采取离线下载然后进行安装的方法
官网里我们看出需要安装 torch = 2.2.2版本,然后结合自己创建虚拟环境的 python 版本以及支持的cuda,去下载离线包:
离线包地址
我下的这三个文件,简单说就是 torch 是 yolov13 要求的 pytorch 版本,2.2.2,虚拟环境创建的 python 版本是 3.11,支持的 cuda 只要是 12.5一下就行
安装 pytorch
点开 Anaconda 的终端,首先记得激活虚拟环境(输入 activate yolov13),然后进入这三个文件的位置,下载即可。记得确保自己当前路径要在这三个文件的文件夹,不然这样直接输入文件名会找不到。
要记得安装顺序: torch、torchvision、torchaudio,然后如图形式安装
安装其他依赖
直接在软件终端安装即可:
官方给的依赖可能很多用不到,可以改为下面代码,代码来自博主
挂科边缘的文章
# Ultralytics requirements
# Example: pip install -r requirements.txt# Base ----------------------------------------
matplotlib>=3.3.0
numpy==1.24.4 # pinned by Snyk to avoid a vulnerability
opencv-python>=4.6.0
pillow>=7.1.2
pyyaml>=5.3.1
requests>=2.23.0
scipy>=1.4.1
tqdm>=4.64.0# Logging -------------------------------------
# tensorboard>=2.13.0
# dvclive>=2.12.0
# clearml
# comet# Plotting ------------------------------------
pandas>=1.1.4
seaborn>=0.11.0# Export --------------------------------------
# coremltools>=7.0 # CoreML export
# onnx>=1.12.0 # ONNX export
# onnxsim>=0.4.1 # ONNX simplifier
# nvidia-pyindex # TensorRT export
# nvidia-tensorrt # TensorRT export
# scikit-learn==0.19.2 # CoreML quantization
# tensorflow>=2.4.1 # TF exports (-cpu, -aarch64, -macos)
# tflite-support
# tensorflowjs>=3.9.0 # TF.js export
# openvino-dev>=2023.0 # OpenVINO export# Extras --------------------------------------
psutil # system utilization
py-cpuinfo # display CPU info
thop>=0.1.1 # FLOPs computation
# ipython # interactive notebook
# albumentations>=1.0.3 # training augmentations
# pycocotools>=2.0.6 # COCO mAP
# roboflow
记得在上一张图片指向的位置那里安装刚才说的依赖,之后还需要再安装一个依赖,如下
pip install huggingface-hub==0.23.2
flash_attn
yolov13 支持 flash_attn 的使用,这个一般用在比较大的模型上,可以提速,我们平常联系的小模型不用也差不多,且官网提供的是 Linux 版,windows版本自己可以搜教程下载,我没有下载。不说了。
YOLOv13 使用
下载官网提供的与训练模型权重文件
先下载一下模型权重文件
官网下载地址
推理
其实到这已经可以推理测试了,用官方的训练模型权重和提供的两张图片推理一下,如果前面没问题就可以运行,博主说到的代码都会在最后附上,可以看完去复制,如图:
如果按我们自己训练模型权重,推理应该是在最后的,顺序: 准备数据集 -> 划分 -> 训练 ->(验证 ->测试 ) -> 推理,不过可以先用官网提供的训练好的模型权重和提供的两张图片先推理一下。yolov13 自动验证,只要配置文件有 val 的路径即可,下面会说。
from ultralytics import YOLOif __name__ == '__main__':# Load a modelmodel = YOLO(model=r'D:\Zachary\7_YOLOv13\yolov13-main\yolov13n.pt') # .pt文件是 训练后/预训练的模型权重model.predict(source=r'D:\Zachary\7_YOLOv13\yolov13-main\ultralytics\assets',save=True,show=True,imgsz=640)
准备数据集
我们使用 labelimg 进行标注,不过我在这个软件上耽误了估计有一天的时间,一直报错,搞了要有十几个小时,找到了个靠谱的方法使用,直接去接下来我提供的地方把软件下载下来就行,不用在终端下载然后使用终端打开,如果想这样,直接去最开始推荐的那篇博客就行,接下来我说在我电脑上没出问题的方法:
这里跳转
下载完直接打开文件即可
标注完看一下自己输出的文件夹里是否多了一些文件,没问题就可以进行划分了
划分
注意:格式,划分时保存图片目录的命名需要是 images,保存的标签需要和 images 在一个目录下,且命名为 labels,因为在我们训练时,我们只指定训练的图片的路径与验证的图片的路径,不需要指定我们刚才用 labelimg 标注后生成标签的路径,编译器会自动将 images 改为 labels 去找对应图片的标注文件,所以如果我们不用这个规则命名,编译器就找不到!一般的目录有两个格式,直接拿那位博主的原图了,不想画了:从图中你可以看出,不管是哪个方式,images 与 labels 都在一个目录下。
如果采用第一种图片,那么目录如下
# -*- coding: utf-8 -*-import os, shutil
from sklearn.model_selection import train_test_splitval_size = 0.2
postfix = 'jpg'
imgpath = r'D:\Zachary\7_YOLOv13\yolov13-main\yolo_test\label_data_1\images'
txtpath = r'D:\Zachary\7_YOLOv13\yolov13-main\yolo_test\label_data_1\txt'output_train_img_folder = r'D:\Zachary\7_YOLOv13\yolov13-main\yolo_test\dataset_1/images/train'
output_val_img_folder = r'D:\Zachary\7_YOLOv13\yolov13-main\yolo_test\dataset_1/images/val'
output_train_txt_folder = r'D:\Zachary\7_YOLOv13\yolov13-main\yolo_test\dataset_1\labels/train'
output_val_txt_folder = r'D:\Zachary\7_YOLOv13\yolov13-main\yolo_test\dataset_1\labels/val'os.makedirs(output_train_img_folder, exist_ok=True)
os.makedirs(output_val_img_folder, exist_ok=True)
os.makedirs(output_train_txt_folder, exist_ok=True)
os.makedirs(output_val_txt_folder, exist_ok=True)listdir = [i for i in os.listdir(txtpath) if 'txt' in i]
train, val = train_test_split(listdir, test_size=val_size, shuffle=True, random_state=0)for i in train:img_source_path = os.path.join(imgpath, '{}.{}'.format(i[:-4], postfix))txt_source_path = os.path.join(txtpath, i)img_destination_path = os.path.join(output_train_img_folder, '{}.{}'.format(i[:-4], postfix))txt_destination_path = os.path.join(output_train_txt_folder, i)shutil.copy(img_source_path, img_destination_path)shutil.copy(txt_source_path, txt_destination_path)for i in val:img_source_path = os.path.join(imgpath, '{}.{}'.format(i[:-4], postfix))txt_source_path = os.path.join(txtpath, i)img_destination_path = os.path.join(output_val_img_folder, '{}.{}'.format(i[:-4], postfix))txt_destination_path = os.path.join(output_val_txt_folder, i)shutil.copy(img_source_path, img_destination_path)shutil.copy(txt_source_path, txt_destination_path)
训练
划分好了数据就可以进行训练了,首先需要调一下配置文件
train: D:\Zachary\7_YOLOv13\yolov13-main\yolo_test\dataset_1\images\train
val: D:\Zachary\7_YOLOv13\yolov13-main\yolo_test\dataset_1\images\valnc: 2names: ['cat', 'dog']
接下来是训练的代码解析:
意外训练中断,想要继续上次,首先查看是否存在 last.pt,存在就行,将 resume 设置为 True,然后一般是默认接着 last.pt 即上次训练的权重继续训练,也可以手动指定,然后记得其他的内容比如配置文件什么的都不要变,最好指定一下训练结果(日志和目录)保存的位置,否则中断的那部分和这次的部分就不在一块了。
yolo train resume=True project=runs/train name=exp
总结就是当 resume 为 True 时,会加载上一次训练的模型权重和优化器状态,继续训练。这在训练被中断或在已有模型的基础上进行进一步训练时非常有用。
# -*- coding: utf-8 -*-import warnings
warnings.filterwarnings('ignore')
from ultralytics import YOLOif __name__ == '__main__':model = YOLO(model=r'D:\Zachary\7_YOLOv13\yolov13-main\ultralytics\cfg\models\v13\yolov13n.yaml') # 模型配置文件 下面那个叫().pt:模型权重文件model.load(r'D:\Zachary\7_YOLOv13\yolov13-main\yolov13n.pt') # 加载预训练权重,改进或者做对比实验时候不建议打开,因为用预训练模型整体精度没有很明显的提升model.train(data=r'D:\Zachary\7_YOLOv13\yolov13-main\data.yaml',imgsz=640,epochs=50,batch=4,workers=0,device='',optimizer='SGD',close_mosaic=10,resume=False,project='runs/train',name='exp',single_cls=False,cache=False,)
验证
当我们训练完如果不改变训练的参数,那么就没必要验证,因为 yolov13会自动验证,如果你想改一下参数,那可以单独验证一下,至于测试,不会自动进行,测试的话也要包含那个配置文件,需要在里边加上测试的图片的路径,我的代码里没弄。这里也不说了,只说说一下验证的代码。
首先需要确定配置文件里有 val 路径。
接下来如图:
from ultralytics import YOLOmodel = YOLO(r"D:\Zachary\7_YOLOv13\yolov13-main\runs\train\exp2\weights\best.pt")metrics = model.val(data=r'D:\Zachary\7_YOLOv13\yolov13-main\data.yaml', batch=8, half=True, workers=0)
print(metrics)
代码总结
voc 转 yolo 数据格式
# -*- coding: utf-8 -*-import xml.etree.ElementTree as ET
import os, cv2
import numpy as npclasses = []def convert(size, box):dw = 1. / (size[0])dh = 1. / (size[1])x = (box[0] + box[1]) / 2.0 - 1y = (box[2] + box[3]) / 2.0 - 1w = box[1] - box[0]h = box[3] - box[2]x = x * dww = w * dwy = y * dhh = h * dhreturn (x, y, w, h)def convert_annotation(xmlpath, xmlname):with open(xmlpath, "r", encoding='utf-8') as in_file:txtname = xmlname[:-4] + '.txt'txtfile = os.path.join(txtpath, txtname)tree = ET.parse(in_file)root = tree.getroot()filename = root.find('filename')img = cv2.imdecode(np.fromfile('{}/{}.{}'.format(imgpath, xmlname[:-4], postfix), np.uint8), cv2.IMREAD_COLOR)h, w = img.shape[:2]res = []for obj in root.iter('object'):cls = obj.find('name').textif cls not in classes:classes.append(cls)cls_id = classes.index(cls)xmlbox = obj.find('bndbox')b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text),float(xmlbox.find('ymax').text))bb = convert((w, h), b)res.append(str(cls_id) + " " + " ".join([str(a) for a in bb]))if len(res) != 0:with open(txtfile, 'w+') as f:f.write('\n'.join(res))if __name__ == "__main__":postfix = 'jpg' # 图像后缀imgpath = r'D:\Zachary\7_YOLOv13\yolov13-main\yolo_test\label_data_1\images' # 图像文件路径xmlpath = r'D:\Zachary\7_YOLOv13\yolov13-main\yolo_test\label_data_1\xml' # xml文件文件路径txtpath = r'D:\Zachary\7_YOLOv13\yolov13-main\yolo_test\label_data_1\txt' # 生成的txt文件路径if not os.path.exists(txtpath):os.makedirs(txtpath, exist_ok=True)list = os.listdir(xmlpath)error_file_list = []for i in range(0, len(list)):try:path = os.path.join(xmlpath, list[i])if ('.xml' in path) or ('.XML' in path):convert_annotation(path, list[i])print(f'file {list[i]} convert success.')else:print(f'file {list[i]} is not xml format.')except Exception as e:print(f'file {list[i]} convert error.')print(f'error message:\n{e}')error_file_list.append(list[i])print(f'this file convert failure\n{error_file_list}')print(f'Dataset Classes:{classes}')
划分
# -*- coding: utf-8 -*-import os, shutil
from sklearn.model_selection import train_test_splitval_size = 0.2
postfix = 'jpg'
imgpath = r'D:\Zachary\7_YOLOv13\yolov13-main\yolo_test\label_data_1\images'
txtpath = r'D:\Zachary\7_YOLOv13\yolov13-main\yolo_test\label_data_1\txt'output_train_img_folder = r'D:\Zachary\7_YOLOv13\yolov13-main\yolo_test\dataset_1/images/train'
output_val_img_folder = r'D:\Zachary\7_YOLOv13\yolov13-main\yolo_test\dataset_1/images/val'
output_train_txt_folder = r'D:\Zachary\7_YOLOv13\yolov13-main\yolo_test\dataset_1\labels/train'
output_val_txt_folder = r'D:\Zachary\7_YOLOv13\yolov13-main\yolo_test\dataset_1\labels/val'os.makedirs(output_train_img_folder, exist_ok=True)
os.makedirs(output_val_img_folder, exist_ok=True)
os.makedirs(output_train_txt_folder, exist_ok=True)
os.makedirs(output_val_txt_folder, exist_ok=True)listdir = [i for i in os.listdir(txtpath) if 'txt' in i]
train, val = train_test_split(listdir, test_size=val_size, shuffle=True, random_state=0)for i in train:img_source_path = os.path.join(imgpath, '{}.{}'.format(i[:-4], postfix))txt_source_path = os.path.join(txtpath, i)img_destination_path = os.path.join(output_train_img_folder, '{}.{}'.format(i[:-4], postfix))txt_destination_path = os.path.join(output_train_txt_folder, i)shutil.copy(img_source_path, img_destination_path)shutil.copy(txt_source_path, txt_destination_path)for i in val:img_source_path = os.path.join(imgpath, '{}.{}'.format(i[:-4], postfix))txt_source_path = os.path.join(txtpath, i)img_destination_path = os.path.join(output_val_img_folder, '{}.{}'.format(i[:-4], postfix))txt_destination_path = os.path.join(output_val_txt_folder, i)shutil.copy(img_source_path, img_destination_path)shutil.copy(txt_source_path, txt_destination_path)
训练
# -*- coding: utf-8 -*-import warnings
warnings.filterwarnings('ignore')
from ultralytics import YOLOif __name__ == '__main__':model = YOLO(model=r'D:\Zachary\7_YOLOv13\yolov13-main\ultralytics\cfg\models\v13\yolov13n.yaml') # 模型配置文件 下面那个叫().pt:模型权重文件model.load(r'D:\Zachary\7_YOLOv13\yolov13-main\yolov13n.pt') # 加载预训练权重,改进或者做对比实验时候不建议打开,因为用预训练模型整体精度没有很明显的提升model.train(data=r'D:\Zachary\7_YOLOv13\yolov13-main\data.yaml',imgsz=640,epochs=50,batch=4,workers=0,device='',optimizer='SGD',close_mosaic=10,resume=False,project='runs/train',name='exp',single_cls=False,cache=False,)
验证
from ultralytics import YOLOmodel = YOLO(r"D:\Zachary\7_YOLOv13\yolov13-main\runs\train\exp2\weights\best.pt")metrics = model.val(data=r'D:\Zachary\7_YOLOv13\yolov13-main\data.yaml', batch=8, half=True, workers=0)
print(metrics)
配置文件
train: D:\Zachary\7_YOLOv13\yolov13-main\yolo_test\dataset_1\images\train
val: D:\Zachary\7_YOLOv13\yolov13-main\yolo_test\dataset_1\images\valnc: 2names: ['cat', 'dog']
推理
# -*- coding: utf-8 -*-from ultralytics import YOLOif __name__ == '__main__':# Load a modelmodel = YOLO(model=r'D:\Zachary\7_YOLOv13\yolov13-main\yolov13n.pt') # .pt文件是 训练后/预训练的模型权重model.predict(source=r'D:\Zachary\7_YOLOv13\yolov13-main\ultralytics\assets',save=True,show=True,imgsz=640)
- 博主长期更新,博主的目标是不断提升阅读体验和内容质量,如果你喜欢博主的文章,请点个赞或者关注博主支持一波,我会更加努力的为你呈现精彩的内容。
🌈专栏推荐
😈魔王的修炼之路–C语言
😈魔王的修炼之路–数据结构
😈魔王的修炼之路–C++
😈魔王的修炼之路–QT
😈魔王的修炼之路–算法
😈魔王的修炼之路–力扣
😈魔王的修炼之路–牛客
😈魔王的修炼之路–剑指offer
😈魔王的修炼之路–Linux
😈魔王的修炼之路–Computer vision
更新不易,希望得到友友的三连支持一波。收藏这篇文章,意味着你将永久拥有它,无论何时何地,都可以立即找到重新阅读;关注博主,意味着无论何时何地,博主将永久和你一起学习进步,为你带来有价值的内容。