⚠️本文为稀土技能社区首发签约文章,30天内制止转载,30天后未获授权制止转载,侵权必究!
✨专栏介绍: 经过几个月的精心筹备,本作者推出全新系列《浅显易懂OCR》专栏,对标最全OCR教程,具体章节如导图所示,将分别从OCR技能发展、方向、概念、算法、论文、数据集等各种视点展开具体介绍。
个人主页: GoAI | 公众号: GoAI的学习小屋 | 交流群: 704932595 |个人简介 : 签约作者、百度飞桨PPDE、领航团团长、开源特训营导师、CSDN、阿里云社区人工智能范畴博客专家、新星方案计算机视觉方向导师等,专心大数据与人工智能常识共享。
文章目录
《浅显易懂OCR》前语常识(二):深度学习根底总结 (✨文末有深度学习总结导图福利!)
《浅显易懂OCR》前语常识(一):机器学习根底总结 (✨文末有机器学习总结导图福利!)
【计算机视觉OCR项目实战】中文文字辨认
本篇导读:在上节深度学习常识总结,自己对手写辨认项目进行实战,为了进一步学习计算机视觉常识,咱们本次以计算机视觉的OCR方向为例,完结中文场景辨认,从头到尾帮助咱们学习并完结中文文字辨认实战使命,方便学习者学习计算机视觉项目流程。
一、项目背景
随着OCR范畴在结构化数据中取得不错作用及应用,中文场景文字辨认技能在人们的日常日子中受到广泛重视,在文档辨认、身份证辨认、银行卡辨认、病例辨认、名片辨认等范畴广泛应用.但由于中文场景中的文字容易受光照改动、低分辨率、字体以及排布多样性、中文字符品种多等影响,对辨认经典有一定影响,如何解决这一问题是现在值得重视的。
二、项目简介:
本项目为根据PaddleOCR的中文场景文字辨认,项目首要以CRNN网络为根底结构,结合数据增强及模型微调,选用ResNet34和MobileNetV3模型作为骨干网络,进行练习及猜测。以准确度为评价目标,终究生成的猜测文件为work中的result.txt文件。
三、数据集介绍:
项目供给的数据练习集(train_img)是5w张,测验集(test_img)为1w张。练习集原始标示文件(train.list)。
- 数据集采自中国街景,并由街景图片中的文字行区域(例如店肆标牌、地标等等)截取出来而构成
- 所有图画都经过一些预处理,将文字区域运用仿射改动,等比映射为一张高为48像素的图片。
数据集样例如下:
标示文件
本数据集供给的标示文件为.txt文件格局。标示文件中的四列分别是图片的宽、高、文件名和文字标示。标示文件信息如下:
h | w | name | value |
---|---|---|---|
128 | 48 | img_1.jpg | 文本1 |
56 | 48 | img_2.jpg | 文本2 |
四、相关结构及技能
PaddleOCR结构: github.com/PaddlePaddl…
PaddleOCR是一款超轻量、中英文辨认模型,目标是打造丰厚、抢先、有用的文本辨认模型/工具库 3.5M有用超轻量OCR体系,支撑在服务器,移动,嵌入式和IoT设备之间进行培训和部署 同时支撑中英文辨认;支撑倾斜、竖排等多种方向文字辨认,支撑GPU、CPU猜测,同时可运转于Linux、Windows、MacOS等多种体系。
本次项目以开源的百度飞桨PaddleOCR为结构,选用CRNN+CTC网络为主体,具体结构如下图:
五、项目流程:
深度学习OCR通用流程
项目剖析:针对中文场景下的数据预处理(包括:把繁体字转成简体字,大写->小写,删去空格,删去符号等操作),结合相应的中文字典来提高文字辨认的准确率。并且在飞桨结构下选用当前业界最经典的CRNN算法架构来建模与求解,以确保模型的性能。
根据上述剖析,我将本次项目大致分为以下几个流程:
1.PaddleOCR环境装置
2.数据处理
3.模型调整
4.练习与猜测
六、环境装置
6.1 项目环境装置
本次项目环境需求先克隆PaddleOCR项目,具体指令:
!cd ~/work && git clone -b develop <https://gitee.com/paddlepaddle/PaddleOCR.git>
其次,需求装置PaddleOCR项目供给环境文件requirements.txt,具体指令:
!cd ~/work/PaddleOCR
!pip install -r ./requirements.txt && python setup.py install
6.2 PaddleOCR辨认测验
另外,在正式开端介绍项现在,咱们测验能够快速开端体会PaddleOCR,将其应用到自己的范畴进行图片辨认测验。相同需求咱们在自己电脑上装置如下环境
1.1 装置PaddlePaddle
假如咱们没有根底的Python运转环境,请参阅运转环境准备。
-
您的机器装置的是CUDA9或CUDA10,请运转以下指令装置
python3 -m pip install paddlepaddle-gpu -i https://mirror.baidu.com/pypi/simple
-
您的机器是CPU,请运转以下指令装置
python3 -m pip install paddlepaddle -i https://mirror.baidu.com/pypi/simple
更多的版本需求,请参照飞桨官网装置文档中的说明进行操作。
1.2 装置PaddleOCR whl包
pip install "paddleocr>=2.0.1" # 引荐运用2.0.1+版本
在装置好环境后,为了咱们能够更好的直观体会PaddleOCR辨认作用,咱们能够直接调用PaddleOCR结构供给的接口进行测验,自己帮咱们收拾好了相关代码,咱们能够自行替换图片途径。
from paddleocr import PaddleOCR, draw_ocr
# Paddleocr supports Chinese, English, French, German, Korean and Japanese.
# You can set the parameter `lang` as `ch`, `en`, `fr`, `german`, `korean`, `japan` to switch the language model in order.
ocr = PaddleOCR(
use_angle_cls=True,
lang='en', #挑选语种
use_gpu=False, #是否调用GPU
det_model_dir="/root/.paddleocr/whl/det/en/en_PP-OCRv3_det_infer/", # 检测模型
cls_model_dir="/root/.paddleocr/whl/cls/ch_ppocr_mobile_v2.0_cls_infer/", # 分类模型
rec_model_dir="/root/.paddleocr/whl/rec/en/en_PP-OCRv3_rec_infer/" # 辨认模型
) # need to run only once to download and load model into memory
img_path = './1.jpg' #替换自己的图片途径
result = ocr.ocr(img_path, cls=True)
for line in result:
print(line)
# draw result
from PIL import Image
image = Image.open(img_path).convert('RGB')
boxes = [line[0] for line in result]
txts = [line[1][0] for line in result]
scores = [line[1][1] for line in result]
im_show = draw_ocr(image, boxes, txts, scores, font_path='./fonts/simfang.ttf') # 字体需求准备
im_show = Image.fromarray(im_show)
im_show.save('result.jpg')
七、数据处理及增广合成
7.1 解压数据集
解压练习集与测验集
!cd ~/data/data62842/ && unzip train\_images.zip
!cd ~/data/data62843/ && unzip test\_images.zip
重命名处理
!cd ~/data/data62842/ && mv train\_images ../ && mv train\_label.csv ../
!cd ~/data/data62843/ && mv test\_images ../
查看前十条数据样例
%cd data/data62842
!cat train\_label.csv | head -n 10
2.2数据增广
首先,考虑运用轻量模型会有一定精度丢失,选用经典网络ResNet34。
其次,为了进一步增强辨认作用及模型泛化行,参阅其他项目运用text_render进行数据增广。
最后,运用text_renderer进行数据增广,修正text_render/configs/default.yaml装备,以下为更改后的模版,首要将三项做修正,分别是font_color的enable设为True,img_bg的enable设为False,seamless_clone的enable设为True。
数据增广参阅: 链接
本次数据增广参数装备信息如下:
# Small font_size will make text looks like blured/prydown
font_size:
min: 14
max: 23
# choose Text color range
# color boundary is in R,G,B format
font_color:
enable: True
blue:
fraction: 0.5
l_boundary: [0,0,150]
h_boundary: [60,60,255]
brown:
fraction: 0.5
l_boundary: [139,70,19]
h_boundary: [160,82,43]
# By default, text is drawed by Pillow with (https://stackoverflow.com/questions/43828955/measuring-width-of-text-python-pil)
# If `random_space` is enabled, some text will be drawed char by char with a random space
random_space:
enable: false
fraction: 0.3
min: -0.1 # -0.1 will make chars very close or even overlapped
max: 0.1
# Do remap with sin()
# Currently this process is very slow!
curve:
enable: false
fraction: 0.3
period: 360 # degree, sin 函数的周期
min: 1 # sin 函数的幅值规模
max: 5
# random crop text height
crop:
enable: false
fraction: 0.5
# top and bottom will applied equally
top:
min: 5
max: 10 # in pixel, this value should small than img_height
bottom:
min: 5
max: 10 # in pixel, this value should small than img_height
# Use image in bg_dir as background for text
img_bg:
enable: false
fraction: 0.5
# Not work when random_space applied
text_border:
enable: false
fraction: 0.5
# lighter than word color
light:
enable: true
fraction: 0.5
# darker than word color
dark:
enable: true
fraction: 0.5
# https://docs.opencv.org/3.4/df/da0/group__photo__clone.html#ga2bf426e4c93a6b1f21705513dfeca49d
# https://www.cs.virginia.edu/~connelly/class/2014/comp_photo/proj2/poisson.pdf
# Use opencv seamlessClone() to draw text on background
# For some background image, this will make text image looks more real
seamless_clone:
enable: true
fraction: 0.5
perspective_transform:
max_x: 25
max_y: 25
max_z: 3
blur:
enable: true
fraction: 0.03
# If an image is applied blur, it will not be applied prydown
prydown:
enable: true
fraction: 0.03
max_scale: 1.5 # Image will first resize to 1.5x, and than resize to 1x
noise:
enable: true
fraction: 0.3
gauss:
enable: true
fraction: 0.25
uniform:
enable: true
fraction: 0.25
salt_pepper:
enable: true
fraction: 0.25
poisson:
enable: true
fraction: 0.25
line:
enable: false
fraction: 0.05
random_over:
enable: true
fraction: 0.2
under_line:
enable: false
fraction: 0.2
table_line:
enable: false
fraction: 0.3
middle_line:
enable: false
fraction: 0.3
line_color:
enable: false
black:
fraction: 0.5
l_boundary: [0,0,0]
h_boundary: [64,64,64]
blue:
fraction: 0.5
l_boundary: [0,0,150]
h_boundary: [60,60,255]
# These operates are applied on the final output image,
# so actually it can also be applied in training process as an data augmentation method.
# By default, text is darker than background.
# If `reverse_color` is enabled, some images will have dark background and light text
reverse_color:
enable: false
fraction: 0.5
emboss:
enable: false
fraction: 0.1
sharp:
enable: false
fraction: 0.1
2.3数据预处理
- 读取train.list标签文件,生成图片的信息字典。
- get_aspect_ratio函数设定图片信息(宽、高、比例、最长字符串、类别等信息)。
- 对标签label进行预处理,进行“繁体->简体”、“大写->小写”、“删去空格”、“删去符号”等操作。
import glob
import os
import cv2
def get_aspect_ratio(img_set_dir):
m_width = 0
m_height = 0
width_dict = {}
height_dict = {}
images = glob.glob(img_set_dir+'*.jpg')
for image in images:
img = cv2.imread(image)
width_dict[int(img.shape[1])] = 1 if (int(img.shape[1])) not in width_dict else 1 + width_dict[int(img.shape[1])]
height_dict[int(img.shape[0])] = 1 if (int(img.shape[0])) not in height_dict else 1 + height_dict[int(img.shape[0])]
m_width += img.shape[1]
m_height += img.shape[0]
m_width = m_width/len(images)
m_height = m_height/len(images)
aspect_ratio = m_width/m_height
width_dict = dict(sorted(width_dict.items(), key=lambda item: item[1], reverse=True))
height_dict = dict(sorted(height_dict.items(), key=lambda item: item[1], reverse=True))
return aspect_ratio,m_width,m_height,width_dict,height_dict
aspect_ratio,m_width,m_height,width_dict,height_dict = get_aspect_ratio("/home/aistudio/data/train_images/")
print("aspect ratio is: {}, mean width is: {}, mean height is: {}".format(aspect_ratio,m_width,m_height))
print("Width dict:{}".format(width_dict))
print("Height dict:{}".format(height_dict))
import pandas as pd
def Q2B(s):
"""全角转半角"""
inside_code=ord(s)
if inside_code==0x3000:
inside_code=0x0020
else:
inside_code-=0xfee0
if inside_code<0x0020 or inside_code>0x7e: #转完之后不是半角字符回来本来的字符
return s
return chr(inside_code)
def stringQ2B(s):
"""把字符串全角转半角"""
return "".join([Q2B(c) for c in s])
def is_chinese(s):
"""判别unicode是否是汉字"""
for c in s:
if c < u'\u4e00' or c > u'\u9fa5':
return False
return True
def is_number(s):
"""判别unicode是否是数字"""
for c in s:
if c < u'\u0030' or c > u'\u0039':
return False
return True
def is_alphabet(s):
"""判别unicode是否是英文字母"""
for c in s:
if c < u'\u0061' or c > u'\u007a':
return False
return True
def del_other(s):
"""判别是否非汉字,数字和小写英文"""
res = str()
for c in s:
if not (is_chinese(c) or is_number(c) or is_alphabet(c)):
c = ""
res += c
return res
df = pd.read_csv("/home/aistudio/data/train_label.csv", encoding="gbk")
name, value = list(df.name), list(df.value)
for i, label in enumerate(value):
# 全角转半角
label = stringQ2B(label)
# 大写转小写
label = "".join([c.lower() for c in label])
# 删去所有空格符号
label = del_other(label)
value[i] = label
# 删去标签为""的行
data = zip(name, value)
data = list(filter(lambda c: c[1]!="", list(data)))
# 保存到work目录
with open("/home/aistudio/data/train_label.txt", "w") as f:
for line in data:
f.write(line[0] + "\t" + line[1] + "\n")
# 记录练习集中最长标签
label_max_len = 0
with open("/home/aistudio/data/train_label.txt", "r") as f:
for line in f:
name, label = line.strip().split("\t")
if len(label) > label_max_len:
label_max_len = len(label)
print("label max len: ", label_max_len)
def create_label_list(train_list):
classSet = set()
with open(train_list) as f:
next(f)
for line in f:
img_name, label = line.strip().split("\t")
for e in label:
classSet.add(e)
# 在类的根底上加一个blank
classList = sorted(list(classSet))
with open("/home/aistudio/data/label_list.txt", "w") as f:
for idx, c in enumerate(classList):
f.write("{}\t{}\n".format(c, idx))
# 为数据增广供给词库
with open("/home/aistudio/work/text_renderer/data/chars/ch.txt", "w") as f:
for idx, c in enumerate(classList):
f.write("{}\n".format(c))
return classSet
classSet = create_label_list("/home/aistudio/data/train_label.txt")
print("classify num: ", len(classSet))
这里咱们需求经过上述代码对数据集进行信息计算,设置辨认算法参数,具体计算成果如下:
宽高比等信息:
aspect ratio is: 3.451128333333333, mean width is: 165.65416, mean height is: 48.0
Width dict:{48: 741, 96: 539, 44: 392, 42: 381, 144: 365, 45: 345, 43: 323, 72: 318, 88: 318, 40: 312, 52: 301, 36: 298, 50: 297, 120: 294, 54: 288, 84: 286, 51: 283, 32: 283, 24: 281, 100: 277, 64: 276, 80: 276, 76: 275, 102: 272, 81: 270, 90: 269, 56: 268, 66: 267, 78: 266, 37: 262, 82: 261, 41: 259, 89: 25.....
词典规格:
Height dict:{48: 50000}
最长字符长度:
label max len: 77
类别数:
classify num: 3096
八、模型调整
- 加载官方供给的CRNN预练习模型。
- 改动默许输入图片尺寸,高度height设为48,宽度width设为256。
- 优化学习率战略,经过cosine_decay和warmup战略加速模型收敛。
CRNN模型介绍
本项目模型选用文字辨认经典CRNN模型(CNN+RNN+CTC),其间部分模型代码经过PaddleOCR源码改编,完结辨认模型的建立、练习、评价和猜测进程。练习时能够手动更改config装备文件(数据练习、加载、评价验证等参数),默许选用优化器选用Adam,运用CTC丢失函数。本项目选用ResNet34作为骨干网络。
CRNN网络结构包含三部分,从下到上依次为:
(1)卷积层。作用是从输入图画中提取特征序列。
(2)循环层。作用是猜测从卷积层获取的特征序列的标签(实在值)散布。
(3)转录层。作用是把从循环层获取的标签散布经过去重整合等操作转化成终究的辨认成果。
CRNN网络具体流程:
下载PaddleOCR供给的练习权重
!cd ~/work/PaddleOCR && mkdir pretrain_weights && cd pretrain_weights && wget https://paddleocr.bj.bcebos.com/20-09-22/server/rec/ch_ppocr_server_v1.1_rec_pre.tar
解压练习权重文件
!cd ~/work/PaddleOCR/pretrain_weights && tar -xf ch_ppocr_server_v1.1_rec_pre.tar
PaddleOCR经过将练习参数一致为装备文件进行练习,具体位置在PaddleOCR/configs/rec中,增加练习装备文件 my_rec_ch_train.yml和my_rec_ch_reader.yml
#my_rec_ch_train.yml
Global:
algorithm: CRNN
use_gpu: true
epoch_num: 201
log_smooth_window: 20
print_batch_step: 10
save_model_dir: ./output/my_rec_ch
save_epoch_step: 50
eval_batch_step: 1000
train_batch_size_per_card: 64
test_batch_size_per_card: 64
image_shape: [3, 48, 256]
max_text_length: 80
character_type: ch
character_dict_path: ./ppocr/utils/ppocr_keys_v1.txt
loss_type: ctc
distort: true
use_space_char: true
reader_yml: ./configs/rec/my_rec_ch_reader.yml
pretrain_weights: ./pretrain_weights/ch_ppocr_server_v1.1_rec_pre/best_accuracy
checkpoints:
save_inference_dir:
infer_img:
Architecture:
function: ppocr.modeling.architectures.rec_model,RecModel
Backbone:
function: ppocr.modeling.backbones.rec_resnet_vd,ResNet
layers: 34
Head:
function: ppocr.modeling.heads.rec_ctc_head,CTCPredict
encoder_type: rnn
fc_decay: 0.00004
SeqRNN:
hidden_size: 256
Loss:
function: ppocr.modeling.losses.rec_ctc_loss,CTCLoss
Optimizer:
function: ppocr.optimizer,AdamDecay
base_lr: 0.0001
l2_decay: 0.00004
beta1: 0.9
beta2: 0.999
decay:
function: cosine_decay_warmup
step_each_epoch: 1000
total_epoch: 201
warmup_minibatch: 2000
#my_rec_ch_reader.yml
TrainReader:
reader_function: ppocr.data.rec.dataset_traversal,SimpleReader
num_workers: 1
img_set_dir: /home/aistudio/data/train_images
label_file_path: /home/aistudio/data/train_label.txt
EvalReader:
reader_function: ppocr.data.rec.dataset_traversal,SimpleReader
img_set_dir: /home/aistudio/data/train_images
label_file_path: /home/aistudio/data/train_label.txt
TestReader:
reader_function: ppocr.data.rec.dataset_traversal,SimpleReader
参数解读:
Parameter | Description | Default value |
---|---|---|
use_gpu | 是否启用GPU | TRUE |
gpu_mem | GPU memory size used for initialization | 8000M |
image_dir | The images path or folder path for predicting when used by the command line | |
det_algorithm | 挑选的检测算法类型 | DB |
det_model_dir | 文本检测推理模型文件夹。 参数传递有两种方法:None:主动将内置模型下载到 /root/.paddleocr/det ; 自己转化的推理模型的途径,模型和params文件有必要包含在模型途径中 | None |
det_max_side_len | 图画长边的最大尺寸。 当长边超越这个值时,长边会调整到这个大小,短边会按比例缩放 | 960 |
det_db_thresh | Binarization threshold value of DB output map | 0.3 |
det_db_box_thresh | The threshold value of the DB output box. Boxes score lower than this value will be discarded | 0.5 |
det_db_unclip_ratio | The expanded ratio of DB output box | 2 |
det_east_score_thresh | Binarization threshold value of EAST output map | 0.8 |
det_east_cover_thresh | The threshold value of the EAST output box. Boxes score lower than this value will be discarded | 0.1 |
det_east_nms_thresh | The NMS threshold value of EAST model output box | 0.2 |
rec_algorithm | 挑选的辨认算法类型 | CRNN(卷积循环神经网络) |
rec_model_dir | 文本辨认推理模型文件夹。 参数传递有两种方法:None:主动将内置模型下载到 /root/.paddleocr/rec ; 自己转化的推理模型的途径,模型和params文件有必要包含在模型途径中 | None |
rec_image_shape | 图画形状辨认算法 | “3,32,320” |
rec_batch_num | When performing recognition, the batchsize of forward images | 30 |
max_text_length | 辨认算法能够辨认的最大文本长度 | 25 |
rec_char_dict_path | the alphabet path which needs to be modified to your own path when rec_model_Name use mode 2 | ./ppocr/utils/ppocr_keys_v1.txt |
use_space_char | 是否辨认空格 | TRUE |
drop_score | 按分数过滤输出(来自辨认模型),低于此分数的将不回来 | 0.5 |
use_angle_cls | 是否加载分类模型 | FALSE |
cls_model_dir | 分类推理模型文件夹。 参数传递有两种方法:None:主动下载内置模型到 /root/.paddleocr/cls ; 自己转化的推理模型的途径,模型和params文件有必要包含在模型途径中 | None |
cls_image_shape | 图画形状分类算法 | “3,48,192” |
label_list | label list of classification algorithm | [‘0′,’180’] |
cls_batch_num | When performing classification, the batchsize of forward images | 30 |
enable_mkldnn | 是否启用 mkldnn | FALSE |
use_zero_copy_run | Whether to forward by zero_copy_run | FALSE |
lang | 支撑语言,现在只支撑中文(ch)、English(en)、French(french)、German(german)、Korean(korean)、Japanese(japan) | ch |
det | ppocr.ocr 函数执行时启用检测 | TRUE |
rec | ppocr.ocr func exec 时启用辨认 | TRUE |
cls | Enable classification when ppocr.ocr func exec((Use use_angle_cls in command line mode to control whether to start classification in the forward direction) | FALSE |
show_log | Whether to print log | FALSE |
type | Perform ocr or table structuring, 取值在 [‘ocr’,’structure’] | ocr |
ocr_version | OCR类型版本号,现在模型支撑列表如下:PP-OCRv3支撑中英文检测、辨认、多语言辨认、方向分类器模型;PP-OCRv2支撑中文检测辨认模型;PP-OCR支撑中文检测、辨认 和方向分类器、多语言辨认模型 | PP-OCRv3 |
九、练习与猜测
9.1 练习模型
- 根据修正后的装备文件,输入以下指令就能够开端练习。
!pwd
!cd ~/work/PaddleOCR && python tools/train.py -c configs/rec/my_rec_ch_train.yml
9.2导出模型
经过export_model.py导出模型,设置装备文件及导出途径。
!cd ~/work/PaddleOCR && python tools/export_model.py -c configs/rec/my_rec_ch_train.yml -o Global.checkpoints=./output/my_rec_ch/iter_epoch_27 Global.save_inference_dir=./inference/CRNN_R34
2022-09-30 22:57:53,971-INFO: {'Global': {'debug': False, 'algorithm': 'CRNN', 'use_gpu': True, 'epoch_num': 201, 'log_smooth_window': 20, 'print_batch_step': 10, 'save_model_dir': './output/my_rec_ch', 'save_epoch_step': 3, 'eval_batch_step': 1000, 'train_batch_size_per_card': 64, 'test_batch_size_per_card': 64, 'image_shape': [3, 48, 256], 'max_text_length': 80, 'character_type': 'ch', 'character_dict_path': './ppocr/utils/ppocr_keys_v1.txt', 'loss_type': 'ctc', 'distort': True, 'use_space_char': True, 'reader_yml': './configs/rec/my_rec_ch_reader.yml', 'pretrain_weights': './pretrain_weights/ch_ppocr_server_v1.1_rec_pre/best_accuracy', 'checkpoints': './output/my_rec_ch/iter_epoch_27', 'save_inference_dir': './inference/CRNN_R34', 'infer_img': None}, 'Architecture': {'function': 'ppocr.modeling.architectures.rec_model,RecModel'}, 'Backbone': {'function': 'ppocr.modeling.backbones.rec_resnet_vd,ResNet', 'layers': 34}, 'Head': {'function': 'ppocr.modeling.heads.rec_ctc_head,CTCPredict', 'encoder_type': 'rnn', 'fc_decay': 4e-05, 'SeqRNN': {'hidden_size': 256}}, 'Loss': {'function': 'ppocr.modeling.losses.rec_ctc_loss,CTCLoss'}, 'Optimizer': {'function': 'ppocr.optimizer,AdamDecay', 'base_lr': 0.0001, 'l2_decay': 4e-05, 'beta1': 0.9, 'beta2': 0.999, 'decay': {'function': 'cosine_decay_warmup', 'step_each_epoch': 1000, 'total_epoch': 201, 'warmup_minibatch': 2000}}, 'TrainReader': {'reader_function': 'ppocr.data.rec.dataset_traversal,SimpleReader', 'num_workers': 8, 'img_set_dir': '/home/aistudio/data/train_images', 'label_file_path': '/home/aistudio/data/train_label.txt'}, 'EvalReader': {'reader_function': 'ppocr.data.rec.dataset_traversal,SimpleReader', 'img_set_dir': '/home/aistudio/data/train_images', 'label_file_path': '/home/aistudio/data/train_label.txt'}, 'TestReader': {'reader_function': 'ppocr.data.rec.dataset_traversal,SimpleReader'}}
W0930 22:57:54.222055 22198 device_context.cc:252] Please NOTE: device: 0, CUDA Capability: 70, Driver API Version: 11.2, Runtime API Version: 9.0
W0930 22:57:54.227607 22198 device_context.cc:260] device: 0, cuDNN Version: 7.6.
2022-09-30 22:57:57,220-INFO: Finish initing model from ./output/my_rec_ch/iter_epoch_27
inference model saved in ./inference/CRNN_R34/model and ./inference/CRNN_R34/params
save success, output_name_list: ['decoded_out', 'predicts']
9.3猜测成果
修正模型途径,运转predict.py:
import sys
import os
from paddleocr import PaddleOCR
import numpy as np
import glob
import time
if __name__=='__main__':
# Preference
img_set_dir = os.path.join('..','data','test_images','')
# Load model
use_gpu = True
use_angle_cls = False
det = False
det_model_dir = os.path.join('PaddleOCR','inference','ch_ppocr_mobile_v1.1_det_infer')
cls_model_dir = os.path.join('PaddleOCR','inference','ch_ppocr_mobile_v1.1_cls_infer')
rec_model_dir = os.path.join('PaddleOCR','inference','CRNN_R34')
ocr = PaddleOCR(use_angle_cls=use_angle_cls, lang="ch",use_gpu=use_gpu,use_space_char=False,gpu_mem=4000,
det = det,
rec_image_shape = '3, 48, 256',
rec_algorithm = 'CRNN',
max_text_length = 80,
det_model_dir = det_model_dir,
cls_model_dir = cls_model_dir,
rec_model_dir = rec_model_dir
)
# Load data in a folder
images = glob.glob(img_set_dir+'*.jpg')
log_file_name = time.strftime('%Y-%m-%d-%H-%M-%S', time.localtime())
# Print result to a file
with open(log_file_name+'.txt','w') as fid:
print('new_name\tvalue',file=fid)
#Inference in a folder
for image in images:
result = ocr.ocr(image, cls=use_angle_cls,det=det)
if result is None:
print('Test {} failed.'.format(image.replace(img_set_dir,'')))
continue
for info in result:
pred_label = info[0]
print('{}\t{}'.format(image.replace(img_set_dir,''),pred_label),file=fid)
print("Finished predicting {} images!".format(len(images)))
!pwd
!python ~/work/predict.py
终究成果以txt文件保存,命名格局Y-%m-%d-%H-%M-%S,保存在在/home/aistudio/目录下。
#查看成果 txt文件生成
%cd /home/aistudio/
!cat 2022-09-30-22-58-06.txt | head -n 10
十、总结与后续优化:
1.现在只用resnet网络,后续考虑替换更多轻量级网络测验作用;
2.后续持续对数据进行增强操作或结合更多相关数据集,增加模型的泛化性;
3.持续精调整学习率大小及练习战略调整,提高模型的收敛速度及准确度。
本篇总结: 本篇首要介绍OCR实战项目,以PaddleOCR结构完结计算机视觉中文场景辨认使命,尽可能具体介绍代码及项目流程,如有过错请纠正,后续自己也将介绍更多实战项目,欢迎咱们交流学习。
参阅资料
- PaddleOCR官方教程