Github 项目 - YOLOV3 的 TensorFlow 复现

本文介绍了基于 TensorFlow 的 YOLOV3 复现项目,包括 YOLOV3 的主要原理,如网络结构、输入输出、score 阈值过滤和 NMS 处理。此外,还详细阐述了项目入手步骤,如下载预训练权重,转换为 TF checkpoint,以及训练流程。
摘要由CSDN通过智能技术生成

原文:Github 项目 - YOLOV3 的 TensorFlow 复现 - AIUAI

Github 项目 - tensorflow-yolov3

作者:YunYang1994

论文:yolov3

最近 YunYang1994开源的基于 TensorFlow(TF-Slim) 复现的 YOLOv3 复现,并支持自定义数据集的训练.

该开源项目组成:

  • YOLO v3 网络结构
  • 权重转换Weights converter (用于将加载的 COCO 权重导出为 TF checkpoint)
  • 基础测试 demo
  • 支持 GPU 和 CPU 版本的 NMS
  • Training pipeline
  • 计算 COCO mAP

1. YOLOV3 主要原理

参考:yolo系列之yolo v3【深度解析】- 木盏 - CSDN

YOLO 目标检测器基于深度卷积网络学习的特征,以检测目标物体.

正如 木盏 博文里的介绍,YOLOV3 对比 YOLOV1 和 YOLOV2,保留的部分有:

[1] - 分而治之, YOLO 系列算法是通过划分单元格进行目标检测,区别只是划分单元格的数量不同.

[2] - 激活函数采用 Leaky ReLU.

[3] - End-to-end 训练,只需一个损失函数,关注网络输入端和输出端.

[4] - YOLOV2 开始,采用 Batch Normalization 作为正则化、加速收敛和避免过拟合的方法,并将 BN 层和 Leaky ReLU 层放在每个卷积层之后.

[5] - 多尺度训练. 平衡速度和准确率,速度快,则准确率相对低;准确率高,则速度相对慢.

YOLO 系列算法的提升,很大一部分也决定于 backbone 网络的提升,如,YOLOV2 的 darknet-19 到 YOLOV3 的 darknet-53. YOLOV3 还提供了 tiny darknet. 速度快,则 backbone 可采用 tiny-darknet;性能好,则 backbone 可采用 darnket-53. YOLO 系列算法比较灵活,特别适合作工程算法.

1.1. 网络结构

该项目里使用了预训练的网络权重,其中,共有 80 个训练的 yolo 物体类别(COCO 数据集).

记物体类别名 - coco.namesc,其是从 1 到 80 的整数,每个数字分别表示对应的类别名标签. 如,c=3 表示的分类物体类别为 cat.

深度卷积层学习的图像特征,送入到分类器和回归器中,以进行检测预测.(边界框坐标,对应的类别标签,等).

如图:

image

From yolo系列之yolo v3【深度解析】- 木盏 - CSDN

YOLOV3 结构中,没有 池化层全连接层. 在网络的前向计算过程中,张量的尺寸变换是通过改变卷积核步长来实现的,如:stride=(2, 2),等价于将图像 width 和 height 均缩小一般(即面积缩小到原来的1/4).

而,YOLOV2 中,要进行 5 次张量尺寸的缩小(MaxPool),特征图会缩小到原输入尺寸的 在yolo_v2中,要经历5次缩小,会将特征图缩小到原输入尺寸的 1 / 2 5 1/2^5 1/25,即1/32. 例如,输入图像尺寸为 416x416,则输出特征图尺寸为 13x13 (416/32=13).

