欢迎光临
我们一直在努力

VajraV1震撼来袭,手把手教你如何配置

没等到yolo26,等来了VajraV1

【总结】VajraV1:一种实时目标检测新框架,在现有 YOLO 的检测器基础上进行了架构增强,融合了先前 YOLO 模型中的有效设计,在保持具有竞争力的推理速度的同时,实现了实时目标检测器中最先进的精度!代码已开源

【简介】近年来,实时目标检测技术取得了显著进展,YOLOv10、YOLOv11、YOLOv12 和 YOLOv13 于 2024 年至 2025 年间相继发布。本技术报告介绍了 VajraV1 模型架构,该架构在现有基于 YOLO 的检测器基础上进行了架构增强。VajraV1 融合了先前 YOLO 模型中的有效设计,在保持具有竞争力的推理速度的同时,实现了实时目标检测器中最先进的精度。
在 COCO 验证集上,VajraV1-Nano 的 mAP 达到了 44.3%,比 YOLOv12-N 高出 3.7%,比 YOLOv13-N 高出 2.7%,延迟与 YOLOv12-N 和 YOLOv11-N 相当。 VajraV1-Small 的 mAP 达到 50.4%,比 YOLOv12-S 和 YOLOv13-S 高出 2.4%。VajraV1-Medium 的 mAP 达到 52.7%,比 YOLOv12-M 高出 0.2%。VajraV1-Large 的 mAP 达到 53.7%,比 YOLOv13-L 高出 0.3%。VajraV1-Xlarge 的 mAP 达到 56.2%,优于所有现有的实时目标检测器。

《VajraV1 — The most accurate Real Time Object Detector of the YOLO family》
 

第一步:下载源码

地址:

https://github.com/NamanMakkar/VayuAI

在pycharm中打开这个源码,python版本最好选择3.8以上,我用的3.10

第二步:配置环境

#打开终端用Python3.10创建新虚拟环境,其中的C:\\Python310换成自己的安装的python路径
C:\\Python310\\python.exe -m venv .venv

#安装PyTorch(国内镜像+超长的超时时间防止安装包过大安装失败)
pip3 install –default-timeout=1000 torch==2.2.0 torchvision==0.17.0 torchaudio==2.2.0 -i https://pypi.tuna.tsinghua.edu.cn/simple –index-url https://download.pytorch.org/whl/cu121

#安装其余的环境
pip install –default-timeout=1000 numpy>=1.21 pandas>=1.3 matplotlib>=3.5 pillow>=9.0 scipy>=1.7 tqdm>=4.64 pyyaml>=6.0 ultralytics>=8.0 onnx>=1.13 onnxruntime>=1.14 opencv-python>=4.5 -i https://pypi.tuna.tsinghua.edu.cn/simple

可以用下面的代码检查自己的环境是否安装完全

import sys
import platform
import pkg_resources
from pkg_resources import DistributionNotFound, VersionConflict

# 1. 项目要求的基础配置
REQUIRED_PYTHON = (3, 8) # VayuAI要求Python≥3.8
REQUIRED_DEPENDENCIES = { # 从VayuAI的pyproject.toml提取的核心依赖
"torch": ">=2.0",
"torchvision": ">=0.15",
# "flash-attn": ">=2.7.4",
"numpy": ">=1.21",
"pandas": ">=1.3",
"matplotlib": ">=3.5",
"pillow": ">=9.0",
"scipy": ">=1.7",
"tqdm": ">=4.64",
"pyyaml": ">=6.0",
"ultralytics": ">=8.0",
"onnx": ">=1.13",
"onnxruntime": ">=1.14",
"opencv-python": ">=4.5"
}

# 2. 检查Python版本
def check_python_version():
print(f"当前Python版本: {sys.version.split()[0]}")
if sys.version_info < REQUIRED_PYTHON:
print(f"错误: 需要Python {REQUIRED_PYTHON[0]}.{REQUIRED_PYTHON[1]} 或更高版本")
return False
print("Python版本符合要求")
return True

# 3. 检查系统平台兼容性
def check_platform():
current_platform = platform.system()
print(f"\\n当前系统平台: {current_platform}")
# 重点提示:flash-attn在Windows上无官方预编译包
if current_platform == "Windows":
print("注意: flash-attn在Windows系统上没有官方预编译wheel,可能需要从源码编译或寻找替代方案")
return True

