cv_resnet18_ocr-detection模型训练微调指南:使用自定义数据集

张开发
2026/4/14 14:51:22 15 分钟阅读

分享文章

cv_resnet18_ocr-detection模型训练微调指南:使用自定义数据集
cv_resnet18_ocr-detection模型训练微调指南使用自定义数据集1. 从零开始为什么需要训练自己的OCR检测模型你可能已经体验过cv_resnet18_ocr-detection这个OCR文字检测模型它开箱即用识别效果不错。但当你把它用在你的实际业务中时可能会遇到一些“水土不服”的情况。比如你想用它来识别你公司内部特有的票据或表单某个特定行业的手写单据特殊字体或特殊布局的文档在特定光照或背景下的文字这时候你会发现通用模型的表现可能不尽如人意。它可能漏掉一些关键信息或者把不该识别的东西也框出来了。这就是为什么我们需要“训练微调”——让模型学会认识你的数据适应你的场景。简单来说训练微调就是给模型“开小灶”。我们不用从头开始教它那需要海量数据和计算资源而是在它已经学会的“通用文字识别”基础上用我们自己的数据再教它一些“特殊技能”。2. 准备工作你的数据集应该长什么样在开始训练之前最重要的一步就是准备数据。cv_resnet18_ocr-detection要求的数据格式是ICDAR2015格式这是OCR领域一个比较通用的标准格式。2.1 数据集目录结构你的数据集文件夹应该按照下面的结构来组织你的数据集文件夹/ ├── train_list.txt # 训练集文件列表 ├── train_images/ # 训练图片文件夹 │ ├── 001.jpg │ ├── 002.jpg │ └── 003.jpg ├── train_gts/ # 训练标注文件夹 │ ├── 001.txt │ ├── 002.txt │ └── 003.txt ├── test_list.txt # 测试集文件列表 ├── test_images/ # 测试图片文件夹 │ └── 004.jpg └── test_gts/ # 测试标注文件夹 └── 004.txt几个关键点train_images和test_images存放你的图片文件支持JPG、PNG等常见格式train_gts和test_gts存放对应的标注文件每个图片对应一个.txt文件train_list.txt和test_list.txt告诉模型哪些图片用于训练哪些用于测试2.2 标注文件格式详解每个标注文件比如001.txt的内容格式是这样的71,27,226,27,226,72,71,72,文字内容1 331,130,489,130,489,180,331,180,文字内容2 50,200,150,200,150,250,50,250,文字内容3每一行代表一个文本框包含9个信息前8个数字文本框四个角点的坐标x1,y1,x2,y2,x3,y3,x4,y4第9个这个文本框里的文字内容坐标的顺序很重要必须是顺时针方向(x1,y1) —— (x2,y2) | | (x4,y4) —— (x3,y3)2.3 列表文件格式train_list.txt文件的内容示例train_images/001.jpg train_gts/001.txt train_images/002.jpg train_gts/002.txt train_images/003.jpg train_gts/003.txt格式说明每行一条记录第一部分图片的相对路径第二部分对应标注文件的相对路径中间用一个空格分隔2.4 数据准备工具推荐如果你没有现成的标注数据或者需要标注新的图片这里有几个好用的工具在线标注工具Label Studio功能强大的开源标注平台支持OCR标注Roboflow提供在线标注和数据集管理本地标注工具LabelImg简单易用的矩形框标注工具PPOCRLabelPaddleOCR官方标注工具专门为OCR设计快速创建示例数据如果你只是想先试试训练流程可以用下面的Python代码快速生成一个简单的测试数据集import os import cv2 import numpy as np # 创建目录结构 os.makedirs(demo_data/train_images, exist_okTrue) os.makedirs(demo_data/train_gts, exist_okTrue) os.makedirs(demo_data/test_images, exist_okTrue) os.makedirs(demo_data/test_gts, exist_okTrue) # 创建训练数据 for i in range(3): # 创建一张白色背景的图片 img np.ones((300, 400, 3), dtypenp.uint8) * 255 # 在图片上写文字 cv2.putText(img, f测试文字{i1}, (50, 100i*50), cv2.FONT_HERSHEY_SIMPLEX, 1, (0,0,0), 2) # 保存图片 img_path fdemo_data/train_images/{i1:03d}.jpg cv2.imwrite(img_path, img) # 创建标注文件模拟的文本框坐标 gt_path fdemo_data/train_gts/{i1:03d}.txt with open(gt_path, w, encodingutf-8) as f: # 根据文字位置估算文本框 x1, y1 40, 80i*50 x2, y2 200, 80i*50 x3, y3 200, 120i*50 x4, y4 40, 120i*50 f.write(f{x1},{y1},{x2},{y2},{x3},{y3},{x4},{y4},测试文字{i1}\n) # 创建列表文件 with open(demo_data/train_list.txt, w, encodingutf-8) as f: for i in range(3): f.write(ftrain_images/{i1:03d}.jpg train_gts/{i1:03d}.txt\n) print(示例数据集创建完成)3. 实战训练在WebUI中微调你的模型准备好数据后我们就可以开始训练了。cv_resnet18_ocr-detection提供了一个非常友好的WebUI界面让训练过程变得简单直观。3.1 启动训练服务首先确保你已经启动了WebUI服务cd /root/cv_resnet18_ocr-detection bash start_app.sh然后在浏览器中打开http://你的服务器IP:78603.2 进入训练微调页面在WebUI的顶部你会看到几个标签页点击**训练微调**标签进入训练界面。界面主要分为三个部分数据集配置区域设置你的数据路径训练参数区域调整训练的超参数训练控制区域开始/停止训练按钮和状态显示3.3 配置训练参数让我们一个个来看这些参数是什么意思以及怎么设置训练数据目录这是什么你准备好的数据集所在的文件夹路径怎么填比如/root/my_ocr_data或者./demo_data注意路径要写绝对路径或者相对于项目根目录的相对路径Batch Size批次大小这是什么一次训练喂给模型多少张图片默认值8怎么调如果你的显卡内存小比如4GB设为4或2如果显卡内存大比如12GB以上可以设为16或32一般设为8是一个比较平衡的选择训练轮数这是什么整个数据集要训练多少遍默认值5怎么调如果你的数据量少比如几百张可以设10-20轮如果数据量大几千张5-10轮通常就够了注意轮数太多可能导致过拟合模型只记住了训练数据不会泛化学习率这是什么模型学习新知识的速度默认值0.007怎么调如果训练过程中loss下降很慢可以适当调大比如0.01如果loss波动很大或不下降可以调小比如0.001一般先用默认值观察效果再调整3.4 开始训练配置好参数后点击**开始训练**按钮。你会看到状态显示等待开始训练...然后变成训练中...。训练过程中你可以在终端查看实时日志[INFO] 开始第1轮训练... [INFO] 训练进度: 10/50, Loss: 0.4523 [INFO] 训练进度: 20/50, Loss: 0.3214 ... [INFO] 第1轮训练完成验证集准确率: 0.85训练时间参考100张图片训练5轮约10-15分钟GPU1000张图片训练10轮约1-2小时GPU如果没有GPU时间会延长3-5倍3.5 监控训练进度虽然WebUI界面没有实时显示训练曲线但你可以通过以下方式监控训练情况查看训练日志# 查看最新的训练日志 tail -f /root/cv_resnet18_ocr-detection/workdirs/latest_training.log检查生成的模型文件训练完成后模型会保存在workdirs/目录下workdirs/ └── 你的训练任务_时间戳/ ├── best_model.pth # 效果最好的模型权重 ├── latest_model.pth # 最后一轮的模型权重 ├── config.yaml # 训练配置 └── training_log.txt # 训练日志4. 训练技巧与最佳实践4.1 数据质量决定模型上限图片质量要求分辨率适中建议800×600到1920×1080之间文字清晰可辨避免过度模糊、压缩严重的图片光照均匀避免过暗、过亮或反光严重的图片格式统一尽量使用JPG或PNG格式标注质量检查文本框要紧密包围文字不要留太多空白对于倾斜文字要用四边形准确框出标注的文字内容要完全准确包括标点符号对于难以辨认的文字宁可标注为###忽略也不要猜4.2 数据增强让小数据集发挥大作用如果你的数据量不够多可以通过数据增强来创造更多训练样本。你可以在训练前对图片进行一些变换import cv2 import numpy as np from PIL import Image import imgaug.augmenters as iaa # 创建一个数据增强序列 augmenter iaa.Sequential([ iaa.Affine( rotate(-5, 5), # 随机旋转-5到5度 translate_percent{x: (-0.1, 0.1), y: (-0.1, 0.1)}, # 随机平移 scale(0.9, 1.1) # 随机缩放 ), iaa.GaussianBlur(sigma(0, 1.0)), # 轻微高斯模糊 iaa.AdditiveGaussianNoise(scale(0, 0.05*255)), # 添加高斯噪声 iaa.Multiply((0.8, 1.2)), # 调整亮度 iaa.LinearContrast((0.8, 1.2)), # 调整对比度 ]) # 对图片和标注框同时进行增强 def augment_image_and_boxes(image, boxes): # boxes格式: [[x1,y1,x2,y2,x3,y3,x4,y4], ...] keypoints [] for box in boxes: # 将每个框的4个点作为关键点 for i in range(0, 8, 2): keypoints.append(ia.Keypoint(xbox[i], ybox[i1])) # 应用增强 aug_image, aug_keypoints augmenter(imageimage, keypointskeypoints) # 转换回框格式 aug_boxes [] for i in range(0, len(aug_keypoints), 4): box [] for j in range(4): box.append(int(aug_keypoints[ij].x)) box.append(int(aug_keypoints[ij].y)) aug_boxes.append(box) return aug_image, aug_boxes4.3 训练策略调整学习率调度如果训练到后期loss不再下降可以尝试动态调整学习率# 在训练代码中添加学习率调度 from torch.optim.lr_scheduler import StepLR # 每3轮学习率减半 scheduler StepLR(optimizer, step_size3, gamma0.5) # 在每个epoch结束后调用 scheduler.step()早停策略如果连续几轮验证集效果没有提升就提前停止训练避免过拟合best_accuracy 0 patience 3 # 容忍轮数 no_improve_count 0 for epoch in range(num_epochs): # 训练一个epoch train_loss train_one_epoch() # 在验证集上测试 val_accuracy validate() # 保存最好的模型 if val_accuracy best_accuracy: best_accuracy val_accuracy torch.save(model.state_dict(), best_model.pth) no_improve_count 0 else: no_improve_count 1 # 如果连续patience轮没有提升停止训练 if no_improve_count patience: print(f早停触发在第{epoch1}轮停止训练) break4.4 解决常见训练问题问题1训练loss不下降可能原因学习率太大或太小解决方案尝试调整学习率或者使用学习率预热问题2过拟合训练集效果好测试集效果差可能原因模型太复杂或数据太少解决方案增加数据增强、使用Dropout、减少训练轮数问题3训练速度太慢可能原因Batch Size太小或没有用GPU解决方案增大Batch Size在显存允许范围内、确保使用GPU训练问题4显存不足可能原因图片太大或Batch Size太大解决方案减小图片尺寸、减小Batch Size、使用梯度累积5. 训练后的模型使用与评估5.1 加载微调后的模型训练完成后你可以在WebUI中使用新训练的模型在单图检测或批量检测页面模型会自动加载workdirs/目录下最新的权重或者你可以手动指定模型路径如果你想在代码中加载微调后的模型import torch from models.resnet18_ocr import ResNet18OCR # 加载模型结构 model ResNet18OCR() # 加载微调后的权重 checkpoint torch.load(/root/cv_resnet18_ocr-detection/workdirs/你的训练任务/best_model.pth) model.load_state_dict(checkpoint[model_state_dict]) # 切换到评估模式 model.eval()5.2 评估模型效果训练完成后你需要评估模型在实际数据上的表现定量评估指标精确率Precision检测出的框中有多少是真正的文字召回率Recall所有真正的文字有多少被检测出来了F1分数精确率和召回率的调和平均定性评估方法准备一批测试图片不要和训练集重复用训练好的模型进行检测人工检查检测结果有没有漏检该检测的没检测到有没有误检不是文字的也被框出来了文本框的位置准不准对于倾斜文字框的贴合度如何评估代码示例def evaluate_model(model, test_loader): model.eval() total_precision 0 total_recall 0 total_f1 0 num_samples 0 with torch.no_grad(): for images, targets in test_loader: # 模型预测 predictions model(images) # 计算评估指标 precision, recall, f1 calculate_metrics(predictions, targets) total_precision precision total_recall recall total_f1 f1 num_samples 1 avg_precision total_precision / num_samples avg_recall total_recall / num_samples avg_f1 total_f1 / num_samples print(f平均精确率: {avg_precision:.4f}) print(f平均召回率: {avg_recall:.4f}) print(f平均F1分数: {avg_f1:.4f}) return avg_precision, avg_recall, avg_f15.3 模型效果不佳怎么办如果微调后的模型效果不理想可以尝试以下方法1. 检查数据质量标注是否准确有没有漏标或错标图片质量是否太差考虑进行预处理去噪、增强对比度等2. 调整训练参数增加训练轮数如果欠拟合减小学习率如果loss波动大增加数据增强如果数据量少3. 尝试不同的模型初始化从不同的预训练权重开始尝试冻结部分层只训练最后几层4. 调整检测阈值在WebUI中调整检测阈值如果漏检多降低阈值如0.1如果误检多提高阈值如0.36. 进阶技巧持续改进你的OCR模型6.1 增量训练让模型越来越聪明当你有了新的数据不需要从头开始训练# 加载之前训练好的模型 checkpoint torch.load(previous_model.pth) model.load_state_dict(checkpoint[model_state_dict]) optimizer.load_state_dict(checkpoint[optimizer_state_dict]) # 用新数据继续训练 train_with_new_data(model, new_data_loader, optimizer)6.2 难例挖掘重点攻克识别难点找出模型识别不好的样本重点训练用当前模型在测试集上推理找出识别错误的样本漏检、误检、识别错误把这些难例加入训练集重新训练重复这个过程模型会越来越强6.3 多阶段训练策略对于复杂场景可以分阶段训练阶段1基础训练数据通用文字图片目标让模型学会基本的文字检测阶段2领域适应数据你的业务场景图片目标让模型适应你的特定场景阶段3精细调优数据难例高质量标注目标提升在难点样本上的表现6.4 模型集成多个模型投票决定如果单个模型效果有限可以训练多个模型然后集成# 训练多个不同初始化的模型 models [] for i in range(3): model ResNet18OCR() # 用不同的随机种子初始化 torch.manual_seed(i) # 训练模型... models.append(model) # 推理时集成 def ensemble_predict(models, image): all_predictions [] for model in models: pred model(image) all_predictions.append(pred) # 投票或平均结果 final_prediction combine_predictions(all_predictions) return final_prediction7. 总结通过这篇指南你应该已经掌握了如何使用自定义数据集训练和微调cv_resnet18_ocr-detection模型。让我们回顾一下关键要点数据准备是基础高质量、格式正确的数据是成功训练的前提。记住ICDAR2015格式的要求确保标注准确。参数调整有技巧Batch Size、学习率、训练轮数这些参数不是固定的需要根据你的数据和硬件情况灵活调整。监控训练很重要不要设好参数就放任不管要观察loss变化及时调整策略。评估模型要全面既要看定量指标精确率、召回率也要做定性检查人工看结果。持续改进是王道模型训练不是一劳永逸的通过增量训练、难例挖掘等方法可以让模型越来越适应你的需求。训练自己的OCR模型可能一开始会觉得有点复杂但一旦走通整个流程你会发现它带来的价值是巨大的。一个针对你业务场景优化的OCR模型识别准确率可能比通用模型高出20%-30%这在实际应用中意味着更少的人工校对、更高的自动化程度。现在你可以开始收集你的数据动手训练属于你自己的OCR检测模型了。记住最好的学习方式就是动手实践。从一个小数据集开始体验整个训练流程然后逐步扩大数据规模优化模型效果。获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。

更多文章