{"id":15645943,"url":"https://github.com/yeyupiaoling/paddlepaddle-ssd","last_synced_at":"2025-04-30T11:15:05.566Z","repository":{"id":53172716,"uuid":"249637064","full_name":"yeyupiaoling/PaddlePaddle-SSD","owner":"yeyupiaoling","description":"基于PaddlePaddle实现的SSD，包括MobileNetSSD，MobileNetV2SSD，VGGSSD，ResNetSSD","archived":false,"fork":false,"pushed_at":"2023-09-12T04:06:25.000Z","size":6051,"stargazers_count":54,"open_issues_count":0,"forks_count":10,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-30T11:14:59.974Z","etag":null,"topics":["object-detection","ssd","ssd-mobilenet"],"latest_commit_sha":null,"homepage":"https://blog.doiduoyi.com/articles/1591104273719.html","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/yeyupiaoling.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-03-24T07:07:59.000Z","updated_at":"2024-12-12T17:04:56.000Z","dependencies_parsed_at":"2024-10-23T06:34:57.185Z","dependency_job_id":null,"html_url":"https://github.com/yeyupiaoling/PaddlePaddle-SSD","commit_stats":{"total_commits":39,"total_committers":2,"mean_commits":19.5,"dds":0.02564102564102566,"last_synced_commit":"1fb8d7f3ab078c72955d885808b2bbe17fbf9f52"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yeyupiaoling%2FPaddlePaddle-SSD","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yeyupiaoling%2FPaddlePaddle-SSD/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yeyupiaoling%2FPaddlePaddle-SSD/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yeyupiaoling%2FPaddlePaddle-SSD/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yeyupiaoling","download_url":"https://codeload.github.com/yeyupiaoling/PaddlePaddle-SSD/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251687512,"owners_count":21627585,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["object-detection","ssd","ssd-mobilenet"],"created_at":"2024-10-03T12:10:40.545Z","updated_at":"2025-04-30T11:15:05.540Z","avatar_url":"https://github.com/yeyupiaoling.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# PaddlePaddle-SSD\nSSD，全称Single Shot MultiBox Detector，是Wei Liu在ECCV 2016上提出的一种目标检测算法，截至目前是主要的检测框架之一，相比Faster RCNN有明显的速度优势，相比YOLO V1又有明显的mAP优势。本开源是基于PaddlePaddle实现的SSD，参考了PaddlePaddle下的models的[ssd](https://github.com/PaddlePaddle/models/tree/release/1.6/PaddleCV/ssd) ，包括MobileNetSSD，MobileNetV2SSD，VGGSSD，ResNetSSD。使用的是VOC格式数据集，同时提供了预训练模型和VOC数据的预测模型。\n\n# 快速使用\n1. 将图像数据集存放在`dataset/images`目录下，将标注数据存放在`dataset/annotations`目录下。\n2. 执行`create_data_list.py`程序生成数据列表。\n3. 在下面的表格中下载预训练模型，解压到`pretrained`目录下。\n4. 修改`config.py`参数，其中最重要的是`class_num`、`use_model`、`pretrained_model`。`class_num`是分类数量加上背景一类。`use_model`是指使用的模型，分别有resnet_ssd、mobilenet_v2_ssd、mobilenet_v1_ssd、vgg_ssd四种选择。`pretrained_model`是预训练模型的路径。\n5. 执行`train.py`程序开始训练，每训练一轮都会更新保存的模型，训练过程中可以随时停止训练。\n6. 执行`infer.py`预测图像，预测模型的路径在`config.py`配置文件中查找。\n\n![](https://s1.ax1x.com/2020/05/29/tncEHH.jpg)\n\n\n\n# SSD模型介绍\nSSD全称Single Shot MultiBox Detector，是2016年提出的一种one-stage目标检测算法，相比two-stage目标检测算法的Faster R-CNN来说，其特点是一步到位，速度相对较快。\nSSD有以下几个特点：\n1. 将bounding box的输出空间离散化为一系列不同纵横比的default box， 并能够调整box更好地匹配物体的形状。\n2. 将多个不同分辨率的feature map上的预测结果结合，解决了物体不同大小的问题。\n3. 模型结构简单，SSD模型把全部的计算都放在一个网络模型上，大体上可以分为两部分，图像特征提取网络和分类检测网络。\n\n以下是SSD的结构图，在原论文中主干网络为VGG16，后面接着6个卷积层，用于提取出6个不同尺度的feature map，这样可以提取出不同大小的bbox，以检测到不同大小的目标对象。其中主干网络可以替换成其他的卷积网络，所以SSD也产生了几种衍生版，例如MobileNetV2 SSD、ResNet50 SSD等等。生成的6个feature map都输入到分类检测网络中，分类检测网络分别对这6个feature map依次预测的，这个分类检测网络可以使用PaddlePaddle的`fluid.layers.multi_box_head()`接口实现。\n![](https://s1.ax1x.com/2020/06/02/tNGyJs.png)\n\n针对6个feature map的更详细图如下。\n![](https://s1.ax1x.com/2020/06/01/tJwMef.jpg)\n\n\n以下是按照原论文的模型参数搭建的网络模型，在各个衍生版参数设置也有所变动。如下的主干网络是使用VGG16，使用PaddlePaddle实现的代码片段如下。\n```python\nconv1 = self.conv_block(self.img, 64, 2)\nconv2 = self.conv_block(conv1, 128, 2)\nconv3 = self.conv_block(conv2, 256, 3)\n```\n\n6个feature map的实现代码如下，按照论文中的，feature map1的shape为`38*38*512`，feature map2的shape为`19*19*1024`，feature map3的shape为`10*10*512`，feature map4的shape为`5*5*256`，feature map5的shape为`3*3*256`，feature map6的shape为`1*1*256`，\n\n```python\n# 38x38\nmodule11 = self.conv_bn(conv3, 3, 512, 1, 1)\ntmp = self.conv_block(module11, 1024, 5)\n# 19x19\nmodule13 = fluid.layers.conv2d(tmp, 1024, 1)\n# 10x10\nmodule14 = self.extra_block(module13, 256, 512, 1)\n# 5x5\nmodule15 = self.extra_block(module14, 128, 256, 1)\n# 3x3\nmodule16 = self.extra_block(module15, 128, 256, 1)\n# 1x1\nmodule17 = fluid.layers.pool2d(input=module16, pool_type='avg', global_pooling=True)\n```\n\n最后这个就是分类检测模型，在PaddlePaddle上只需一个接口即可完成，在参数`inputs`参数中把6个feature map的输出都作为参数输入。按照论文中设置先验框的长度和`base_size`的最小比率`min_ratio`为20%，先验框的长度和`base_size`的最大比率`max_ratio`为90%，其中`base_size`是输入图片的大小。\n```python\nmbox_locs, mbox_confs, box, box_var = fluid.layers.multi_box_head(\n    inputs=[module11, module13, module14, module15, module16, module17],\n    image=self.img,\n    num_classes=self.num_classes,\n    min_ratio=20,\n    max_ratio=90,\n    min_sizes=[60.0, 105.0, 150.0, 195.0, 240.0, 285.0],\n    max_sizes=[[], 150.0, 195.0, 240.0, 285.0, 300.0],\n    aspect_ratios=[[2.], [2., 3.], [2., 3.], [2., 3.], [2., 3.], [2., 3.]],\n    base_size=self.img_shape[2],\n    offset=0.5,\n    flip=True)\n```\n`min_sizes`和`max_sizes`分别是每层提取的先验框的最小长度和最大长度，当输入个数len(inputs) \u003e 2，并且`min_size`和`max_size`为None时，通过`baze_size`, `min_ratio`和`max_ratio`来计算出`min_size`和`max_size`，计算公式如下：\n```python\nmin_sizes = []\nmax_sizes = []\nstep = int(math.floor(((max_ratio - min_ratio)) / (num_layer - 2)))\nfor ratio in six.moves.range(min_ratio, max_ratio + 1, step):\n    min_sizes.append(base_size * ratio / 100.)\n    max_sizes.append(base_size * (ratio + step) / 100.)\n    min_sizes = [base_size * .10] + min_sizes\n    max_sizes = [base_size * .20] + max_sizes\n```\n\n同样PaddlePaddle也提供了SSD的损失函数，使用的接口时`fluid.layers.ssd_loss()`。通过给定位置偏移预测，置信度预测，候选框和真实框标签，返回的损失是或回归损失和分类损失的加权和。\n```python\nloss = fluid.layers.ssd_loss(locs, confs, gt_box, gt_label, box, box_var)\nloss = fluid.layers.reduce_sum(loss)\n```\n\n\n\n# 代码详解\n本项目中最重要的是`config.py`配置文件，这里包含了所有的训练配置信息，开发者在使用本项目训练自己的数据集时，一定要留意该配置是否符合当前的数据集和训练环境，以下笔者针对几个重要的参数进行解析。\n - `image_shape`输入训练的现状，默认是[3, 300, 300]，也可以设置大小为`512*512`。\n - `batch_size`训练数据的batch大小，根据自己的硬件环境修改，充分使用硬件资源。\n - `epoc_num`训练的轮数，每一轮都会保存预测模型和训练的参数。\n - `lr`初始化学习率。\n - `class_num`分类的数量，通常还要加上背景一类，例如VOC类别是20类，那该值为21。\n - `use_model`使用的SSD的模型，分别有resnet_ssd、mobilenet_v2_ssd、mobilenet_v1_ssd、vgg_ssd，更加自己的需求选择不同的模型，如何开发者是希望嵌入到移动设备的，那么可以考虑mobilenet_v2_ssd、mobilenet_v1_ssd。如何开发者希望有更好的识别准确率，可以使用resnet_ssd。\n - `label_file`分类的标签对应的名称，由`create_data_list.py`生成，通常不需要修改。\n - `train_list`训练数据的数据列表，每一行数据对应的是他们的图片和标注文件的路径，，由`create_data_list.py`生成，通常不需要修改。\n - `test_list`测试数据的数据列表，每一行数据对应的是他们的图片和标注文件的路径，，由`create_data_list.py`生成，通常不需要修改。\n - `persistables_model_path`训练过程中保存的模型参数，可以用于再次训练，恢复之前的训练。\n - `infer_model_path`训练过程中保存的预测模型，可以用于之后的预测图像，不需要再依赖模型代码。\n - `pretrained_model`预训练模型路径，预训练模型文件在上面[模型下载](#模型下载)中下载，需要指定解压的文件夹路径。\n - `use_gpu`是否使用GPU进行训练。\n - `use_multiprocess`是否使用多线程读取数据，在Windows系统下不能使用，否则会出错。\n\n\u003cbr/\u003e\n\n`create_data_list.py`代码是生成数据类别和数据标签的，本项目目前仅支持VOC标注格式的数据。如果开发者把数据集分为`images`和`annotations`，并且存放在`dataset/images`，`dataset/annotations`目录下，还有他们的文件名是一样的，那么这个代码是不需要修改的。如果开发者的数据格式有差别，请修改代码生成如下的数据列表，每一行第一个为图像的路径，第二个是VOC格式的标注文件，他们中间有制表符`\\t`分开。\n\n```\ndataset/images/00001.jpg\tdataset/annotations/00001.xml\ndataset/images/00002.jpg\tdataset/annotations/00002.xml\n```\n\n\u003cbr/\u003e\n\n`train.py`为训练代码，基本上的训练配置都在`config.py`。\n\n\u003cbr/\u003e\n\n`infer.py`为预测代码，这代码可以单独运行，不再需要网络模型代码。预测是可以在图像上画框和类别名称并显示。\n\n - `label_file`是标签文件，由`create_data_list.py`生成，在画框的时候显示类别名称。\n -  `score_threshold`为预测得分阈值，小于该阈值的结果不显示。\n -  `infer_model_path`指定预测模型的路径。\n\n\u003cbr/\u003e\n\n`utils/reader.py`是将图像和标签数据生成训练和测试数据的生成器，图像预处理和生成SSD模型的预选框也会在这个过程完成。但是生成SSD模型的预选框是调用了`utils/image_util.py`完成，这个代码包含了生成预选框和数据增强，增强方式请仔细阅读该代码。\n\n\u003cbr/\u003e\n\n四种模型的代码存放在`nets`文件夹下，包括`mobilenet_v1_ssd.py`，`mobilenet_v2_ssd.py`，`vgg_ssd.py`，`resnet_ssd.py`模型，模型代码介绍请查看上面的[SSD模型介绍](#SSD模型介绍)。\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyeyupiaoling%2Fpaddlepaddle-ssd","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyeyupiaoling%2Fpaddlepaddle-ssd","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyeyupiaoling%2Fpaddlepaddle-ssd/lists"}