从零开始使用最新版Paddle【PaddleOCR系列】——第二部分:自建数据集 + 模型微调训练

目录

一、自建数据集

1.官方数据集格式参考

2.自建数据集txt文件编写代码

3.数据集检验

二、模型训练

1.模型配置yaml文件

2.命令行指令训练


在上一篇文章中,构建好了paddleOCR 运行必需的环境,并通过在线下载的方式,使用官方训练好的模型进行了简单的部署预测。但现实使用中,对于特定任务的数据集,如果想要提高精度表现,需要在原始模型的基础上进行训练微调。

因此,本文记录如何构建符合paddlepaddle训练要求格式的数据集,以及如何使用官方提供的便利低代码量平台 PaddleX 进行模型训练。

环境篇文章快速链接:https://blog.csdn.net/qq_58718853/article/details/142875253

本文属于是记录性文档,斗胆抛砖引玉,详细参见官方文档地址:https://gitee.com/paddlepaddle/PaddleX/blob/release/3.0-beta1/docs/module_usage/tutorials/ocr_modules/text_detection.md

一、自建数据集

1.官方数据集格式参考

在上篇文章中介绍了官方测试数据的命令行快速下载和解压。首先下载官方数据,查看其数据集构建目录结构和内容编写规范。

python 复制代码
## 下载解压数据集
wget https://paddle-model-ecology.bj.bcebos.com/paddlex/data/ocr_det_dataset_examples.tar -P ./dataset
tar -xf ./dataset/ocr_det_dataset_examples.tar -C ./dataset/

目录结构上,在数据集目录下放 images子目录存放所有的图片,框和文字信息分为训练 train和 val 验证,分别存放在 txt 文件中。

txt 文件编写上 ,文本文件每一行代表一张图片的所有信息------图片名和地址、所有框和文字信息的列表。具体来说,框信息和文字信息一起存放在字典结构中,一张图存在多个框和字组合,一起存放在一个列表中。

图片地址和框信息中间用 **'\t'**分隔,中间不能出现空格。图片地址信息始终是字符串格式,需特别注意的是框和文字信息的编写,存在从字典列表结构写入txt 文本结构的转化细节,这在后续实操中会解释。

综上,自建数据集实际需要操作的部分是构建这个两个关键 txt 文件,而编写文本文件中的关键就是后面框和文本信息的编写。下面我自己编写了一个简单的功能性脚本,可以完成对txt文件的编写。

2.自建数据集txt文件编写代码

代码总览:

直接运行下述代码会在项目目录下新建示例文件 test.txt

python 复制代码
import json
import os