# 4. 检查依赖包(版本+是否缺失)
def check_dependencies():
missing = []
version_mismatch = []

for pkg_name, req_version in REQUIRED_DEPENDENCIES.items():
try:
# 获取已安装版本并验证
installed_version = pkg_resources.get_distribution(pkg_name).version
pkg_resources.require(f"{pkg_name}{req_version}")
print(f"{pkg_name}: {installed_version} (符合要求 {req_version})")
except DistributionNotFound:
missing.append(f"{pkg_name} (需要 {req_version})")
except VersionConflict as e:
installed = e.dist.version
version_mismatch.append(f"{pkg_name}: 已安装{installed},需要{req_version}")

# 输出问题依赖
if missing:
print("\\n缺少以下依赖:")
for pkg in missing:
print(f"- {pkg}")
if version_mismatch:
print("\\n版本不匹配的依赖:")
for pkg in version_mismatch:
print(f"- {pkg}")

return len(missing) == 0 and len(version_mismatch) == 0

# 5. 执行检测
def main():
print("=== VayuAI环境配置检测 ===")
python_ok = check_python_version()
platform_ok = check_platform()
deps_ok = check_dependencies()

print("\\n=== 检测总结 ===")
if python_ok and platform_ok and deps_ok:
print("环境配置完全符合要求")
else:
print("环境存在问题,请根据上述提示修复")

if __name__ == "__main__":
main()

步骤三:添加训练代码和配置文件mydata.yaml

新建mydata.yaml,内容如下(路径自己看着来)

nc: 3 # 若仅1类,与names长度一致
path: D:KuaKeDW/VayuAI-main/datasets # 数据集所在路径 也可使用绝对路径
train: D:KuaKeDW/VayuAI-main/datasets/train.txt # 数据集路径下的train.txt
val: D:KuaKeDW/VayuAI-main/datasets/val.txt # 数据集路径下的val.txt
test: D:KuaKeDW/VayuAI-main/datasets/test.txt # 数据集路径下的test.txt

# Classes
names:
0: 1
1: 2
2: 3

新建train.py内容如下(参数依照自己所需来修改)

from vajra import Vajra
import torch

# 核心:Windows 多进程必须包裹在 if __name__ == '__main__' 中
if __name__ == '__main__':
# 1. 检查GPU是否可用
if torch.cuda.is_available():
print(f"检测到GPU:{torch.cuda.get_device_name(0)}")
train_device = "cuda"
else:
print("未检测到GPU,将使用CPU训练")
train_device = "cpu"

# 2. 加载预训练模型
model = Vajra("vajra-v1-small-det.pt")

# 3. 训练(关键:workers先设为0,避免多进程报错)
result = model.train(
data="D:/KuaKeDW/VayuAI-main/mydata.yaml",
epochs=100,
img_size=640,
batch=4,
device=train_device,
amp=True,
workers=0, # 核心修正:Windows下先设为0,调试通过后可改为2/4
# 可选:添加其他稳定训练的参数
rect=False, # 关闭矩形训练,减少内存占用
mosaic=0.0 # 暂时关闭mosaic增强,避免数据加载报错(可选)
)

注:其中的训练模型 vajra-v1-small-det.pt 需自己在项目的release里面提前下载,不然运行时找不到程序自己下载时会非常慢,还有可能会运行失败

步骤四:准备数据集并开始训练

首先把自己的数据放在同目录下的data文件夹中,区分为(images和label两个文件夹)

然后新建一个划分数据集的.py文件

代码如下

import shutil
import random
import os

def check_paths(image_path, label_path):
"""检查源路径是否存在以及是否包含文件"""
if not os.path.exists(image_path):
raise FileNotFoundError(f"图片源路径不存在: {image_path}")
if not os.path.exists(label_path):
raise FileNotFoundError(f"标签源路径不存在: {label_path}")

