参考 【小陈的学习笔记】使用PaddleDetection训练自己的数据集_哔哩哔哩_bilibili
项目地址 https://github.com/PaddlePaddle/PaddleDetection
项目文档地址 欢迎使用 PaddleDetection! --- PaddleDetection 0.1 文档 详细的操作方式你可以看这个文档,不详细的可以看下面的
目录
[1 使用环境](#1 使用环境)
[2 验证项目能不能用](#2 验证项目能不能用)
[3 准备数据集](#3 准备数据集)
[3.1 VOCdevkit](#3.1 VOCdevkit)
[3.2 get_label_list.py 与 label_list.txt](#3.2 get_label_list.py 与 label_list.txt)
[3.3 get_train_val.py 与 test.txt 与 trainval.txt](#3.3 get_train_val.py 与 test.txt 与 trainval.txt)
[4 调整网络](#4 调整网络)
[4.1 BASE](#4.1 BASE)
[4.2 num_classes](#4.2 num_classes)
[4.3 epoch](#4.3 epoch)
[4.4 use_gpu](#4.4 use_gpu)
[5 训练模型](#5 训练模型)
[6 预测模型](#6 预测模型)
[6.1 导出预测模型](#6.1 导出预测模型)
[6.2 使用预测模型](#6.2 使用预测模型)
[7 服务预测](#7 服务预测)
[7.1 修改代码](#7.1 修改代码)
[7.2 开启服务](#7.2 开启服务)
[7.3 请求服务](#7.3 请求服务)
[8 遇到的问题](#8 遇到的问题)
[8.1 paddle3.0以上版本预测时会提示要model.json](#8.1 paddle3.0以上版本预测时会提示要model.json)
1 使用环境


paddlepaddle-gpu 2.6.2 python3.10
- 后又用paddlepaddle3.0的cpu版本,也能走完全程
之后安装项目中的requirement
2 验证项目能不能用
需要运行 /ppdet/modeling/test/test_architectures.py 这个文件,在设置的时候注意这两个画红线的位置就行了

正常的运行结果是这样的。他这里就是检查库装没装,还有文件少没少,基本上没问题

3 准备数据集
我搞的是VOC数据集。这个文档里面需要准备的数据集比较麻烦,我简单整了一下,至少需要这几种东西,位置要和我这里面的一样
在项目路径下有个dataset

里面有个voc

voc里面画红框的是需要你准备的东西,没画红框的是他自带的(不用管他,愿意删可以删掉)

3.1 VOCdevkit
里面有个VOC2007
- 名称要一致

VOC2007里面有Annotations和JPEGImages这两个文件夹

Annotations放xml格式文件

JPEGImages放的是图像文件
- 无论是jpg还是png或者是其他的图像类型都是可以的,但最好统一,不然后面要改一下代码

3.2 get_label_list.py 与 label_list.txt
get_label_list.py是用来生成label_list.txt这个文件的
- 如果你有别的方式生成label_list.txt,你也可以不用get_label_list.py

get_label_list.py内容如下

label_list.txt内容如下
- 实际就是标签的名字,最后多一行空行无所谓
- label_list.txt的文件名最好叫这个,不然后面要有改动

3.3 get_train_val.py 与 test.txt 与 trainval.txt
get_train_val.py是生成test.txt与trainval.txt的

get_train_val.py的内容如下

test.txt内容如下
- test.txt是评估集,实际就是前面是图像地址,然后中间放个空格,最后是xml地址

trainval.txt内容如下

4 调整网络
PaddleDetection这个项目中所有可用的神经网络都在configs这个文件夹里面

我用的神经网络是 yolov3_mobilenet_v1_270e_voc.yml
- 这个名字大概是这个意思
- yolov3 是神经网络
- mobilenet 是轻量级网络,就相对于yolov3里面它属于轻量级的,可以理解是这个意思
- v1 版本1。其他版本是什么我不清楚
- 270e 270个epoch
- voc 用的是voc格式数据集

网络中可以调整的参数有很多,我们挑几个重要的说一下
4.1 BASE
BASE 这个是不需要改的,里面的这些yml文件是总yml引用的文件,相当于voc.yml这个文件被yolov3_mobilenet_v1_270e_voc.yml这个文件引用了

4.2 num_classes
num_classes是种类数,是必改的参数,参数在 configs/datasets/voc.yml 中

是几分类就写几

4.3 epoch
epoch是训练的轮数,参数在 configs/yolov3/base/optimizer_270e.yml 中

4.4 use_gpu
在项目路径下的 config/runtime.yml 中

如果不用gpu可以把它搞成false

5 训练模型
实际上你只用把类别数改了,就可以训练了。执行python tools/train.py -c [总yml文件的路径] -o use-gpu=true就可以训练了
- -o是覆盖前面的选项,即使你在yml中对use_gpu设置为false,如果你在这里对use-gpu设置为true,那么就会覆盖掉之前在yml中的设置
第一次训练会自动下载预训练模型

每5个epoch它会进行保留1次,它默认保留在项目路径下的output中,对于咱们来讲只需要下面画框的这两个文件

6 预测模型
6.1 导出预测模型
在output创建与yml同名的文件夹

然后把上面画红框的两个文件放到这个文件夹中

执行 python -u tools/export_model.py -c [总yml文件路径] --output_dir=./inference_model

执行完毕后在 项目路径下会生成一个inference_model



6.2 使用预测模型
执行 python deploy/python/infer.py --model_dir=[模型所在的文件夹路径] --image_file=[要预测的图像路径]

预测完毕后会把预测的结果图像保存到项目路径下的output中

7 服务预测
paddle_serving_cline0.9.0这个版本是不能配合paddlepaddle3.0使用的,所以按照官方的方式部署API(导出服务模型,然后用命令开开启预测的服务)是行不通的

所以还是自己整一个比较好
7.1 修改代码
我们可以看到在 deploy/python/infer.py 的这里

会得到预测的信息。result依次是 id,置信度,左上角x值,左上角y值,右下角x值,右下角y值

我复制了infer.py然后命名为infer_server.py,之后再infer_server.py中把 main() 函数和下面的所有东西都删掉,然后把下面的代码粘贴上
python
def pic_predict(img,label_list):
if FLAGS.use_fd_format:
deploy_file = os.path.join(FLAGS.model_dir, 'inference.yml')
else:
deploy_file = os.path.join(FLAGS.model_dir, 'infer_cfg.yml')
with open(deploy_file) as f:
yml_conf = yaml.safe_load(f)
arch = yml_conf['arch']
detector_func = 'Detector'
if arch == 'SOLOv2':
detector_func = 'DetectorSOLOv2'
elif arch == 'PicoDet':
detector_func = 'DetectorPicoDet'
elif arch == "CLRNet":
detector_func = 'DetectorCLRNet'
detector = eval(detector_func)(
FLAGS.model_dir,
device=FLAGS.device,
run_mode=FLAGS.run_mode,
batch_size=FLAGS.batch_size,
trt_min_shape=FLAGS.trt_min_shape,
trt_max_shape=FLAGS.trt_max_shape,
trt_opt_shape=FLAGS.trt_opt_shape,
trt_calib_mode=FLAGS.trt_calib_mode,
cpu_threads=FLAGS.cpu_threads,
enable_mkldnn=FLAGS.enable_mkldnn,
enable_mkldnn_bfloat16=FLAGS.enable_mkldnn_bfloat16,
threshold=FLAGS.threshold,
output_dir=FLAGS.output_dir,
use_fd_format=FLAGS.use_fd_format)
img_list = []
img_list.append(img)
result = detector.predict_image(
img_list,
FLAGS.run_benchmark,
repeats=100,
visual=FLAGS.save_images,
save_results=FLAGS.save_results)
results_list = []
for i in result['boxes']:
result_list = []
result_list.append(label_list[int(i[0])])
result_list.append(i[1])
result_list.append(int(i[2]))
result_list.append(int(i[3]))
result_list.append(int(i[4]))
result_list.append(int(i[5]))
results_list.append(result_list)
return results_list
paddle.enable_static()
parser = argsparser()
FLAGS = parser.parse_args()
print_arguments(FLAGS)
FLAGS.device = FLAGS.device.upper()
assert FLAGS.device in ['CPU', 'GPU', 'XPU', 'NPU', 'MLU', 'GCU'
], "device should be CPU, GPU, XPU, MLU, NPU or GCU"
assert not FLAGS.use_gpu, "use_gpu has been deprecated, please use --device"
assert not (
FLAGS.enable_mkldnn == False and FLAGS.enable_mkldnn_bfloat16 == True
), 'To enable mkldnn bfloat, please turn on both enable_mkldnn and enable_mkldnn_bfloat16'
yaml_position = "/root/PaddleDetection-release-2.8.1/inference_model/yolov3_mobilenet_v1_270e_voc/infer_cfg.yml"
with open(yaml_position, 'r') as file:
label_list = yaml.safe_load(file)["label_list"]
from flask import Flask,request
app = Flask(__name__)
@app.route('/server_predict',methods=['POST'])
def server_predict():
img_base64 = request.json['img_base64']
img_base64 = base64.b64decode(img_base64)
img_base64 = np.fromstring(img_base64,np.int8)
img_base64 = cv2.imdecode(img_base64,cv2.IMREAD_COLOR)
cv2.imwrite('test.png',img_base64)
return str(pic_predict("test.png",label_list))
if __name__ == '__main__':
app.run(host='0.0.0.0',debug=False)
- 这里实际上是给图像存储下来了,应该也可以不存储下来,我找了找在process这个函数中应该是能操作一下,但看起来比较麻烦,回来有需要再弄
7.2 开启服务
执行 python deploy/python/infer_server.py --model_dir=[模型文件夹] 就可以开启服务了

7.3 请求服务
然后我们搞个图请求一下

发现可以成功预测

8 遇到的问题
8.1 paddle3.0以上版本预测时会提示要model.json
这里不知道哪里蹦出来一个model.json

这个时候需要对infer.py做一些修改,在997行代码对paddle的版本进行了判断。屏蔽掉它,然后把else部分的缩进前提一级,就能预测了