class Paddle_Dataset_Creator:
    def __init__(self, savefile, input_dict, input_num=4, mode='only_det'):
        self.savefile = savefile    # paddle训练数据保存地址
        self.input_num = input_num   # 输入训练框数量信息:==4------左上、右下两点四坐标 or ==8------四顶点八坐标
        self.input_dict = input_dict   # 输入字典:键------文件名;值:框坐标列表

        self.mode = mode   # 选择模式:only_det------只进行检测框的训练集构建; ocr------检测框和区域识别字训练集
        self.pp_boxdict = None  # 存放格式正确的框字典

    # 四坐标转为八坐标,并保存paddle支持的框列表结构
    def check_box(self):
        # 标准格式------以一个框为例:[【xx,xx】,【xx,xx】,【xx,xx】,【xx,xx】],从左上顶点出发,顺时针一圈
        if self.input_num == 4:
            self.pp_boxdict = dict()
            for key in self.input_dict.keys():
                two_boxes_list = self.input_dict[key]  # 四坐标列表信息
                pp_box_list = []
                for two_box in two_boxes_list:
                    pp_dict = dict()
                    if self.mode == 'only_det':
                        l,t,r,b = two_box  # 左x_min,上y_min, 右x_max, 下y_max
                        pp_dict["transcription"] = "ZW"
                    elif self.mode == 'ocr':
                        l,t,r,b,text = two_box
                        pp_dict["transcription"] = str(text)
                    else:
                        raise ValueError('miss key value self.mode')
                    pp_box = [[min(l,r), min(t,b)], [max(l,r), min(t,b)], [max(l,r), max(t,b)], [min(l,r), max(t,b)]]
                    pp_dict["points"] = pp_box
                    pp_box_list.append(pp_dict)
                self.pp_boxdict[key] = pp_box_list
        elif self.input_num == 8:
            self.pp_boxdict = dict()
            for key in self.input_dict.keys():
                four_boxes_list = self.input_dict[key]  # 四坐标列表信息
                pp_box_list = []
                for four_box in four_boxes_list:
                    pp_dict = dict()
                    if self.mode == 'only_det':
                        pp_dict["transcription"] = "ZW"
                        pp_dict["points"] = four_box
                    elif self.mode == 'ocr':
                        pp_dict["transcription"] = str(four_box[4])
                        pp_dict["points"] = four_box[:4]
                    else:
                        raise ValueError('miss key value self.mode')
                    pp_box_list.append(pp_dict)
                self.pp_boxdict[key] = pp_box_list
        else:
            raise ValueError('cant process box_num, box_num must in [4,8]')

    # 创建paddle数据txt文件
    def create_pptext(self, mode='train'):
        savedir = os.path.join(self.savefile, mode+'.txt')  # 保存结果地址
        if self.pp_boxdict != None:
            for name in self.pp_boxdict.keys():
                filename = 'images/'+name     # 写入txt图片地址信息
                box_list = self.pp_boxdict[name] # 写入txt框和字信息
                json_box_list = json.dumps(box_list, ensure_ascii=False, separators=(',',':'))
                line_text = filename + '\t' + str(json_box_list)   # 写入一行完整信息,中间使用'\t'隔开
                with open(savedir, 'a') as f:
                    f.writelines(str(line_text))
                with open(savedir, 'a') as f:
                    f.write('\n')

if __name__=='__main__':
    example1 = {'abc.jpg':[[1,2,3,4],[5,6,7,8]], 'def.jpg':[[10,20,30,40],[50,60,70,80]]}
    example2 = {'abc.jpg':[[1,2,3,4,'a'],[5,6,7,8,'b']], 'def.jpg':[[10,20,30,40,'c'],[50,60,70,80,'d']]}
    paddle_creator = Paddle_Dataset_Creator(savefile='./', input_dict=example1, input_num=4, mode='only_det')
    paddle_creator.check_box()
    paddle_creator.create_pptext(mode='test')
    print(paddle_creator.pp_boxdict)

使用方法:

必要条件:1.框信息是顶点的绝对值坐标信息构建的(如果是归一化坐标------YOLO,或者是左上点坐标信息加框的长宽,需要先做好数据转化)

2.输入数据格式必须是字典,且键为对应图片文件名,值为该图所有框和字信息

3.如果存在文字信息,请放在对应框列表的最后;如果没有文字信息,则默认为只训练框的检测模型。

具体使用:

具体使用的时候,只需将此类嵌入文件处理的过程中,使用相应的功能函数即可。

①初始化 self.init:

初始化类有四个需要输入的参数------savefile :你需要txt文件保存的地址;input_dict :框和文字信息字典(按必要条件要求组织);input_num :框信息坐标数量,默认是4,代表左上右下两点四坐标;mode :是做仅框的检测模型训练 'only_det' ,还是带上识别模型的文本训练**'ocr'**

②框信息规范 self.check_box:

直接训练该函数会将输入的框信息标准化为paddle需要的格式

③写入txt文件 self.create_pptext(mode):

传入mode参数代表当前编写的是训练集train的txt还验证val的txt文件。

3.数据集检验

PaddleX 中自备了检验数据集是否构建成功的命令行指令。

使用时只需将 xxx.yaml 修改为自建模型配置文件地址,将dataset_dir=xxx 改为自建数据集地址即可。

python 复制代码
# 效验官方数据集
python main.py -c paddlex/configs/text_detection/PP-OCRv4_mobile_det.yaml -o Global.mode=check_dataset -o Global.dataset_dir=./dataset/ocr_det_dataset_examples

# 效验自建数据集
python main.py -c xxx.yaml -o Global.mode=check_dataset -o Global.dataset_dir=xxx

