概述
模型统一服务中心,如果将其类比成施工队的话,那么此处应该是项目经理的指挥中心,主要负责协调模型的加载、配置和部署,提供便捷的接口和功能,确保整个项目能够高效地启动、执行和测试
主要模块
- _create 函数(模型创建函数)
- 功能:通用的模型加载和创建函数,处理预训练权重、设备选择、依赖检查等
- 项目经理根据项目需求和资源,决定使用哪种建筑设计,选择合适的建筑材料和施工设备
- custom 函数(自定义模型加载函数)
- 功能:加载自定义或本地保存的模型权重
- 项目经理根据特定客户需求,使用自定义的建筑设计或特别定制的建筑材料
- yolov3、yolov3_spp、yolov3_tiny 函数(特定模型加载函数)
- 功能:加载不同版本的 YOLOv3 模型,提供便捷的接口
- 项目经理根据不同的建筑项目需求,选择不同类型的建筑设计方案
- 主执行块(Main Execution Block)
- 功能:演示如何加载模型并进行推理,验证模型的实际效果
- 项目经理在施工完成后,对建筑进行最终的质量检查和功能测试,确保所有系统正常运行
模块分析
_create 函数(模型创建函数)
该函数是一个通用的模型创建函数,负责根据指定的模型名称、是否使用预训练权重、输入通道数、类别数等参数,加载或构建相应的 YOLOv3 模型
类似于项目经理根据项目需求和资源,决定使用哪种建筑设计(模型配置),选择合适的建筑材料(预训练权重),并协调施工设备和工具(设备选择和依赖安装)
分析:此处创建模型的逻辑
该函数会创建一个完整的yolov3模型,其中是包括主干网络、Neck、Head部分,但是不包括后处理部分
里面有两种模型,其一可以使用预训练模型,那么相应的权重会自动加载,其二则是自定义模型,会根据yolov3.yaml或者自己创建的结构实现
主要流程总结
- 检查依赖和设置日志
- 加载预训练权重或构建新模型
- 启用 autoshape 支持多种输入
- 将模型移到指定设备并返回
def _create(name, pretrained=True, channels=3, classes=80, autoshape=True, verbose=True, device=None):
"""
创建指定的 YOLO 模型。
该函数根据模型的名称、通道数和类别数,创建并返回对应的 YOLO 模型实例,
支持加载预训练权重和自定义类别数、通道数等功能。
参数:
name (str): 模型名称,例如 'yolov3'。
pretrained (bool): 是否加载预训练权重,默认为 True。
channels (int): 输入图像的通道数,默认为 3(RGB 图像)。
classes (int): 模型的类别数,默认为 80。
autoshape (bool): 是否应用 `.autoshape()` 包装器以支持多种输入格式,默认为 True。
verbose (bool): 是否打印详细日志信息,默认为 True。
device (str, torch.device, None): 模型加载的设备('cpu' 或 'cuda'),默认为 None(自动选择设备)。
返回:
torch.nn.Module: 加载完成的模型。
"""
# **导入必要的模块和工具**
from pathlib import Path # 用于文件路径操作
from models.experimental import attempt_load # 加载预训练模型
from models.yolo import Model # YOLO 模型类
from utils.downloads import attempt_download # 下载权重文件
from utils.general import check_requirements, intersect_dicts, set_logging # 通用工具
from utils.torch_utils import select_device # 选择设备(CPU 或 GPU)
# 获取当前脚本的绝对路径
file = Path(__file__).resolve()
# 检查并安装必要的依赖项(排除 'tensorboard', 'thop', 'opencv-python')
check_requirements(exclude=('tensorboard', 'thop', 'opencv-python'))
# 根据 verbose 参数设置日志记录的详细程度
set_logging(verbose=verbose)
# **模型保存路径**
# 如果模型名称以 '.pt' 结尾,则保存目录为空路径;否则为当前脚本所在目录的父目录
save_dir = Path('') if str(name).endswith('.pt') else file.parent
path = (save_dir / name).with_suffix('.pt') # 模型检查点的完整路径
try:
# **选择设备**
# 如果未指定设备,则自动选择 GPU(如果可用)或 CPU
device = select_device(('0' if torch.cuda.is_available() else 'cpu') if device is None else device)
# **加载模型**
if pretrained and channels == 3 and classes == 80:
# 如果需要加载预训练权重,并且输入通道数为 3,类别数为 80(COCO 数据集),
# 尝试从指定路径加载预训练模型
model = attempt_load(path, map_location=device) # 下载或加载 FP32 模型权重
else:
# 如果未启用预训练权重,或者需要自定义通道数和类别数
# 从 YAML 配置文件构建一个新模型
cfg = list((Path(__file__).parent / 'models').rglob(f'{name}.yaml'))[0] # 查找模型的 YAML 配置文件路径
model = Model(cfg, channels, classes) # 使用配置文件、输入通道数和类别数创建模型实例
if pretrained:
# 如果指定了预训练权重,则加载权重文件
ckpt = torch.load(attempt_download(path), map_location=device) # 加载检查点权重
csd = ckpt['model'].float().state_dict() # 提取模型的 state_dict(参数字典)
csd = intersect_dicts(csd, model.state_dict(), exclude=['anchors']) # 取权重字典的交集(忽略 anchors 参数)
model.load_state_dict(csd, strict=False) # 加载权重到模型(非严格匹配)
# 如果权重文件中的类别名称数量与目标类别数一致,则更新模型的类别名称
if len(ckpt['model'].names) == classes:
model.names = ckpt['model'].names
# **是否启用 autoshape 包装器**
# 如果 autoshape 为 True,则为模型添加 autoshape 功能,支持更多类型的输入(如 OpenCV 图像、PIL 图像等)
if autoshape:
model = model.autoshape()
# **返回模型**
# 将模型移到指定设备(CPU 或 GPU),并返回模型实例
return model.to(device)
except Exception as e:
# **异常处理**
# 如果在加载或创建模型过程中发生异常,提示用户更新缓存或参考帮助文档
help_url = 'https://github.com/ultralytics/yolov5/issues/36' # 提供帮助链接
s = 'Cache may be out of date, try `force_reload=True`. See %s for help.' % help_url
raise Exception(s) from e # 提示带有额外信息的异常
custom 函数(自定义模型加载函数)
该函数允许用户加载自定义或本地保存的模型权重,通过_create函数,可以指定任意路径的模型文件进行加载
类似于项目经理根据特定客户需求,使用自定义的建筑设计或特别定制的建筑材料,确保建筑项目能够满足特定的功能和客户特殊要求
def custom(path='path/to/model.pt', autoshape=True, verbose=True, device=None):
# 自定义或本地模型
return _create(path, autoshape=autoshape, verbose=verbose, device=device)
特定模型加载函数
与上述相似
主函数
类似于项目经理在施工完成后,对建筑进行最终的质量检查和功能测试,确保所有系统(如安全监控、照明系统等)正常运行,并记录和保存测试结果
if __name__ == '__main__':
"""
主函数入口,用于测试 YOLOv3-tiny 模型的加载和推理。
流程:
1. 创建 YOLOv3-tiny 模型。
2. 定义多种类型的输入图像。
3. 使用模型进行推理并输出推理结果。
"""
# **Step 1: 创建 YOLOv3-tiny 模型**
# 调用 _create 函数,加载 YOLOv3-tiny 模型,使用预训练权重。
model = _create(
name='yolov3-tiny', # 模型名称
pretrained=True, # 是否加载预训练权重
channels=3, # 输入图像的通道数(RGB)
classes=80, # 模型的目标类别数(COCO 数据集,80 类)
autoshape=True, # 是否启用 autoshape,支持多种输入格式
verbose=True # 是否打印加载过程的详细信息
)
# **注释:**
# 如果需要加载自定义模型(例如训练的权重文件),可以使用以下代码替代上面的 `_create`:
# model = custom(path='path/to/model.pt') # 自定义模型路径
# **Step 2: 导入必要的库**
from pathlib import Path # 用于文件路径操作
import cv2 # OpenCV,用于读取和处理图像
import numpy as np # 用于创建和操作矩阵
from PIL import Image # PIL库,用于图像读取和处理
# **Step 3: 定义测试的输入图像**
imgs = [
'data/images/zidane.jpg', # 图像文件路径(字符串形式)
Path('data/images/zidane.jpg'), # 图像文件路径(Path对象)
'https://ultralytics.com/images/zidane.jpg', # 图像网络地址(HTTP URL)
cv2.imread('data/images/bus.jpg')[:, :, ::-1], # 使用 OpenCV 读取图像,并转换为 RGB 格式
Image.open('data/images/bus.jpg'), # 使用 PIL 库读取图像
np.zeros((320, 640, 3)) # 创建一个空的 numpy 数组,表示一张黑色图像(大小为 320x640x3)
]
# **Step 4: 使用模型进行批量推理**
results = model(imgs) # 将图像列表作为输入,进行模型推理
# **Step 5: 输出推理结果**
# 打印推理结果,例如目标框、类别和置信度分数
results.print()
# 保存推理结果,包括检测到的目标框和标注的图像
results.save()