신경망 모델 학습하기에 앞서 학습에 필요한 학습데이터 생성 및 변환 등에 대한 내용은 이전 포스트를 참고하기 바란다.
[Development/OCR] - EasyOCR 사용자 모델 학습하기 (1) - 시작하기 전에
[Development/OCR] - EasyOCR 사용자 모델 학습하기 (2) - 학습데이터 생성
[Development/OCR] - EasyOCR 사용자 모델 학습하기 (3) - 학습데이터 변환
3. 모델 학습하기
신경망 모델 학습 단계는 역시 앞서 말한 것과 같이 CLOVA AI에서 제공하는 deep-text-recognition-benchmark라는 오픈소스 프로젝트를 이용할 것이다. 해당 프로젝트와 관련된 자세한 내용은 아래 링크에서 확인하기 바란다.
github.com/clovaai/deep-text-recognition-benchmark
3.1 프로젝트 설치 및 개발환경 구축
다음 명령 구문을 통해 deep-text-recognition-benchmark 프로젝트 소스코드를 내려받고, 프로젝트에서 요구하는 환경을 구축한다.
# 소스코드 내려받기
$ git clone https://github.com/clovaai/deep-text-recognition-benchmark.git
# 개발환경 구축
$ pip3 install torch torchvision
$ pip3 install lmdb pillow nltk natsort
$ pip3 install fire
3.2 학습 준비
신경망 학습에 사용할 학습데이터와 미세조정(Fine tune) 학습에 필요한 이미 학습된 모델 (Pre-trained model)를 준비한다.
3.2.1 학습데이터 준비
이전 포스트를 통해 생성한 1,000개의 학습데이터를 deep-text-recognition-benchmark 프로젝트에서 요구하는 학습데이터 구조로 변환했는데, 그 구조는 다음과 같다.
- 이미지 파일 목록 구조
/data
├── gt.txt
└── /images
# image_[idx].[ext]
├── image_00001.png
├── image_00001.png
├── image_00001.png
└── ...
- 'gt.txt' 파일 구조
# {filename}\t{label}\n
images/image_00001.png abcd
images/image_00002.png efgh
images/image_00003.png ijkl
...
위 학습데이터 변환 과정은 본 포스트 상단의 링크를 참고하기 바란다.
3.2.2 학습데이터를 lmdb 포맷으로 변환하기
이제 다음 명령 구문으로 deep-text-recognition-benchmark 프로젝트에서 실제 학습할 때 사용할 lmdb 포맷으로 변환한다.
# deep-text-recognition-benchmark 프로젝트 root에서 실행
(venv) $ python3 create_lmdb_dataset.py \
--inputPath data/ \
--gtFile data/gt.txt \
--outputPath result/
실행 결과는 다음과 같다.
이제 학습데이터를 준비하는 일련의 과정은 모두 끝났다.
다만, deep-text-recognition-benchmark 프로젝트에서 학습에 사용할 명령 구문을 보면, training, validation의 용도로 학습데이터를 별도로 준비해야 한다. 또 학습 성능 향상을 목적으로, training, validation 용도의 학습데이터는 각각 MJ, ST (이름은 바꿀 수 있음)로 나눠서 데이터를 구축하고, 학습 시 batch_ratio를 두어, 각각 MJ, ST 데이터를 적당한 비율로 학습하는 것으로 보인다.
따라서, 결론적으로 지금까지 학습데이터를 생성한 일련의 과정을 반복해 다음과 같이 총 4개를 준비하면 된다. (만일의 예외상황을 마주하지 않기 위해 deep-text-recognition-benchmark 프로젝트에서 제공하는 명령 구문 그대로 학습하기 위함이다)
/lmdb
|
├── /training
| ├── MJ
| | ├── data.mdb
| | └── lock.mdb
| └── ST
| ├── data.mdb
| └── lock.mdb
|
└── /validation
├── MJ
| ├── data.mdb
| └── lock.mdb
└── ST
├── data.mdb
└── lock.mdb
3.2.3 기존에 이미 학습된 모델 (Pre-Trained Model) 준비
이제 미세조정(Fine tune) 학습을 위해 기초가 되는 학습 모델을 다음의 경로에서 다운로드한다.
github.com/clovaai/deep-text-recognition-benchmark#run-demo-with-pretrained-model
실제 EasyOCR에서 사용하고 있는 기본 모델과 동일한 네트워크 구조('None-VGG-BiLSTM-CTC')를 갖는 Pre-trained Model을 다운로드한다. 다음은 사용 가능한 네트워크 중 여기서 사용할 네트워크를 음영으로 표시했다.
- Transforamtion: None, TPS
- Feature Extraction: VGG, RCNN, ResNet
- Sequence Modeling: None, BiLSTM
- Prediction: CTC, Attn
참고로, deep-text-recognition-benchmark 프로젝트에서 추천하는 Best Accuracy를 갖는 모델의 구조는 'TPS-ResNet-BiLSTM-Attn' 이다.
다운로드한 파일은 다음 경로에 저장한다.
3.2.4 프로젝트 및 모델의 정상 동작 확인
이제 다운로드 받은 모델로 deep-text-recognition-benchmark 프로젝트가 정상 동작하는지 다음 구문을 통해 테스트해 보자.
단, 이제부터는 GPU가 탑재된 데스크탑 환경에서 진행해야 한다. (본 포스트를 작성하는 시점까지는 반드시 GPU가 있어야 학습이 가능한 것으로 보인다)
# 사용할 GPU 설정 (개수가 아니라, GPU 인덱스를 나열한다)
(venv) $ CUDA_VISIBLE_DEVICES = '0,1'
# 프로젝트에 포함된 demo images를 대상으로 테스트
(venv) $ python3 demo.py \
--Transformation None \
--FeatureExtraction VGG \
--SequenceModeling BiLSTM \
--Prediction CTC \
--image_folder demo_image/ \
--saved_model ./models/None-VGG-BiLSTM-CTC.pth
실행한 결과는 다음과 같이 Terminal을 통해 확인할 수 있다.
그리고 deep-text-recognition-benchmark 프로젝트에서 이미 테스트한 'TPS-ResNet-BiLSTM-Attn' 모델과 우리가 사용할 'None-VGG-BiLSTM-CTC' 모델의 결과를 비교해 보면 다음과 같다.
demo images | TPS-ResNet-BiLSTM-Attn | None-VGG-BiLSTM-CTC |
available | available | |
shakeshack | shakeshack | |
london | londen | |
greenstead | greenstead | |
toast | toast | |
merry | merrt | |
underground | underground | |
ronaldo | honaldo | |
bally | balay | |
university | university |
확실히 deep-text-recognition-benchmark 프로젝트에서 추천하는 Best Accuracy를 갖는 'TPS-ResNet-BiLSTM-Attn' 모델인 것을 확인할 수 있었다. (기회가 된다면, 또 다른 모델로 학습하고 EasyOCR에서 사용하는 방법을 작성해 볼까 한다)
3.3 모델 학습하기
이제 학습데이터와 학습에 필요한 Pre-trained Model도 준비가 됐으니, deep-text-recognition-benchmark 프로젝트에서 제공하는 다음의 명령 구문으로 학습을 시작한다.
# EasyOCR에서 사용하는 모델은 'None-VGG-BiLSTM-CTC' 조합이다.
(venv) $ python3 train.py --train_data lmdb/training \
--valid_data lmdb/validation \
--select_data MJ-ST \
--batch_ratio 0.5-0.5 \
--Transformation None \
--FeatureExtraction VGG \
--SequenceModeling BiLSTM \
--Prediction CTC \
--saved_model models/None-VGG-BiLSTM-CTC.pth \
--FT
위 명령 구문에 대해 간략히 설명하자면 다음과 같다.
- --train_data: 학습데이터 중 학습(training)용 데이터 경로
- --valid_data: 학습데이터 중 검증(validation)용 데이터 경로
- --select_data: 학습데이터 중에서 학습에 사용할 데이터 선정
- --batch_ratio: 복수의 학습데이터를 선정한 경우, 각 학습데이터를 사용하는 비율
- --Transformation: 사용할 Transformation 모듈 선택. ['None', 'TPS']
- --FeatureExtraction: 사용할 FeatureExtraction 모듈 선택. ['RCNN', 'ResNet', 'VGG']
- --SequenceModeling: 사용할 SequenceModeling 모듈 선택. ['None', 'BiLSTM']
- --Prediction: 사용할 Prediction 모듈 선택. ['Attn', 'CTC']
- --saved_model: 미세조정 학습을 위한 Pre-trained Model의 저장 위치
- --FT: 미세조정 학습 여부
사실 더 많은 옵션을 제공하는데, 여기선 굳이 전부 다룰 필요는 없으니 여기까지만 설명하겠다.
학습 결과는 /saved_models 폴더에 저장된다. (위 학습 옵션 '--saved_model'과는 무관하다)
저장되는 학습 결과 정보는 다음과 같다.
- best_accuracy.pth / best_norm_ED.pth: 학습된 모델 파일 중 특정 성능 지표를 갖는 선택된 모델 (단, norm_ED는 'Normalized edit distance'의 약자인데, 아직 어떤 지표인지 파악을 못했...)
- iter_xxxxxx.pth: 학습 중간중간 특정 반복 주기에서 학습된 모델을 저장 (코드 상 10만 단위에서 저장)
- log_dataset.txt: 학습에 사용된 데이터셋 정보
- log_train.txt: 학습이 진행되는 동안의 로그 (위 터미널에서 보이는 내용과 동일)
- opt.txt: 학습 명령 구문 실행 시 설정된 학습 옵션 정보
학습은 반드시 끝까지 할 필요가 없으며, 목표로 했던 적당한 수준의 성능을 보일 때 멈추면 된다.
3.4 모델 테스트
이제 학습된 모델을 이용해 학습이 제대로 됐는지 확인해 보자.
역시 마찬가지로, 위에서 사용했던 구문을 그대로 이용한다. 단, 사용할 모델을 새로 학습한 모델('./saved_models/None-VGG-BiLSTM-Seed1111/best_accuracy.pth')로 지정한다.
# 사용할 GPU 설정 (개수가 아니라, GPU 인덱스를 나열한다)
(venv) $ CUDA_VISIBLE_DEVICES = '0,1'
# 프로젝트에 포함된 demo images를 대상으로 테스트
(venv) $ python3 demo.py \
--Transformation None \
--FeatureExtraction VGG \
--SequenceModeling BiLSTM \
--Prediction CTC \
--image_folder demo_image/ \
--saved_model ./saved_models/None-VGG-BiLSTM-CTC-Seed1111/best_accuracy.pth
실행한 결과는 역시 다음과 같이 Terminal을 통해 확인할 수 있으며, 위에서 다운로드한 Pre-trained Model로 테스트한 것과 결과를 비교해 보았다.
또, 동시에 현재 EasyOCR의 영문 인식 성능과도 비교해 보고자 다음과 같이 테스트를 진행했다.
이제 테스트 결과를 모아서 비교해 보자. (대소문자는 맞고 틀리고를 구분하는데 반영하지 않았다)
demo images |
None-VGG-BiLSTM-CTC |
EasyOCR | ||||
Pre-Trained Model | Fine-tuned Model | |||||
Text | Confidence | Text | Confidence | Text | Confidence | |
available | 0.5610 | available | 0.7047 | Available | 0.9141 | |
shakeshack | 0.4792 | shakeshack | 0.3212 | SELL_ SHACK | 0.1573 | |
londen | 0.7947 | londen | 0.6224 | Loner | 0.1865 | |
greenstead | 0.9409 | greenstead | 0.9152 | Greenstead | 1.0000 | |
toast | 0.7408 | toast | 0.9918 | ToasT | 0.1213 | |
merrt | 0.4749 | merry | 0.6181 | MIERRI | 0.2201 | |
underground | 0.6128 | underground | 0.8554 | underground | 0.9478 | |
honaldo | 0.2704 | honaldo | 0.2529 | ON F ALDo |
0.9667 0.3445 0.8859 |
|
balay | 0.0753 | balay | 0.4316 | RALLJ | 0.1566 | |
university | 0.5636 | university | 0.6251 | ONIVERSITY | 0.5832 |
단순히 10개 이미지를 테스트해서 더 낫고 나쁘고를 판단하기는 어렵겠지만, Pre-trained Model에 비해서는 일단 1개를 덜 틀렸으니 학습한 효과가 좀 있다고 볼 수 있지 않을까 싶다. (그 와중에 EasyOCR 자체 모델 사용 성능은 왜 저럴까......)
여하튼, 보다 많은 양질의 학습데이터를 확보해 제대로 학습한다면 이보다 더 좋은 성능을 보일 수 있으리라 생각된다.
이제 다음 포스트에서는 미세조정(Fine tune) 방법을 통해 학습한 모델을 EasyOCR 엔진에서 사용자 모델로 지정, 사용하는 방법을 알아보겠다.
[Development/OCR] - EasyOCR 사용자 모델 학습하기 (5) - 모델 적용 및 테스트
'Development > OCR' 카테고리의 다른 글
EasyOCR 사용자 모델 학습하기 (6) - 한글 학습데이터 생성, 학습 및 테스트 (147) | 2021.06.15 |
---|---|
EasyOCR 사용자 모델 학습하기 (5) - 모델 적용 및 테스트 (9) | 2021.05.27 |
EasyOCR 사용자 모델 학습하기 (3) - 학습데이터 변환 (3) | 2021.05.22 |
EasyOCR 사용자 모델 학습하기 (2) - 학습데이터 생성 (0) | 2021.05.22 |
EasyOCR 사용자 모델 학습하기 (1) - 시작하기 전에 (0) | 2021.05.22 |