运行出现以下绿字则说明数据集构建成功。

二、模型训练

这里模型训练仅以文本检测 ------text_detection 模型为例,实际上大部分其他模型的训练方式逻辑和本例类似。两步走:一、找到对应模型配置文件;二、命令行指令运行训练。

1.模型配置yaml文件

首先需要找到需要的模型配置 yaml 文件,在之前git克隆下载好的 PaddleX 源码**/paddlex/configs**目录下就可以查询到 paddle 所有模型的配置文件。

打开本例需要的PP-OCRv4_server_det.yaml文件,按下图修改一些参数即可。(实际上,不一定非要修改,在命令行指令运行中也可以传入修改对应参数,如在命令代码后加上-o Global.dataset_dir=./dataset/ocr_det_dataset_examples,也可以修改数据集目录)

2.命令行指令训练

命令行训练需要配置几个所必需的参数,下面逐一记录。

一个官方例子如下图。

基础命令参数配置:

**① -c model.yaml:**这是模型配置yaml文件地址

②-o Global.mode=train:当前模式选择,可以是训练train模式也可以是验证或者预测模式

③-o Global.dataset_dir=./:之前构建的训练数据集目录地址

④-o Global.device=gpu:0,1:指定训练设备,例中表示使用双卡训练

⑤-o Global.output=./:结果保存地址

训练参数配置:

⑥-o Train.epochs_iters=100:训练轮次

⑦-o Train.num_classes=1:数据集中的类别数,对于仅框检测来说,类别为1

⑧-o Train.batch_size=16:训练批量大小

⑨-o Train.pretrain_weight_path:预训练模型参数地址,第一次训练会下载在本地c盘

参数配置上的详细内容参考官方文档地址:https://gitee.com/paddlepaddle/PaddleX/blob/release/3.0-beta1/docs/module_usage/instructions/config_parameters_common.md

训练中会打印过程结果。

经过训练结果保存目录会得到以下结果。

可以在best_model下找到训练最优模型参数,即可将微调模型参数用于部署任务。

由于服务器CUDA版本环境存在一定冲突,虽然之前在yolo训练时没有报过错,但paddle会有警告。不过似乎并特别影响正常训练,训练还是能跑起来的。下一章将集中精力解决这些环境报错,并深入研究其训练输出目录下结果的使用,还有模型的测试评估和最终的部署。

相关推荐
思通数科多模态大模型12 小时前
10大核心应用场景,解锁AI检测系统的智能安全之道
人工智能·深度学习·安全·目标检测·计算机视觉·自然语言处理·数据挖掘
sp_fyf_202413 小时前
【大语言模型】ACL2024论文-18 MINPROMPT:基于图的最小提示数据增强用于少样本问答
人工智能·深度学习·神经网络·目标检测·机器学习·语言模型·自然语言处理
思通数科AI全行业智能NLP系统14 小时前
六大核心应用场景,解锁AI检测系统的智能安全之道
图像处理·人工智能·深度学习·安全·目标检测·计算机视觉·知识图谱
非自律懒癌患者16 小时前
Transformer中的Self-Attention机制如何自然地适应于目标检测任务
人工智能·算法·目标检测
菠菠萝宝19 小时前
【YOLOv8】安卓端部署-1-项目介绍
android·java·c++·yolo·目标检测·目标跟踪·kotlin
Eric.Lee20211 天前
数据集-目标检测系列- 花卉 玫瑰 检测数据集 rose >> DataBall
人工智能·目标检测·计算机视觉
Eric.Lee20211 天前
数据集-目标检测系列- 花卉 鸡蛋花 检测数据集 frangipani >> DataBall
人工智能·python·yolo·目标检测·计算机视觉·鸡蛋花检查
杰哥技术分享2 天前
百度飞浆:paddle 线性回归模型
百度·线性回归·paddle
深度学习lover2 天前
<项目代码>YOLOv8 草莓成熟识别<目标检测>
人工智能·python·yolo·目标检测·计算机视觉·草莓成熟识别
铭瑾熙2 天前
深度学习之目标检测的技巧汇总
人工智能·深度学习·目标检测