YOLOV3 类似于 YOLOV2,backbone 网络会将输出特征图缩小到输入图片的 1/32. 因此,要求输入图片的尺寸为 32 的倍数.

  • DBL: YOLOV3 的基本组件,对应于代码中的Darknetconv2d_BN_Leaky,即:卷积+BN+Leaky relu. YOLOV3 中 BN 和 Leaky ReLU 和卷积层是不可分类的部分(除了最后一层卷积),共同构成了最小组件.

  • resnn 代表数字,表示 res_block 里有多少个 res_unit,如 res1,res2, … , res8 等. YOLOV3 借鉴了 ResNet 的残差结构,可以使得网络更深.

  • concat:张量拼接操作. 将 darknet 中间层和后面的某一层的上采样进行拼接. 拼接操作和残差层 add 操作是不一样的,拼接会扩充张量的维度,而 add 只是直接相加不会导致张量维度的改变.

image

Darknet-19 vs Darknet-53 网络层结构 (From yolo系列之yolo v3【深度解析】- 木盏 - CSDN)

YOLOV3 输出了三个不同尺度的特征图 - y1, y2, y3,如图:

image

这种多尺度预测方式,借鉴了 FPN(Feature pyramid networks),对不同尺寸的目标进行预测,越精细的单元网格( grid cell) 可以检测出越精细的物体.

YOLOV3 设定每个网格单元输出 3 个矩形框box 的预测,每个 box 需要五个参数(x, y, w, h, confidence),再对应 80 个类别的概率,则可得到 3*(5 + 80) = 255.

image

From YOLOv3代码分析(Keras+Tensorflow)

1.2. 网络输入与输出

[1] - 网络输入:[None, 416, 416, 3]

[2] - 网络输出:矩形框中物体的置信度,矩形框位置的列表,检测到的物体类别名. 每个矩形框表示为 6 个数:(Rx, Ry, Rh, Rw, Pc, C1,…Cn). 其中,n=80,即 c 是 80 维向量. 矩形框最终的向量大小为 5 + 80=85. 如图:

image

图中第一个数字 Pc 为物体的置信;第二个到第四个数字数字 bx, by, bh, bw 表示矩形框坐标信息;最后的 80 个数字中每个分别表示对应于类别的输出概率.

1.3. 设置 score 阈值过滤边界框

输出结果可能包含多个矩形框,可能是 false positive 结果,或者重叠情况. 如,输入图像尺寸为 [416, 416, 3],YOLOV3 总共采用 9 个 anchor boxes(每个尺寸对应 3 个anchor boxes),则可以得到 (52x52 + 26x26 + 13x13)x3=10647 个矩形框.

因此,需要减少输出结果中的矩形框数量,比如,通过设置 score 阈值.

输入参数:

  • boxes: tensor of shape [10647, 4)]
  • scores: tensor of shape [10647, 80] containing the detection scores for 80 classes.
  • score_thresh: float value , fliter boxes with low score

如:

# Step 1: Create a filtering mask based on "box_class_scores" by using "threshold".
score_thresh=0.4
mask = tf.greater_equal(scores, tf.constant(score_thresh))

1.4. NMS 处理

设置 score 阈值过滤预测的矩形框后,还是可能有大量的重叠矩形框. 进一步的操作是,采用 NMS(non-maximum suppression) 算法.

  • Discard all boxes with Pc <= 0.4
  • While there are any remaining boxes :
    • Pick the box with the largest Pc
    • Output that as a prediction
    • Discard any remaining boxes with IOU>=0.5 with the box output in the previous step

如:

for i in range(num_classes):
    tf.image.non_max_suppression(boxes, score[:,i], iou_threshold=0.5) 

NMS 采用了 IoU(Intersection over Union) 函数. NMS 例示如图:NMS 的输入是 4 个重叠的矩形框,输出是只有一个矩形框.

image

1.5. 相关材料

[1] - Implementing YOLO v3 in Tensorflow (TF-Slim)

[2] - Object Detection using YOLOv2 on Pascal VOC2012

[3] - Understanding YOLO

[4] - YOLOv3目标检测有了TensorFlow实现,可用自己的数据来训练

[5] - 学员分享 | 小哥哥和用YOLOv3做目标检测的故事「文末送课」

[6] - 目标检测|YOLOv2原理与实现(附YOLOv3)

[7] - YOLOv2は、2016年12月25日時点の、速度、精度ともに世界最高のリアルタイム物体検出手法です