# 扩展支持的图片文件类型,包括 .bmp 格式(大小写敏感)
image_extensions = ('.jpg', '.jpeg', '.png', '.bmp', '.JPG', '.JPEG', '.PNG', '.BMP')
image_files = [f for f in os.listdir(image_path) if f.endswith(image_extensions)]
label_files = [f for f in os.listdir(label_path) if f.endswith('.txt')]

if not image_files:
raise ValueError(f"图片源路径 {image_path} 不包含任何图片文件")
if not label_files:
raise ValueError(f"标签源路径 {label_path} 不包含任何标签文件")

print(f"找到 {len(image_files)} 张图片和 {len(label_files)} 个标签文件")
return image_files, label_files

def del_file(path):
"""删除目录下的所有文件"""
if os.path.exists(path):
for i in os.listdir(path):
file_data = os.path.join(path, i)
if os.path.isfile(file_data):
os.remove(file_data)

def mkdir():
"""创建输出目录,如果目录已存在则清空"""
dirs = [
train_image_path, train_label_path,
val_image_path, val_label_path,
test_image_path, test_label_path
]

for path in dirs:
if not os.path.exists(path):
os.makedirs(path)
else:
del_file(path)

def clearfile():
"""清除之前的列表文件"""
files = [list_train, list_val, list_test]
for file_path in files:
if os.path.exists(file_path):
os.remove(file_path)

def main():
# 原始路径
global image_original_path, label_original_path
# 如果需要,这里可以修改为绝对路径
image_original_path = "data/images/"
label_original_path = "data/labels/"

# 确保路径以斜杠结尾
if not image_original_path.endswith(('/', '\\\\')):
image_original_path += '/'
if not label_original_path.endswith(('/', '\\\\')):
label_original_path += '/'

# 转换为绝对路径,便于调试
image_original_path = os.path.abspath(image_original_path)
label_original_path = os.path.abspath(label_original_path)

cur_path = os.getcwd()
print(f"当前工作目录: {cur_path}")

# 训练集路径
global train_image_path, train_label_path
train_image_path = os.path.join(cur_path, "datasets/images/train/")
train_label_path = os.path.join(cur_path, "datasets/labels/train/")

# 验证集路径
global val_image_path, val_label_path
val_image_path = os.path.join(cur_path, "datasets/images/val/")
val_label_path = os.path.join(cur_path, "datasets/labels/val/")

# 测试集路径
global test_image_path, test_label_path
test_image_path = os.path.join(cur_path, "datasets/images/test/")
test_label_path = os.path.join(cur_path, "datasets/labels/test/")

# 训练集目录
global list_train, list_val, list_test
list_train = os.path.join(cur_path, "datasets/train.txt")
list_val = os.path.join(cur_path, "datasets/val.txt")
list_test = os.path.join(cur_path, "datasets/test.txt")

global train_percent, val_percent, test_percent
train_percent = 0.8
val_percent = 0.1
test_percent = 0.1

try:
# 检查源路径和文件
image_files, label_files = check_paths(image_original_path, label_original_path)

# 确保图片和标签文件数量匹配
image_names = {f.split('.')[0] for f in image_files}
label_names = {f.split('.')[0] for f in label_files}
common_names = image_names & label_names

if len(common_names) < len(image_names):
print(f"警告: 找到 {len(image_names) – len(common_names)} 张图片没有对应的标签")

if len(common_names) < len(label_names):
print(f"警告: 找到 {len(label_names) – len(common_names)} 个标签没有对应的图片")

total_txt = sorted(list(common_names))
print(f"将处理 {len(total_txt)} 对匹配的图片和标签")

mkdir()
clearfile()

file_train = open(list_train, 'w')
file_val = open(list_val, 'w')
file_test = open(list_test, 'w')

num_txt = len(total_txt)
list_all_txt = range(num_txt)

num_train = int(num_txt * train_percent)
num_val = int(num_txt * val_percent)
num_test = num_txt – num_train – num_val

train = random.sample(list_all_txt, num_train)
val_test = [i for i in list_all_txt if not i in train]
val = random.sample(val_test, num_val)

print("训练集数目:{}, 验证集数目:{}, 测试集数目:{}".format(len(train), len(val), len(val_test) – len(val)))

# 用于记录复制失败的文件
failed_files = []

for i in list_all_txt:
name = total_txt[i]

