YOLO代码详解(一)

源码fork自 该版本,代码注释借鉴多处,仅供个人学习记录。

0.文件结构

在这里插入图片描述

  • config: 配置文件,包含超参数、网络结构等信息
  • data: 训练图片、训练标签等信息
  • pytorchyolo:项目需要使用到的工具代码,运行代码
  • weights: 权重文件

0.1 config:

在这里插入图片描述

├── coco.data
├── create_custom_model.sh # 创建自定义.cfg用的脚本
├── custom.data
├── yolov3-tiny.cfg # 模型定义文件
├── yolov3.cfg # 模型定义文件

0.1.1 coco.data:

coco数据的配置文件

classes= 80
train=data/coco/trainvalno5k.txt
valid=data/coco/5k.txt
names=data/coco.names
backup=backup/
eval=coco

class=80

表示类别的数量

train=data/coco/trainvalno5k.txt
valid=data/coco/5k.txt

coco数据集的训练集数据地址和验证集数据地址

backup=backup/

备份文件

eval=coco

0.1.2 create_custom_model.sh

create_custom_model.sh是用来执行自定义模型的文件,建自定义.cfg用的脚本

0.1.3 custom.data:

classes= 1 # 类别数量
train=data/custom/train.txt # 存放训练集图片地址的txt
valid=data/custom/valid.txt # 存放验证集图片地址的txt
names=data/custom/classes.names # 类别名称

0.2 data:

── coco
│ └── 5k.txt
├── coco.names
├── custom
│ ├── classes.names
│ ├── images
│ │ └── train.jpg
│ ├── labels
│ │ └── train.txt
│ ├── train.txt
│ └── valid.txt
├── get_coco_dataset.sh
└── samples

0.2.1 custom

在这里插入图片描述

这里的customer文件夹配合上面的custom.data,就是完整的自定义训练集的配置文件了。
images:存放训练验证图片

labels: (可通过代码将xml格式文件进行转换)存放YOLO格式的标签 其中每一个.txt对应images中一个.jpg;.txt中每一行对应一个gt框。坐标均除以原图的长宽以归一化。第一个是标签号,从0开始 中心点x坐标 中心点y坐标 标注框的宽 标注框的高。

classes.names:这里面写的是所有类别的标签,标签用换行符隔开,最后一行末尾没有换行符。类别名称的顺序与类别标号对应

train.txt: 训练数据的地址

valid.txt: 验证数据的地址

1 推理介绍

detect.py 文件

该文件的作用、推理过程:

1、配置参数。
2、加载模型。
3、加载数据。
4、推理&绘制

1.1 配置参数

 parser = argparse.ArgumentParser(description="Detect objects on images.")
    parser.add_argument("-m", "--model", type=str, default="config/yolov3.cfg", help="Path to model definition file (.cfg)")  #网络结构
    parser.add_argument("-w", "--weights", type=str, default="weights/yolov3.weights", help="Path to weights or checkpoint file (.weights or .pth)") #权重文件
    parser.add_argument("-i", "--images", type=str, default="data/samples", help="Path to directory with images to inference")# 推理图片路径
    parser.add_argument("-c", "--classes", type=str, default="data/coco.names", help="Path to classes label file (.names)") # 类别名称
    parser.add_argument("-o", "--output", type=str, default="output", help="Path to output directory") # 输出路径
    parser.add_argument("-b", "--batch_size", type=int, default=1, help="Size of each image batch") 
    parser.add_argument("--img_size", type=int, default=416, help="Size of each image dimension for yolo")
    parser.add_argument("--n_cpu", type=int, default=0, help="Number of cpu threads to use during batch generation")
    parser.add_argument("--conf_thres", type=float, default=0.5, help="Object confidence threshold") # 置信度阈值
    parser.add_argument("--nms_thres", type=float, default=0.4, help="IOU threshold for non-maximum suppression") # nms阈值
    args = parser.parse_args()

1.2 加载模型

进入detect_directory 开始推理

def detect_directory(...):
    dataloader = _create_data_loader(img_path, batch_size, img_size, n_cpu)
    model = load_model(model_path, weights_path)
    img_detections, imgs = detect(model,dataloader, output_path, conf_thres,nms_thres)
    _draw_and_save_output_images(img_detections, imgs, img_size, output_path, classes)

