3步解锁CLIP超能力:用文字精准搜索图片的实战指南
2025/12/18 17:41:33
plaintext
环境准备 → 数据准备(文件夹搭建+图片划分) → labelImg标注(生成YOLO格式TXT) → 编写配置文件 → 模型训练 → 推理(单图/批量图/视频)核心目标:基于自定义数据集(如 hero/bing/dongwu 三类)训练 YOLO11 模型,实现目标检测。
bash
运行
# 1. 创建虚拟环境(Python3.10+/3.12均可) conda create -n YOLO11_test python=3.12 # 2. 激活环境 conda activate YOLO11_test # 3. 安装ultralytics(YOLO11核心库) pip install ultralytics # 4. 验证安装 python -c "from ultralytics import YOLO; print('安装成功')"在工作目录(如F:\shijue\YOLO11_test)下创建mydataset文件夹,结构如下:
plaintext
mydataset/ ├── images/ # 存放所有图片 │ ├── train/ # 训练集图片(建议占80%,≥50张,越多越好) │ └── val/ # 验证集图片(建议占20%,≥10张) └── labels/ # 存放标注后的TXT标签(与images一一对应) ├── train/ # 训练集TXT标签(和images/train图片同名) └── val/ # 验证集TXT标签(和images/val图片同名)img_001.jpg而非截图 1.jpg);labelImg.exe);PascalVOC按钮 → 点击切换为YOLO格式;Open Dir→ 选择mydataset/images/train(先标注 train 集);Change Save Dir→ 选择mydataset/labels/train(标签保存路径);View → Auto Save Mode(自动保存标签,无需手动点保存)。W键调出标注框,鼠标框选目标;hero/bing/dongwu,与后续配置文件一致),点击OK;D键切换下一张图片,重复标注;Open Dir为images/val,Change Save Dir为labels/val)。labels/train/labels/val下是否为.txt文件(而非.xml);类别ID 归一化x_center y_center width height(如0 0.45 0.52 0.18 0.32,ID 从 0 开始,数值 0-1);box_loss/cls_loss/dfl_loss逐步下降(如 2.4→1.5→1.0);no labels found仅影响验证指标,不影响模型训练,可忽略;runs/detect/trainX/weights下生成best.pt(最优)和last.pt(最后一轮)。yolo11s.pt/yolo11m.pt);augment=True+hsv_h=0.015等)。imgsz(如 480);vid_stride=2(隔帧推理);在F:\shijue\YOLO11_test目录下新建dataset.yaml,内容如下(需适配自己的类别):
yaml
# 数据集根路径(用/或\\,避免\) path: F:/shijue/YOLO11_test/mydataset # 训练/验证集图片路径(相对path) train: images/train val: images/val # 若无val集,可临时改为images/train # 类别配置(核心!) nc: 3 # 类别数量(如hero/bing/dongwu为3) names: ['hero', 'bing', 'dongwu'] # 类别名称(与标注一致,ID对应0/1/2)python
运行
from ultralytics import YOLO import os # 切换工作目录 os.chdir(r"F:\shijue\YOLO11_test") # 加载YOLO11模型(n=轻量版,s=标准版,m/l/x=更重,精度更高) model = YOLO("yolo11n.pt") # 启动训练(CPU/GPU适配) results = model.train( data=r"F:\shijue\YOLO11_test\dataset.yaml", # 配置文件绝对路径 epochs=50, # 训练轮数(建议≥30,数据少可设20) batch=2, # CPU设2/1,GPU可设8/16 imgsz=640, # 输入图片尺寸 device="cpu", # CPU填"cpu",GPU填0(如多张GPU填0,1) patience=10, # 早停:10轮无提升则停止 augment=True, # 开启数据增强(提升精度) val=False, # 新手可先关闭验证(避免标签匹配警告) workers=0, # CPU设0,避免多线程报错 save=True # 保存最优模型(best.pt) ) # 打印最优模型路径 best_model_path = os.path.join(os.getcwd(), "runs/detect/train/weights/best.pt") print(f"训练完成!最优模型路径:{best_model_path}")bash
运行
conda activate YOLO11_test cd F:\shijue\YOLO11_test python train_yolo11.pypython
运行
from ultralytics import YOLO import os os.chdir(r"F:\shijue\YOLO11_test") # 加载训练好的模型(替换为实际路径) model = YOLO(r"F:\shijue\YOLO11_test\runs\detect\train6\weights\best.pt") # 推理单张图片 test_img = r"F:\shijue\YOLO11_test\mydataset\images\val\img_001.jpg" results = model(test_img, conf=0.2) # conf=置信度阈值(0.2-0.5) # 保存标注结果 results[0].save("single_result.jpg") # 打印检测结果 for box in results[0].boxes: cls_id = int(box.cls[0]) cls_name = ["hero", "bing", "dongwu"][cls_id] # 匹配类别名 print(f"类别:{cls_name},置信度:{box.conf[0]:.2f}")python
运行
from ultralytics import YOLO import os # 配置参数 MODEL_PATH = r"F:\shijue\YOLO11_test\runs\detect\train6\weights\best.pt" IMG_DIR = r"F:\shijue\YOLO11_test\mydataset\images\val" # 待推理图片目录 SAVE_DIR = r"F:\shijue\YOLO11_test\batch_results" CONF = 0.2 CLASS_NAMES = ["hero", "bing", "dongwu"] # 初始化 os.makedirs(SAVE_DIR, exist_ok=True) model = YOLO(MODEL_PATH) # 遍历所有图片 for img_file in os.listdir(IMG_DIR): if img_file.lower().endswith((".jpg", ".png")): img_path = os.path.join(IMG_DIR, img_file) results = model(img_path, conf=CONF) # 保存结果 save_path = os.path.join(SAVE_DIR, img_file) results[0].save(save_path) print(f"处理完成:{img_file}")python
运行
from ultralytics import YOLO import os # 配置参数 MODEL_PATH = r"F:\shijue\YOLO11_test\runs\detect\train6\weights\best.pt" VIDEO_PATH = r"F:\shijue\YOLO11_test\mydataset\images\SVID_20210726_111258_1.mp4" SAVE_DIR = r"F:\shijue\YOLO11_test\video_results" CONF = 0.2 # 初始化 os.makedirs(SAVE_DIR, exist_ok=True) model = YOLO(MODEL_PATH) # 视频推理(CPU建议stream=True,逐帧处理) results = model( source=VIDEO_PATH, conf=CONF, device="cpu", stream=True, # 避免内存溢出 save=True, # 保存标注视频 project=SAVE_DIR, name="detect", exist_ok=True, show=False # CPU关闭实时预览(卡顿) ) # 打印进度 frame_count = 0 for r in results: frame_count += 1 if frame_count % 10 == 0: print(f"已处理{frame_count}帧") print(f"视频推理完成!结果保存在:{SAVE_DIR}/detect")| 问题现象 | 原因 | 解决方案 |
|---|---|---|
no labels found警告 | 验证集标签与图片不匹配 / 无 val 标签 | 1. 训练时加val=False;2. 复制 train 标签到 val 目录;3. 检查 TXT 文件名与图片一致 |
| 显存 / 内存溢出 | batch 过大 / 未开 stream 推理 | 1. CPU 设batch=1/2;2. 视频推理加stream=True;3. 降低imgsz=480 |
| 推理无目标 | 置信度阈值过高 / 模型未学到特征 | 1. 降低conf=0.1;2. 增加训练轮数(epochs=50);3. 补充训练数据 |
| labelImg 生成 XML 而非 TXT | 未切换 YOLO 格式 | 左侧PascalVOC按钮切换为YOLO格式 |
device=0报错 | 无 GPU/CPU 版本 PyTorch | 改device="cpu" |
python
运行
import xml.etree.ElementTree as ET import os import cv2 # 配置 CLASS_NAMES = ["hero", "bing", "dongwu"] XML_DIR = r"F:\shijue\YOLO11_test\mydataset\labels\train" IMG_DIR = r"F:\shijue\YOLO11_test\mydataset\images\train" def xml2yolo(xml_path): tree = ET.parse(xml_path) root = tree.getroot() img_name = root.find("filename").text img = cv2.imread(os.path.join(IMG_DIR, img_name)) h, w = img.shape[:2] lines = [] for obj in root.findall("object"): cls = obj.find("name").text if cls not in CLASS_NAMES: continue cls_id = CLASS_NAMES.index(cls) bbox = obj.find("bndbox") x1, y1, x2, y2 = float(bbox.find("xmin").text), float(bbox.find("ymin").text), float(bbox.find("xmax").text), float(bbox.find("ymax").text) # 归一化 x_center = (x1 + x2) / 2 / w y_center = (y1 + y2) / 2 / h width = (x2 - x1) / w height = (y2 - y1) / h lines.append(f"{cls_id} {x_center:.6f} {y_center:.6f} {width:.6f} {height:.6f}") # 保存TXT txt_path = xml_path.replace(".xml", ".txt") with open(txt_path, "w", encoding="utf-8") as f: f.write("\n".join(lines)) # 批量转换 for file in os.listdir(XML_DIR): if file.endswith(".xml"): xml2yolo(os.path.join(XML_DIR, file)) print("转换完成!")