Yolo训练的实现基础
在YoloSharp代码中可以看到,项目包含了多个不同版本Yolo的TorchSharp实现(对TorchSharp不了解的可以看之前将TorchSharp的文章)。可自行调整或保持与Yolov11一致的结构。YoloSharp中的Yolo11模型代码如下:
public class Yolov11 : Yolov8
{
protected override int[] outputIndexs => new int[] { 4, 6, 10, 13, 16, 19, 22 };
public Yolov11(int nc = 80, YoloSize yoloSize = YoloSize.n, Device? device = null, torch.ScalarType? dtype = null, int[] kpt_shape = null) : base(nc, yoloSize, device, dtype, kpt_shape: kpt_shape)
{
}
internal override ModuleList<Module> BuildModel(int nc, YoloSize yoloSize, Device? device, torch.ScalarType? dtype)
{
(float depth_multiple, float width_multiple, int max_channels, bool useC3k) = yoloSize switch
{
YoloSize.n => (0.5f, 0.25f, 1024, false),
YoloSize.s => (0.5f, 0.5f, 1024, false),
YoloSize.m => (0.5f, 1.0f, 512, true),
YoloSize.l => (1.0f, 1.0f, 512, true),
YoloSize.x => (1.0f, 1.5f, 768, true),
_ => throw new ArgumentOutOfRangeException(nameof(yoloSize), yoloSize, null)
};
base.widths = new List<int> { 64, 128, 256, 512, 1024 }.Select(w => Math.Min((int)(w * width_multiple), max_channels)).ToArray();
int depthSize = (int)(2 * depth_multiple);
ch = new int[] { widths[2], widths[3], widths[4] };
ModuleList<Module> mod = new ModuleList<Module>(
new Conv(3, widths[0], 3, 2, device: device, dtype: dtype),
new Conv(widths[0], widths[1], 3, 2, device: device, dtype: dtype),
new C3k2(widths[1], widths[2], depthSize, useC3k, e: 0.25f, device: device, dtype: dtype),
new Conv(widths[2], widths[2], 3, 2, device: device, dtype: dtype),
new C3k2(widths[2], widths[3], depthSize, useC3k, e: 0.25f, device: device, dtype: dtype),
new Conv(widths[3], widths[3], 3, 2, device: device, dtype: dtype),
new C3k2(widths[3], widths[3], depthSize, c3k: true, device: device, dtype: dtype),
new Conv(widths[3], widths[4], 3, 2, device: device, dtype: dtype),
new C3k2(widths[4], widths[4], depthSize, c3k: true, device: device, dtype: dtype),
new SPPF(widths[4], widths[4], 5, device: device, dtype: dtype),
new C2PSA(widths[4], widths[4], depthSize, device: device, dtype: dtype),
Upsample(scale_factor: new double[] { 2, 2 }, mode: UpsampleMode.Nearest),
new Concat(),
new C3k2(widths[4] + widths[3], widths[3], depthSize, useC3k, device: device, dtype: dtype),
Upsample(scale_factor: new double[] { 2, 2 }, mode: UpsampleMode.Nearest),
new Concat(),
new C3k2(widths[3] + widths[3], widths[2], depthSize, useC3k, device: device, dtype: dtype),
new Conv(widths[2], widths[2], 3, 2, device: device, dtype: dtype),
new Concat(),
new C3k2(widths[3] + widths[2], widths[3], depthSize, useC3k, device: device, dtype: dtype),
new Conv(widths[3], widths[3], 3, 2, device: device, dtype: dtype),
new Concat(),
new C3k2(widths[4] + widths[3], widths[4], depthSize, c3k: true, device: device, dtype: dtype),
new Yolov8Detect(nc, ch, false, device: device, dtype: dtype)
);
return mod;
}
}
二、数据集准备
训练开始前需要先准备训练集。以目标检测为例,每一张图片和该图片对应的分类标签构成了一个case,比如 001.jpg 和 001.txt。
图片:如果图片尺寸不同,模型读取后会自行适配大小。当某些群体或场景在数据集中代表性不足或过度代表时,会导致泛化能力差。因此尽量需要从多个来源收集数据,以捕获不同的视角和场景,如果实在样本不够还可以对代表性不足的类别进行过采样、或考虑数据增强和公平感知算法。
标注:常见的标注有边界框(对象检测任务)、多边形(实例分割)、掩码(语义分割)、关键点(姿势估计和面部特征点检测)等。
以对象检测任务为例, 假设001.jpg是训练集中的一个图像,001.txt是与图片对应的标注数据:
// 001.txt 0 0.486622 0.287910 0.273133 0.243852 1 0.386423 0.549155 0.532456 0.732381
每行有5列数据,各自对应的含义如下:
0 | 0.486622 | 0.287910 | 0.273133 | 0.243852 |
制作数据集是入门的第一道坎。为了提高效率,有多种开源工具可以帮助简化数据标注流程。本项目中用的是Yolo_Label,提供了较好的快捷键与简单的操作逻辑,仅需选择分类,框选即可完成标记,显著提升了标注速度。