model = load_model(model_path, weights_pat 加载模型

def load_model(model_path, weights_path=None):
    device = torch.device("cuda" if torch.cuda.is_available()
                          else "cpu")  # Select device for inference
    model = Darknet(model_path).to(device)

    model.apply(weights_init_normal)

    # If pretrained weights are specified, start from checkpoint or weight file
    if weights_path:
        if weights_path.endswith(".pth"):
            # Load checkpoint weights
            model.load_state_dict(torch.load(weights_path, map_location=device))
        else:
            # Load darknet weights
            model.load_darknet_weights(weights_path)
    return model

这里利用自定义的Darknet——一个自定义的nn.Module——来解析模型的网络结构文件(yolov3.cfg)

yolov3.cfg文件
见博客 https://editor.youkuaiyun.com/md/?articleId=131627851

Darknet类

这个类在models.py里面。该类的init方法里面,就将配置文件转化为以nn.ModuleList表示的网络结构了。
models.py ->class Darknet(nn.Modules)

class Darknet(nn.Module):
    """YOLOv3 object detection model"""

    def __init__(self, config_path):
        super(Darknet, self).__init__()
        self.module_defs = parse_model_config(config_path)
        ## 使用 parse_model_config函数 解析.cfg文件,输出的是一个包含配置信息的list
        
        self.hyperparams, self.module_list = create_modules(self.module_defs)
		## 使用 create_modules函数, 输出配置信息list,得到网络的超参数hyperparams和nn.Modulelist(module_list)
	
        self.yolo_layers = 
### YOLO V1 源码解析与实现细节 #### 1. 数据预处理 在YOLO V1中,输入图像被调整到固定大小(通常是448×448),并应用些简单的数据增强技术来提高模型泛化能力。这些操作包括随机裁剪、颜色抖动等[^1]。 #### 2. 网络结构设计 YOLO V1采用了种类似于GoogLeNet的卷积神经网络架构,该网络由多个卷积层和池化层组成,最后接两个全连接层。具体来说: - 输入尺寸为\(448 \times 448\) 的RGB图片; - 经过系列 \(7\times7\), stride=2 和 \(3\times3\), maxpooling layers; - 使用了若干个 \(1\times1\) 卷积减少通道数以及 \(3\times3\) 卷积提取特征; - 输出维度为 \(S\times S\times (B*5+C)\),其中\(S=7,B=2,C=20\)分别表示网格数量、边界框预测数目及类别种类数。 ```python import torch.nn as nn class YOLONet(nn.Module): def __init__(self, num_classes=20): super(YOLONet, self).__init__() # 定义基础卷积层 self.conv_layers = nn.Sequential( nn.Conv2d(3, 64, kernel_size=7, stride=2), nn.LeakyReLU(), ... ) def forward(self, x): out = self.conv_layers(x) return out.view(out.size()[0], -1) model = YOLONet() print(model) ``` #### 3. Loss Function 设计 为了训练这个多任务学习框架下的分类器兼回归器,损失函数综合考虑了以下几个方面: - **坐标误差**:对于每个负责预测物体位置的cell中的每个box,计算中心点偏差平方和宽度高度log尺度差值。 - **置信度得分**:衡量所预测bbox内是否有object存在及其IOU情况。 - **类别概率分布差异**:当某个grid cell确实含有目标对象时,则需最小化真实标签向量y与预测p之间的交叉熵距离。 \[ L_{coord}=\lambda _{coord}\sum _{{i}=0}^{S^{2}}\sum _{j=0}^{B}(1^{obj}_{ij})[(x_i-\hat{x}_i)^2+(y_i-\hat{y}_i)^2]\] \[L_{noobj}=\lambda _{noobj}\sum _{i=0}^{S^2}\sum _{j=0}^{B}(1^{noobj}_{ij})(C_i-\hat C_i)^2\] \[L_{class}=\sum _{i=0}^{S^2}1^{obj}_i\sum _{c\in classes}(p_i(c)-\hat p_i(c))^2\] 最终总Loss定义如下: \[loss=(L_{coord}+L_{conf}+L_{class})\]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值