# 查找该名称对应的图片文件扩展名
image_ext = None
for ext in ('.jpg', '.jpeg', '.png', '.bmp', '.JPG', '.JPEG', '.PNG', '.BMP'):
if os.path.exists(os.path.join(image_original_path, name + ext)):
image_ext = ext
break

if image_ext is None:
print(f"警告: 找不到对应的图片文件: {name}")
failed_files.append(f"{name} (找不到匹配的扩展名)")
continue

srcImage = os.path.join(image_original_path, name + image_ext)
srcLabel = os.path.join(label_original_path, name + ".txt")

# 检查文件是否存在
if not os.path.exists(srcImage):
failed_files.append(srcImage)
continue

if not os.path.exists(srcLabel):
failed_files.append(srcLabel)
continue

if i in train:
dst_train_Image = os.path.join(train_image_path, name + image_ext)
dst_train_Label = os.path.join(train_label_path, name + '.txt')
try:
shutil.copyfile(srcImage, dst_train_Image)
shutil.copyfile(srcLabel, dst_train_Label)
file_train.write(dst_train_Image + '\\n')
except Exception as e:
print(f"复制失败 {srcImage}: {e}")
failed_files.append(srcImage)
elif i in val:
dst_val_Image = os.path.join(val_image_path, name + image_ext)
dst_val_Label = os.path.join(val_label_path, name + '.txt')
try:
shutil.copyfile(srcImage, dst_val_Image)
shutil.copyfile(srcLabel, dst_val_Label)
file_val.write(dst_val_Image + '\\n')
except Exception as e:
print(f"复制失败 {srcImage}: {e}")
failed_files.append(srcImage)
else:
dst_test_Image = os.path.join(test_image_path, name + image_ext)
dst_test_Label = os.path.join(test_label_path, name + '.txt')
try:
shutil.copyfile(srcImage, dst_test_Image)
shutil.copyfile(srcLabel, dst_test_Label)
file_test.write(dst_test_Image + '\\n')
except Exception as e:
print(f"复制失败 {srcImage}: {e}")
failed_files.append(srcImage)

file_train.close()
file_val.close()
file_test.close()

if failed_files:
print(f"共有 {len(failed_files)} 个文件复制失败")
for file in failed_files[:10]: # 只显示前10个
print(f" – {file}")
if len(failed_files) > 10:
print(f" … 等 {len(failed_files) – 10} 个文件")
else:
print("所有文件复制成功!")

except Exception as e:
print(f"程序执行出错: {e}")

if __name__ == "__main__":
main()

然后运行即可划分完成

划分完成之后运行train.py即可开始训练

步骤五:.pt ——> .onnx(可选)

首先按装转换的环境

# 先安装基础ONNX(若未安装)
pip install onnx==1.15.0 –upgrade

# 安装onnxslim(简化ONNX模型)
pip install onnxslim

# 安装onnxruntime-gpu
pip install onnxruntime-gpu==1.16.3 –upgrade

# 若onnxruntime-gpu安装失败,可先装CPU版临时用:
# pip install onnxruntime==1.16.3

然后 新建.py文件,代码如下

from vajra import Vajra
import torch

if __name__ == '__main__':
# 1. 加载训练好的.pt模型(best.pt/last.pt)
model_path = r"D:\\KuaKeDW\\VayuAI-main\\runs\\detect\\train5\\weights\\best-vajra-v1-small-det.pt" # 替换为你的.pt文件路径
model = Vajra(model_path) # 加载模型

# 2. 导出ONNX(指定输入尺寸、保存路径)
onnx_save_path = r"D:\\KuaKeDW\\VayuAI-main\\best.onnx" # 自定义ONNX保存路径
model.export(
format="onnx", # 导出格式为ONNX
img_size=2048, # 输入尺寸(必须和训练时的img_size一致!)
save_dir=onnx_save_path, # ONNX文件保存路径
dynamic=True # 可选:开启动态维度(支持不同尺寸输入)
)

print(f"ONNX文件已导出到:{onnx_save_path}")

最后运行即可进行.pt -> .onnx

赞(0)
未经允许不得转载:171主机测评 » VajraV1震撼来袭,手把手教你如何配置
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址