三、模型训练
3.1 训练前参数配置
开源的YoloSharp开放了很多参数可以直接用。如果没有开放的,比如想修改optimizer(默认为SGD),也可以直接去源码中对TorchSharp代码进行修改。
下面是YoloSharp给出的Demo中用到的参数,以及相关说明。
本项目中对trainDataPath和valDataPath的路径配置进行了修改,为了方便使标记与图片放在了同一个文件夹下,这样就和Yolo_Label输出路径一致了。
// 训练集根目录 string rootPath = @"D:\Desktop\yoloTransf\medical-pills"; // 训练数据的目录,存放图片和标注 xxxx.jpg xxxx.txt string trainDataPath = @"\train"; // 用于评估训练过程数据的目录,存放图片 xxxx.jpg xxxx.txt // 也可以用训练集来评估 string valDataPath = @"\val"; // 模型输出位置,自动保存 best.bin 和 last.bin string outputPath = @"D:\Desktop\yoloTransf\medical-pills\result"yijumy.cn; // 批训练组大小 int batchSize = 5; // 总类别的数量,设置不对会报错 int numberClass = 1; // 训练迭代次数 int epochs = 120; // 训练时所有图像被统一缩放到的边长 int imageSize = 480; // 预测时 float predictThreshold = 0.3f; float iouThreshold = 0.5f; // YoloSharp自带的枚举值 YoloType yoloType = YoloType.Yolov11; // Yolo代 DeviceType deviceType = DeviceType.CUDA;www.yijumy.cn // Cpu or GPU ScalarType dtype = ScalarType.Float32; // 候选 Float16 YoloSize yoloSize = YoloSize.n; // 预设几档大小 n, s , m, l, x ImageProcessType imageProcessType = ImageProcessType.Mosiac; // 候选 LetterBox TaskType taskType = TaskType.Detection; // YoloSharp目前支持的几种任务类型:Detection, Segmentation, Obb, Pose Classification = 4,
3.2 模型训练
模型训练主要代码就4行。需要先实例化一个YoloTask实例;然后选择性的可加载之前预训练的模型; 如果不加载也可以从头开始直接Train; 手动另存SaveModel(原项YoloSharp自动保存没有SaveModel方法,这个是自己改的)。
// 实例化 YoloTask yoloTask = new YoloTask(taskType, numberClass, yoloType: yoloType, deviceType: deviceType, yoloSize: yoloSize, dtype: dtype); // 可选 // yoloTask.LoadModel(@"d:\medical-pills.yolo11", skipNcNotEqualLayers: true); // 训练 yoloTask.Train(rootPath, trainDataPath, valDataPath, lr: 1E-4f, outputPath: outputPath, imageSize: imageSize, batchSize: batchSize, epochs: epochs, wap.yijumy.cn imageProcessType: imageProcessType); // 另存 yoloTask.SaveModel(@"d:\medical-pills.yolo11");
在单纯运行预测的时候,把train和saveModel全部注释掉,仅实例化YoloTask就可以了。
3.3 模型预测
定义一个路径,然后读取,传入加载好的模型执行预测,生成YoloResult。YoloResult的各个元素就代表着一个对象检测任务中识别到的结果。
string predictImagePath = @"D:\Desktop\yoloTransf\medical-pills\val\Frame_456.jpg"; Mat predictImage = Cv2.ImRead(predictImagePath); float predictThreshold = 0.3f; // 检测置信度的阈值,越低越容易检出 float iouThreshold = 0.5f; // 区域重叠度的阈值,越低越容易检出 List<YoloResult> predictResult =m.yijumy.cn yoloTask.ImagePredict(predictImage, predictThreshold, iouThreshold);
其他包括在图片上绘制检测框以及类别标注就比较简单,demo里都有不再赘述。
四、模型效果
以下案例都是在笔记本上训练10来分钟就停止了,并不代表YoloSharp的最终效果。仅作为可用性的初探以及使用的示例。
4.1 公开数据集测试
检查模型及代码效果首先可以尝试官方的数据集,如ultralytics提供了很多经典数据集免费下载还有详细说明
Oracle运行过程中会生成警告日志、审计日志、跟踪文件等,需提前创建专用目录并授权,以SID为zhoul为例:
export ORACLE_SID=zhoul mkdir -p $ORACLE_BASE/admin/$ORACLE_SID/bdump mkdir -p $ORACLE_BASE/admin/$ORACLE_SID/adump mkdir -p $ORACLE_BASE/admin/$ORACLE_SID/cdump mkdir -p $ORACLE_BASE/admin/$ORACLE_SID/udump chown -R oracle:dba $ORACLE_BASE/admin/$ORACLE_SID
各目录核心作用:
- bdump:存放警告日志和DBWR、LGWR等后台进程跟踪文件;
- adump:存放审计信息,默认对sysdba连接审计,空间不足会导致ORA-09817错误;
- udump:存放用户进程跟踪文件,需定期清理避免空间溢出;
- cdump:存放核心转储文件(core文件),记录进程异常终止时的内存状态。
2. 密码文件创建
密码文件用于数据库特权用户(如SYS、SYSTEM)的认证,创建命令如下:
orapwd file=$ORACLE_HOME/dbs/orapw$ORACLE_SID password=oracle entries=5 force=y
*.user_dump_dest=uefa.yijumy.cn '/oracle/app/admin/zhoul/udump'
*.audit_file_dest='/oracle/app/admin/zhoul/adump'
*.background_dump_dest='/live.yijumy.cn.oracle/app/admin/zhoul/bdump'
*.core_dump_dest='/oracle/app/admin/zhoul/cdump'
*.compatible='10.2.0.5.0'
*.control_files=og.yijumy.cn '/oradata/zhoul/control01.ctl'
*.db_name='zhoul'
*.processes=500
*.job_queue_processes=10
*.sga_target=16384M
*.db_block_size=8192
*.db_files=500
*.open_cursors=500
*.session_cached_cursors=100
*.undo_management='AUTO'
*.undo_tablespace=ouguan.yijumy.cn 'undotbs'
七、数据库创建脚本执行:实例初始化
参数文件配置完成后,即可启动实例至NOMOUNT状态,执行建库脚本初始化数据库。根据是否使用OMF(Oracle Managed Files)特性,分为两种创建方式:
1. 常规建库脚本(手动指定文件路径)
CREATE DATABASE zhoul
USER SYS IDENTIFIED BY oracle
USER SYSTEM IDENTIFIED BY oracle
LOGFILE
GROUP 1('/oradata/zhoul/redo01.log') SIZE 100M,
GROUP 2('/oradata/zhoul/redo02.log') SIZE 100M,
GROUP 3('/oradata/zhoul/redo03.log') SIZE 100M
MAXLOGFILES 5
MAXLOGMEMBERS 5
MAXLOGHISTORY 1
MAXDATAFILES 100
MAXINSTANCES 1
CHARACTER SET ZHS16GBK
NATIONAL CHARACTER SET AL16UTF16
DATAFILE '/oradata/zhoul/system01.dbf' SIZE 325M REUSE
EXTENT MANAGEMENT LOCAL
SYSAUX DATAFILE '/oradata/zhoul/sysaux01.dbf' SIZE 325M REUSE
DEFAULT TEMPORARY TABLESPACE temp
TEMPFILE '/oradata/zhoul/temp01.dbf' SIZE 20M REUSE
DEFAULT TABLESPACE users
DATAFILE '/oradata/zhoul/users01.dbf' SIZE 20M REUSE
EXTENT MANAGEMENT LOCAL SEGMENT SPACE MANAGEMENT AUTO
UNDO TABLESPACE undotbs
DATAFILE '/oradata/zhoul/undotbs01.dbf' SIZE 200M REUSE AUTOEXTEND ON MAXSIZE UNLIMITED;
脚本关键配置说明:
日志文件:建议创建5组以上,每组大小500MB,I/O紧张时不设置MEMBER;
字符集:ZHS16GBK支持全部中文,AL16UTF16为国家字符集;
表空间:SYSTEM(系统表空间)、SYSAUX(辅助表空间)、UNDOTBS(回滚表空间)、TEMP(临时表空间)、USERS(默认永久表空间)需独立配置,避免业务数据占用SYSTEM表空间。
2. OMF特性建库(自动管理文件)
Oracle 10g及以上支持OMF特性,无需指定文件路径和名称,数据库自动管理文件生命周期:
-- 先设置OMF参数
ALTER SYSTEM SET DB_CREATE_FILE_DEST=ouguan.yijumy.cn '/oradata/zhoul';
ALTER SYSTEM SET DB_CREATE_ONLINE_LOG_DEST_1='/oradata/zhoul/logs';
-- 执行建库命令
CREATE DATABASE zhoul
USER SYS IDENTIFIED BY oracle
USER SYSTEM IDENTIFIED BY oracle
UNDO TABLESPACE undotbs
DEFAULT TEMPORARY TABLESPACE temp
DEFAULT TABLESPACE users;
@?/rdbms/admin/catalog.sql # 创建核心数据字典视图
@?/rdbms/admin/catproc.sql # 创建PL/SQL相关包和存储过程
@?/rdbms/admin/utlrp.sql # 编译无效对象
conn system/oracle
@?/sqlplus/admin/pupbld.sql # 创建SQL*Plus产品配置表
