- 前言
- 一、ai studio平台训练
- 1.1、clone paddocr
- 1.2、安装各种包
- 1.3、准备好数据集
- 1.3.1、导入数据集
- 1.3.2、数据集解压
- 1.3.3、划分训练集和验证集
- 1.4、下载预训练权重并解压
- 1.5、配置文件
- 1.6、train
- 1.7、验证(可省略)
- 1.8、保存测试结果
- 1.9、上传结果,拿到名次
- Reference
这章主要教你从0开始一步步在链接: AIStudio平台上进行训练,这个平台还是很牛的,有很多比赛、项目以及数据集:
这次要打的比赛在这里: AIStudio,是一个入门级的OCR比赛,很适合刚学完RCNN的基础,想实践下的同学。
平台每天会免费给8点算力,折合V100单卡8个小时,全免费的,每个人每天都有8个小时,还是很给力的。
全部代码内容也可在我的 我的项目>中文字符检测比赛 查看。
一、ai studio平台训练 1.1、clone paddocr%cd ~/work !git clone https://gitee.com/paddlepaddle/PaddleOCR.git --depth=11.2、安装各种包
%cd ~/work/PaddleOCR/ %pip install -r requirements.txt1.3、准备好数据集 1.3.1、导入数据集
新建项目的时候就要导入数据集
%cd ~/data/data103285/ !unzip -d /home/aistudio/work/PaddleOCR/data train_images.zip !unzip -d /home/aistudio/work/PaddleOCR/data test_images.zip
再验证一下数据集是否正确:
验证一下label标签:
import pandas as pd
%cd ~
data_label=pd.read_csv('work/PaddleOCR/data/train_label.csv', encoding='gb2312')
data_label.head()
1.3.3、划分训练集和验证集
# 对数据列表文件进行划分
%cd ~/work/PaddleOCR/data/
print(data_label.shape)
train=data_label[:45000]
val=data_label[45000:]
train.to_csv('train.txt',sep='t',header=None,index=None)
val.to_csv('val.txt',sep='t',header=None,index=None)
label文件必须要以t符号间隔,否则会报错的。
最终数据集所有文件:
1.4、下载预训练权重并解压先在paddleocr下新建pre_train文件夹
%cd ~/work/PaddleOCR/pre_train/ !wget https://paddleocr.bj.bcebos.com/dygraph_v2.0/ch/ch_ppocr_server_v2.0_rec_pre.tar !tar -xf ch_ppocr_server_v2.0_rec_pre.tar1.5、配置文件
配置文件解析: 【PaddleOCR入门】二、配置文件说明
r34_vd_none_bilstm_ctc.yaml全部配置:
Global:
use_gpu: True
epoch_num: 50
log_smooth_window: 20
print_batch_step: 1
save_model_dir: ./output/rec/r34_vd_none_bilstm_ctc/
save_epoch_step: 5
# evaluation is run every 2000 iterations
eval_batch_step: [0, 1000]
cal_metric_during_train: True
pretrained_model: ./pre_train/ch_ppocr_server_v2.0_rec_pre/best_accuracy
checkpoints:
save_inference_dir:
use_visualdl: False
infer_img: /home/aistudio/work/PaddleOCR/data/test_images
# for data or label process
character_dict_path: ./ppocr/utils/ppocr_keys_v1.txt
max_text_length: 64
infer_mode: False
use_space_char: True
save_res_path: ./output/rec/predicts_r34_vd_none_bilstm_ctc.txt
Optimizer:
name: Adam
beta1: 0.9
beta2: 0.999
lr:
learning_rate: 0.00001
regularizer:
name: 'L2'
factor: 0
Architecture:
model_type: rec
algorithm: CRNN
Transform:
Backbone:
name: ResNet
layers: 34
Neck:
name: SequenceEncoder
encoder_type: rnn
hidden_size: 256
Head:
name: CTCHead
fc_decay: 0
Loss:
name: CTCLoss
PostProcess:
name: CTCLabelDecode
Metric:
name: RecMetric
main_indicator: acc
Train:
dataset:
name: SimpleDataSet
data_dir: ./data/train_images/
label_file_list: ["./data/train.txt"]
transforms:
- DecodeImage: # load image
img_mode: BGR
channel_first: False
- CTCLabelEncode: # Class handling label
- RecResizeImg:
image_shape: [3, 32, 256]
- KeepKeys:
keep_keys: ['image', 'label', 'length'] # dataloader will return list in this order
loader:
shuffle: True
batch_size_per_card: 196
drop_last: True
num_workers: 8
Eval:
dataset:
name: SimpleDataSet
data_dir: ./data/train_images/
label_file_list: ["./data/val.txt"]
transforms:
- DecodeImage: # load image
img_mode: BGR
channel_first: False
- CTCLabelEncode: # Class handling label
- RecResizeImg:
image_shape: [3, 32, 256]
- KeepKeys:
keep_keys: ['image', 'label', 'length'] # dataloader will return list in this order
loader:
shuffle: False
drop_last: False
batch_size_per_card: 64
num_workers: 4
1.6、train
%cd ~/work/PaddleOCR/ !python tools/train.py -c ./configs/rec/rec_r34_vd_none_bilstm_ctc.yml
如图,正常训练
!python -m paddle.distributed.launch tools/eval.py -c ./configs/rec/rec_r34_vd_none_bilstm_ctc.yml -o Global.checkpoints=./output/rec/r34_vd_none_bilstm_ctc/latest.pdparams1.8、保存测试结果
%cd ~/PaddleOCR/ !python tools/infer_rec.py -c configs/rec/rec_r34_vd_none_bilstm_ctc.yml -o Global.checkpoints=./output/rec/r34_vd_none_bilstm_ctc/latest
修改infer_rec.py
# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import numpy as np
import os
import sys
import json
import re
__dir__ = os.path.dirname(os.path.abspath(__file__))
sys.path.append(__dir__)
sys.path.insert(0, os.path.abspath(os.path.join(__dir__, '..')))
os.environ["FLAGS_allocator_strategy"] = 'auto_growth'
import paddle
from ppocr.data import create_operators, transform
from ppocr.modeling.architectures import build_model
from ppocr.postprocess import build_post_process
from ppocr.utils.save_load import load_model
from ppocr.utils.utility import get_image_file_list
import tools.program as program
def main():
global_config = config['Global']
# build post process
post_process_class = build_post_process(config['PostProcess'],
global_config)
# build model
if hasattr(post_process_class, 'character'):
char_num = len(getattr(post_process_class, 'character'))
if config['Architecture']["algorithm"] in ["Distillation",
]: # distillation model
for key in config['Architecture']["Models"]:
if config['Architecture']['Models'][key]['Head'][
'name'] == 'MultiHead': # for multi head
out_channels_list = {}
if config['PostProcess'][
'name'] == 'DistillationSARLabelDecode':
char_num = char_num - 2
out_channels_list['CTCLabelDecode'] = char_num
out_channels_list['SARLabelDecode'] = char_num + 2
config['Architecture']['Models'][key]['Head'][
'out_channels_list'] = out_channels_list
else:
config['Architecture']["Models"][key]["Head"][
'out_channels'] = char_num
elif config['Architecture']['Head'][
'name'] == 'MultiHead': # for multi head loss
out_channels_list = {}
if config['PostProcess']['name'] == 'SARLabelDecode':
char_num = char_num - 2
out_channels_list['CTCLabelDecode'] = char_num
out_channels_list['SARLabelDecode'] = char_num + 2
config['Architecture']['Head'][
'out_channels_list'] = out_channels_list
else: # base rec model
config['Architecture']["Head"]['out_channels'] = char_num
model = build_model(config['Architecture'])
load_model(config, model)
# create data ops
transforms = []
for op in config['Eval']['dataset']['transforms']:
op_name = list(op)[0]
if 'Label' in op_name:
continue
elif op_name in ['RecResizeImg']:
op[op_name]['infer_mode'] = True
elif op_name == 'KeepKeys':
if config['Architecture']['algorithm'] == "SRN":
op[op_name]['keep_keys'] = [
'image', 'encoder_word_pos', 'gsrm_word_pos',
'gsrm_slf_attn_bias1', 'gsrm_slf_attn_bias2'
]
elif config['Architecture']['algorithm'] == "SAR":
op[op_name]['keep_keys'] = ['image', 'valid_ratio']
else:
op[op_name]['keep_keys'] = ['image']
transforms.append(op)
global_config['infer_mode'] = True
ops = create_operators(transforms, global_config)
save_res_path = config['Global'].get('save_res_path',
"./output/rec/predicts_rec.txt")
if not os.path.exists(os.path.dirname(save_res_path)):
os.makedirs(os.path.dirname(save_res_path))
model.eval()
with open(save_res_path, "w") as fout:
fout.write('new_name' + "t" + 'value' +'n') # 添加列头
# 排序
infer_list = get_image_file_list(config['Global']['infer_img'])
infer_list.sort(key=lambda x: int(re.split('/home/aistudio/work/PaddleOCR/data/test_images/|.jpg', x)[1]))
for file in infer_list:
logger.info("infer_img: {}".format(file))
with open(file, 'rb') as f:
img = f.read()
data = {'image': img}
batch = transform(data, ops)
if config['Architecture']['algorithm'] == "SRN":
encoder_word_pos_list = np.expand_dims(batch[1], axis=0)
gsrm_word_pos_list = np.expand_dims(batch[2], axis=0)
gsrm_slf_attn_bias1_list = np.expand_dims(batch[3], axis=0)
gsrm_slf_attn_bias2_list = np.expand_dims(batch[4], axis=0)
others = [
paddle.to_tensor(encoder_word_pos_list),
paddle.to_tensor(gsrm_word_pos_list),
paddle.to_tensor(gsrm_slf_attn_bias1_list),
paddle.to_tensor(gsrm_slf_attn_bias2_list)
]
if config['Architecture']['algorithm'] == "SAR":
valid_ratio = np.expand_dims(batch[-1], axis=0)
img_metas = [paddle.to_tensor(valid_ratio)]
images = np.expand_dims(batch[0], axis=0)
images = paddle.to_tensor(images)
if config['Architecture']['algorithm'] == "SRN":
preds = model(images, others)
elif config['Architecture']['algorithm'] == "SAR":
preds = model(images, img_metas)
else:
preds = model(images)
post_result = post_process_class(preds)
info = None
if isinstance(post_result, dict):
rec_info = dict()
for key in post_result:
if len(post_result[key][0]) >= 2:
rec_info[key] = {
"label": post_result[key][0][0],
"score": float(post_result[key][0][1]),
}
info = json.dumps(rec_info, ensure_ascii=False)
else:
if len(post_result[0]) >= 2:
info = post_result[0][0] + "t" + str(post_result[0][1])
if info is not None:
logger.info("t result: {}".format(info))
# fout.write(file + "t" + info + "n")
# 格式化输出
fout.write(os.path.basename(file) + "t" + post_result[0][0] +'n')
logger.info("success!")
if __name__ == '__main__':
config, device, logger, vdl_writer = program.preprocess()
main()
在PaddleOCR/output/rec下生成predicts_r34_vd_none_bilstm_ctc.txt文件:
将上一步的txt文件下载下来,上次到这里,2秒钟即可出现排名结果:
这只是一个baseline,后续还有很对可以改进的地方,可以继续提分,下篇再讲吧。
飞桨常规赛:中文场景文字识别 - 12月第3名方案
飞桨常规赛:中文场景文字识别 - 4月第1名方案
【精选项目汇总】中文场景文字识别