2. YOLOV3 项目入手

[1] - 下载项目:

git clone https://github.com/YunYang1994/tensorflow-yolov3.git

[2] - 安装项目依赖项:

cd tensorflow-yolov3
pip3 install -r ./docs/requirements.txt

requirements.txt:

numpy==1.15.1
Pillow==5.3.0
scipy==1.1.0
tensorflow-gpu==1.11.0
wget==3.2

[3] - 将加载的 COCO 权重导出为 TF Checkpoint - yolov3.ckpt 和 frozen graph - yolov3_gpu_nms.pb.

下载 [yolov3.weight](wget https://github.com/YunYang1994/tensorflow-yolov3/releases/download/v1.0/yolov3.weights),并放到 ./checkpoint/ 路径:

wget https://github.com/YunYang1994/tensorflow-yolov3/releases/download/v1.0/yolov3.weights

导出权重:

python3 convert_weight.py --convert --freeze

[4] - 利用路径 ./checkpoint/ 中的 .pb 文件,运行测试 demo:

python3 nms_demo.py
python3 video_demo.py # if use camera, set video_path = 0

如:

image

image

3. YOLOV3 训练

3.1. 下载预训练权重文件

YOLOV3 使用在Imagenet上预训练好的模型参数(文件名称: darknet53.conv.74,大小76MB)基础上继续训练.
darknet53.conv.74下载链接: https://pjreddie.com/media/files/darknet53.conv.74.

wget https://pjreddie.com/media/files/darknet53.conv.74

3.2. 快速入手训练

这里给出 YOLOV3 训练过程的简单示例.

采用 python3 core/convert_tfrecord.py 将图片数据集转换为 tfrecords 文件.

python3 core/convert_tfrecord.py \
		--dataset /data/train_data/quick_train_data/quick_train_data.txt  \
		--tfrecord_path_prefix /data/train_data/quick_train_data/tfrecords/quick_train_data
python3 quick_train.py  # start training

3.3. 训练 COCO 数据集

[1] - 首先,需要下载 COCO2017 数据集,并放到路径 ./data/train_data/COCO 中.

cd data/train_data/COCO
wget http://images.cocodataset.org/zips/train2017.zip
unzip train2017.zip
wget http://images.cocodataset.org/annotations/annotations_trainval2017.zip
unzip annotations_trainval2017.zip

[2] - 提取 COCO 数据集中的一些有用信息,如边界框(bounding box), category id 等,并生成 .txt 文件.

python3 core/extract_coco.py --dataset_info_path ./data/train_data/COCO/train2017.txt

即可得到 ./data/train_data/COCO/train2017.txt. 每一行为一个样本,如:

/path/to/data/train_data/train2017/000000458533.jpg 20 18.19 6.32 424.13 421.83 20 323.86 2.65 640.0 421.94
/path/to/data/train_data/train2017/000000514915.jpg 16 55.38 132.63 519.84 380.4
# image_path, category_id, x_min, y_min, x_max, y_max, category_id, x_min, y_min, ...

[3] - 接着,将图像数据集转换为 .tfrecord 数据集,以二进制文件的方式存储数据. 之后,即可进行模型训练.

python3 core/convert_tfrecord.py \
		--dataset ./data/train_data/COCO/train2017.txt  \
		--tfrecord_path_prefix ./data/train_data/COCO/tfrecords/coco \
		--num_tfrecords 100
python3 train.py

YOLOV2 的训练过程为例:

image

3.4. 在 COCO 数据集上的评估验证(待续)

cd data/train_data/COCO
wget http://images.cocodataset.org/zips/test2017.zip
wget http://images.cocodataset.org/annotations/image_info_test2017.zip 
unzip test2017.zip
unzip image_info_test2017.zip

4. YOLOV3 模型定义

core/common.py

#! /usr/bin/env python3
# coding=utf-8
#================================================================
#   Copyright (C) 2018 * Ltd. All rights reserved.
#
#   Editor      : VIM
#   File name   : common.py
#   Author      : YunYang1994
#   Created date: 2018-11-20 10:22:32
#   Description : some basical layer for daraknet53 and yolov3
#
#================================================================

import tensorflow as tf
slim = tf.contrib.slim

def _conv2d_fixed_padding(inputs, filters, kernel_size, strides=1):
    if strides > 1: inputs = _fixed_padding(inputs, kernel_size)
    inputs = slim.conv2d(inputs, filters, kernel_size, stride=strides,
                         padding=('SAME' if strides == 1 else 'VALID'))
    return inputs


@tf.contrib.framework.add_arg_scope
def _fixed_padding(inputs, kernel_size, *args, mode='CONSTANT', **kwargs):
    """
    Pads the input along the spatial dimensions independently of input size.

    Args:
      inputs: A tensor of size [batch, channels, height_in, width_in] or
        [batch, height_in, width_in, channels] depending on data_format.
      kernel_size: The kernel to be used in the conv2d or max_pool2d operation.
                   Should be a positive integer.
      mode: The mode for tf.pad.

    Returns:
      A tensor with the same format as the input with the data either intact
      (if kernel_size == 1) or padded (if kernel_size > 1).
    """
    pad_total = kernel_size - 1
    pad_beg = pad_total // 2
    pad_end = pad_total - pad_beg

    padded_inputs = tf.pad(inputs, [[0, 0], [pad_beg, pad_end],
                                    [pad_beg, pad_end], [0, 0]], 
                           mode=mode)
    return padded_inputs

core/yolov3.py

#! /usr/bin/env python3
# coding=utf-8
#================================================================
#   Copyright (C) 2018 * Ltd. All rights reserved.
#
#   Editor      : VIM
#   File name   : yolov3.py
#   Author      : YunYang1994
#   Created date: 2018-11-21 18:41:35
#   Description : YOLOv3: An Incremental Improvement
#
#================================================================

import numpy as np
import tensorflow as tf
from core import common, utils
slim = tf.contrib.slim

class 
您好!对于 TPH-YOLOv5 的代码复现,可以按照以下步骤进行操作: 1. 克隆源代码库:首先,将 TPH-YOLOv5 的源代码库克隆到本地。可以通过在终端中执行以下命令完成: ``` git clone https://github.com/tphanson/yolov5.git ``` 2. 安装依赖项:进入克隆下来的 yolov5 文件夹,并使用以下命令安装所有依赖项: ``` cd yolov5 pip install -r requirements.txt ``` 3. 数据准备:将您的训练数据集放在 `data` 文件夹下,并按照要求的格式进行组织。具体的数据集准备方法可以参考 yolov5 官方文档中的说明。 4. 配置模型:在 `models` 文件夹中,可以根据自己的需求选择合适的 YOLOv5 模型结构和超参数配置文件。 5. 开始训练:通过运行以下命令开始训练模型: ``` python train.py --img {image size} --batch {batch size} --epochs {num epochs} --data {path to data.yaml} --cfg {path to model.yaml} ``` 其中,`image size` 是输入图像的尺寸,`batch size` 是每个批次的图像数量,`num epochs` 是训练的迭代次数,`path to data.yaml` 是数据集的配置文件路径,`path to model.yaml` 是模型的配置文件路径。 6. 模型推理:训练完成后,您可以使用训练得到的权重文件进行目标检测推理。使用以下命令运行推理脚本: ``` python detect.py --source {path to input image/video} --weights {path to trained weights} --conf {detection threshold} ``` 其中,`path to input image/video` 是输入图像/视频的路径,`path to trained weights` 是训练得到的权重文件路径,`detection threshold` 是目标检测的置信度阈值。 以上是 TPH-YOLOv5 代码复现的基本步骤。根据您的实际需求,可能还需要对数据集、模型和训练参数进行进一步的配置和调整。希望这些步骤对您有所帮助!如果还有其他问题,请随时提问。
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值