- In this repository, we train 'EasyOCR' using '공공행정문서 OCR' dataset from 'AI-Hub'.
- run
source step1_set_environment.sh
- set 'train_easyocr/config_files/config.yaml'
- run
bash step2_run_prepare_dataset_py.sh
- The example of 'step2_run_prepare_dataset_py.sh':
python3 prepare_dataset.py\ --dataset="/data/공공행정문서 OCR"\ # Path to the original dataset directory "공공행정문서 OCR" --unzip\ # Whether to unzip --training\ # Whether to generate training set --validation\ # Whether to generate validation set --evaluation # Whether to generate evaluation set
- run
bash step3_run_train_py.sh
- Reference: Custom recognition models
- run
bash step4_set_finetuned_model.sh
- The example of 'step4_set_finetuned_model.sh':
cp train_easyocr/saved_models/phase4/best_norm_ed.pth ~/.EasyOCR/model/finetuned.pth cp finetuned/finetuned.py ~/.EasyOCR/user_network/finetuned.py cp finetuned/finetuned.yaml ~/.EasyOCR/user_network/finetuned.yaml
- Then the structure of directory '~/.EasyOCR' would be like,
~/.EasyOCR ├── model │ └── finetuned.pth └── user_network ├── finetuned.py └── finetuned.yaml
- run
bash step5_run_evaluate_py.sh
- The example of 'step5_run_evaluate_py.sh':
python3 evaluate.py\ --eval_set="/data/evaluation_set"\ # Path to the evaluation set --baseline\ # Whether to evaluate EasyOCR baseline model --finetuned\ # Whether to evaluate fine-tuned model --cuda # Whether to use GPU
### Environment ###
seed: # Seed
experiment_name: # 'train_easyocr/saved_models'에 생성될 폴더 이름입니다.
### Dataset ###
train_data: # Training set의 디렉토리
val_data: # Validation set의 디렉토리
select_data: # Subdirectory
batch_ratio:
# Modulate the data ratio in the batch.
# For example, when `select_data` is `MJ-ST` and `batch_ratio` is `0.5-0.5`,
# the 50% of the batch is filled with 'MJ' and the other 50% of the batch is filled with 'ST'.
total_data_usage_ratio: # How much ratio of the data to use
train_images: # Number of training images
val_images: # Number of validation images
eval_images: # Number of evaluation images
### Data processing ###
img_height: # Height of input image
img_width: # Width of input image
PAD: # If `True` pad to input images to keep aspect ratio
contrast_adjust: # Adjust contrast
character:
# 예측에 사용할 문자들
# Pre-trained model로서 'korean_g2'를 사용할 것이므로 사용할 문자들을 다음을 참고하여 동일하게 설정합니다. (https://github.com/JaidedAI/EasyOCR/blob/master/easyocr/config.py)
sensitive: # Case sensitivity
batch_max_length: # Maximum length of label
data_filtering_off:
# If `False` filter images containing characters not in `character`
# and whose label is longer than `batch_max_length`
### Training ###
workers: # Same as `num_workers` from `torch.utils.data.DataLoader`
batch_size: # Batch size
n_iter: # Number of iterations
val_period: # Period to run validation
show_number: # How many validation result to show
continue_from:
# Checkpoint from which to continue training
# 첫 학습시에는 'korean_g2' (https://github.com/JaidedAI/EasyOCR/releases/download/v1.3/korean_g2.zip)를 사용합니다.
strict: # If `False` ignore non-matching keys when loading a model from checkpoint
### Optimizer ###
adam: # If `True` use `torch.optim.Adam`, if `False` use `torch.optim.Adadelta`
lr:
rho:
eps:
grad_clip:
### Model ###
Transformation: # `None` or `TPS`
FeatureExtraction: # `VGG`, `RCNN` or `ResNet`
SequenceModeling: # `None` or `BiLSTM`
Prediction: # `CTC` or `Attn`
### VGG ###
freeze_FeatureFxtraction: # If `True` do not update feature extraction parameters
rgb: False # `True` for RGB input image
input_channel: # `1` for grayscale input image, `3` for RGB
output_channel: # Output dimension of featrue extraction result
### BiLSTM ###
freeze_SequenceModeling: # If `True` do not update sequence modeling parameters
hidden_size: # `hidden_size` of `torch.nn.LSTM`
### Prediction ###
new_prediction: False # If `True` dimension of model prediction changes according to checkpoint
### CTC ###
decode: # `greedy` or `beamsearch`
- 전체 데이터셋의 크기가 너무 커서 학습시키기에 어려움이 있으므로 아래 디렉토리 구조에 나타난 데이터만을 대상으로 했습니다.
공공행정문서 OCR ├── Training │ ├── [라벨]train.zip │ ├── [원천]train1.zip │ ├── [원천]train3.zip │ └── [원천]train2.zip └── Validation ├── [라벨]validation.zip └── [원천]validation.zip
- Number of training images: 102,477
- Number of validation images: 11,397
- Categories: '농림.축산지원', '도시개발', '산업진흥', '상.하수도관리', '인.허가', '일반행정', '주민복지', '주민생활지원', '주민자치', '지역문화', '지역환경.산림', '회계.예산'
- 'step2_run_prepare_dataset_py.sh' 실행시
--unzip
을 옵션으로 주면 아래와 같은 디렉토리 구조로 압축을 풉니다.unzipped ├── training │ ├── images │ │ └── ... │ └── labels │ └── ... └── validation ├── images │ └── ... └── labels └── ...
- 아래와 같은 디렉토리 구조로 이미지 패치가 생성됩니다.
- 'step2_run_prepare_dataset_py.sh' 실행시
--training
를 옵션으로 주면 'training' 폴더가,--validation
을 옵션으로 주면 'validation' 폴더가 생성됩니다.training_and_validation_set ├── training │ └── select_data │ ├── images │ │ └── ... │ └── labels.csv └── validation └── select_data ├── images │ └── ... └── labels.csv
- 'train_easyocr/config_files/config.yaml'에서
train_images
와val_images
에 어떤 값을 주느냐에 따라 이미지 패치의 수가 달라지며 제가 사용한 이미지 패치의 수는 다음과 같습니다.- Number of training images: 40,000, image patches: 4,494,278
- Number of validation images: 2,000, image patches: 223,115
- Structure of 'labels.csv':
filename words 5350178-1999-0001-0344_829-262-1003-318.png 김해를 5350178-1999-0001-0344_1022-262-1215-321.png 아름답게 5350178-1999-0001-0344_1231-259-1384-324.png 시민을 5350178-1999-0001-0344_1405-259-1620-324.png 행복하게 ... ... - 일부 좌표가 음수인 경우 0으로 수정했습니다.
- Validation set과 중복되지 않도록 'training_and_validation_set/validation'에서 무작위로 500개의 이미지를 뽑아 Evaluation set으로 선정했습니다.
evaluation_set
├── images
│ └── ...
└── labels
└── ...
- Server specification: AWS EC2 g5.xlarge
- Total number of trainable parameters: 4,015,729
- Total iterations: 약 600,000 (약 1 epoch)
- Total training time: 약 50시간
- Sample of training log ('log_train.txt')
[720000/1400000] Training loss: 0.00818 | Validation loss: 0.09826 | Total 0:21:12 elapsed Current accuracy : 94.938 | Current normalized edit distance: 0.9826 Best accuracy : 94.938 | Best normalized edit distance: 0.9826 -------------------------------------------------------------------------------- Ground Truth | Prediction | Confidence Score & T/F -------------------------------------------------------------------------------- 결 재 | 결재 | 0.4155 False 장 | 장 | 0.9992 True 김해공원 | 김해공원 | 0.9956 True 나. | 나. | 0.7449 True 21 | 21 | 0.9036 True 246 | 246 | 0.5787 True 심사자 | 심사자 | 0.9652 True : | : | 0.9761 True -------------------------------------------------------------------------------- [740000/1400000] Training loss: 0.09315 | Validation loss: 0.09707 | Total 0:54:13 elapsed Current accuracy : 94.940 | Current normalized edit distance: 0.9824 Best accuracy : 94.940 | Best normalized edit distance: 0.9826 -------------------------------------------------------------------------------- Ground Truth | Prediction | Confidence Score & T/F -------------------------------------------------------------------------------- 유지에 | 유지에 | 0.9970 True 개설공사에 | 개설공사에 | 0.9422 True 거성산업 | 거성산업 | 0.8966 True 우리의 | 우리의 | 0.9052 True 및 | 및 | 0.9987 True 않는 | 않는 | 0.9775 True 국공유재산관리담당 | 국공유재산관리담당 | 0.9169 True 사후 | 사후 | 0.9964 True --------------------------------------------------------------------------------
- Text detection에 대해서는 'IoU >= 0.5'인 경우를 True positive로 하는 F1 score를, Text recognition에 대해서는 CER (Character Error Rate)를 사용했습니다.
- 그러나 위와 같이 Text detection과 Text recognition 각각에 대해서 평가하는 방법으로는 End-to-end evaluation을 실현할 수 없습니다. 따라서 'IoU >= 0.5'인 경우에 한해 CER을 측정하여 '1 - CER'로서 계산한 Score를 사용해 True positive, False positive, False negative를 측정했습니다. 이를 바탕으로 F1 score를 계산하여 최종 Metric으로 사용했습니다.
- 즉 완전히 Ground truth를 맞히기 위해서는 'IoU >= 0.5'이 되도록 Text detection을 수행하고 'CER = 0'이 되도록 Text recognition을 수행해야만 합니다. 'CER = 0'이라 하더라도 'IoU < 0.5'라면 예측이 전혀 맞지 않은 것이며 `IoU >= 0.5'라면 CER에 따라서 일종의 부분점수를 받게 됩니다.
- Baseline: 0.369
- Fine-tuned: 0.710
- 92.6% 성능이 향상됐습니다.
- IoU를 기반으로 하는 Metric을 사용하므로 성능을 제대로 측정할 수 없는 상황이 발생할 수 있습니다. (Source: https://arxiv.org/pdf/2006.06244.pdf)
- Split case
- Merged case:
- Missing characters
- Overlapping characters
- '공종행정문서 OCR'의 전체 384.9GB 중 79.4GB (20%)밖에 사용하지 못했습니다. 그 이유는 첫째, 네트워크 속도가 제한되어 있는 상황 하에서 데이터셋을 다운로드 받는 데 매우 많은 시간이 소요되었으며 둘째, 사용 가능한 컴퓨팅 자원의 한계로 학습 중 자꾸 서버가 다운되는 현상이 발생하였기 때문입니다.
- 위와 비슷한 이유로 40,000개의 이미지에 대해서 약 1 epoch밖에 학습시키지 못했습니다.
- CLEval (CLEval: Character-Level Evaluation for Text Detection and Recognition Tasks)
- Not IoU-based evaluation metric.
- 문자 단위로 Text detection and recognition을 평가하므로 좀 더 정교하게 성능 측정이 가능합니다.
- Intersection over Union: GIoU(Generalized Intersection over Union)
- Metric: calculate_mean_ap.py
- EasyOCR training:
- Font: 나눔스퀘어 네오 Regular