DL/Computer Vision

[Computer Vision]DACON 교원 그룹 AI 챌린지 Task : OCR (feat. parseq)

moonzoo 2023. 1. 2. 13:15

1.INTRO

DACON에서 진행한 교원그룹 AI 챌린지

Task : OCR 

평가지표 : Accuracy

처음으로 진행해보는 OCR Task라서 이것저것 찾아보면서 컴피티션을 진행했습니다.

컴피티션을 진행하면서 겪은 시행착오 및 결과를 얻어가는 과정에 대해 이 글에서 작성하도록 하겠습니다.

 

2. State-of-the-Art(SOTA)

scene text recognition task에서 sota를 달성한 parseq를 사용해보기로 결정했습니다. parseq의 논문 리뷰는 다음 글을 참고 해주시면 될 것 같습니다.

 

논문 리뷰 링크

 

3. Parseq

https://github.com/baudm/parseq

 

GitHub - baudm/parseq: Scene Text Recognition with Permuted Autoregressive Sequence Models (ECCV 2022)

Scene Text Recognition with Permuted Autoregressive Sequence Models (ECCV 2022) - GitHub - baudm/parseq: Scene Text Recognition with Permuted Autoregressive Sequence Models (ECCV 2022)

github.com

https://github.com/dilithjay/Sinhala-ParSeq

 

GitHub - dilithjay/Sinhala-ParSeq: Scene Text Recognition with Permuted Autoregressive Sequence Models (ECCV 2022)

Scene Text Recognition with Permuted Autoregressive Sequence Models (ECCV 2022) - GitHub - dilithjay/Sinhala-ParSeq: Scene Text Recognition with Permuted Autoregressive Sequence Models (ECCV 2022)

github.com

 

모델 구현은 위 두개의 깃허브를 참고해서 진행했습니다.

여기선 밑의 깃허브 링크로 진행해보도록 하겠습니다. 사실 거의 차이는 없고 호환성 문제가 생겨서 밑에껄로 사용했을 뿐입니다.

3-1 환경 설정

!git clone https://github.com/dilithjay/Sinhala-ParSeq.git
%cd Sinhala-ParSeq

!pip install -r requirements.txt
!pip install -e .
!pip install torch==1.10.0 torchtext==0.11.0

3-2 LMDB 데이터셋 생성

Parseq 모델에서는 LMDB 데이터셋으로 학습을 진행합니다. LMDB Dataset을 활용하면 im-memory로 학습이 가능해져 빠르다는 장점이 있으며 그 외에도 많은 Repository에서 LMDB Dataset를 활용하기 때문에 변경해서 보관하면 더욱 학습에 용이합니다. 그래서 Parseq 모델에 사용할 LMDB 데이터셋을 생성해보도록 하겠습니다. 

 

3-2-1. CSV 파일 txt파일로 변환

대회에서 파일을 csv 파일로 제공했기 때문에 LMDB 데이터셋으로 변경해주기 위해 txt파일로 변경해줄 필요가 있습니다. 

image_path에 대한 전처리를 진행한 후에 학습용 데이터와 평가용 데이터를 split합니다.

다음으로 to_csv를 활용하여 확장자를 txt파일로 저장하고 구분자를 \t으로 index = False로 텍스트 파일을 생성합니다.

train.txt

3-2-2. LMDB 데이터셋 생성 및 경로 설정

다음과 같이 txt파일을 생성했다면 baudm경로에서 다음과 같이 실행해주면 LMDB 데이터셋이 생성됩니다.

!python tools/create_lmdb_dataset.py source_data/ train.txt data/train/my_name

여기서 source_data는 train이미지의 경로입니다. 자신의 train 이미지가 있는 경로로 설정하면 됩니다.

train.txt는 img_path와 라벨이 들어있는 txt파일로 자신의 txt파일 경로로 설정하시면 됩니다.

마지막으로 data/train/my_name은 output LMDB파일의 생성 경로입니다. train 데이터셋은 data/train/my_name으로. val 데이터셋은 data/val/my_name으로 생성해주시면 됩니다. 여기서 my_name 원하는대로 설정하셔도 무방합니다.

위의 구조로 경로를 설정해주시면 됩니다. 마지막 sin_hw부분은 자신이 원하는 폴더명으로 생성하시면 됩니다.

 

그럼 학습에 사용할 LMDB 데이터셋은 준비가 됐습니다.

 

3-3 한국어 데이터 yml 설정

사실 이 부분이 정말 힘들었던 부분입니다. 구글이나 어디든 검색해보면 알 수 있듯이 이렇다할 한국어 OCR모델이 존재하지 않습니다. Parseq를 사용할 때도 한국어 데이터로 학습을 진행한 예시가 없어 프로젝트를 수행한 지인에게 도움을 청해 겨우 문제를 해결 했습니다.

 

하나씩 yml파일 설정을 진행하도록 하겠습니다.

 

3-3-1. charset.yaml

 

우선 configs -> charset에 들어갑니다. 여러가지 charset가 존재하는데 저희는 한국어 데이터를 학습시켜야 하기 때문에 새로운 yml을 생성해줘야 합니다. github에 현재 공개되어 있는 모델은 IC15, SynthText(ST) 등과 같이 영어 데이터셋으로 학습시키는 것을 기준으로 설명되어 있습니다.

 

 

그래서 train.py 학습 파일을 보면 argument에서 '0123456789abcdefghijklmnopqrstuvwxyz'인 단어들만 학습하도록 character에 설정이 되어 있습니다. 하지만 저희가 학습시키고 싶은 것은 주로 한글이며 추가로 숫자+영어(소문자)+특수문자를 모두 추가해줬습니다. 그리고 korean.yaml이라고 이름을 변경해주고 저장을 하시면 charset은 끝입니다.

 

3-3-2. dataset.yaml

 

다음으로 configs->dataset에 들어갑니다. charset.yml과 유사하게 dataset디렉토리 안에 configs디렉토리가 있습니다. 위에서 지정한 my_name이름으로 yaml 파일을 생성합니다. 기존 파일 중 하나를 복제하고 yaml 파일의 이름과 train_dir속성을 데이터 세트의 이름으로 바꿔주시면 됩니다. 데이터 세트와 이름이 train_dir 굳이 같을 필요는 없지만 이 방법이 더 쉽습니다. 제 경우에는 데이터 세트의 이름이 sin_printed이므로 sin_printed.yaml로 변경해줬습니다.

이렇게 하면 dataset.yaml도 끝입니다.

 

3-3-3. main.yaml

 

마지막으로 configs에 main.yaml만 수정해주면 끝이납니다.

main.yaml (1)

하나씩 수정해보도록 하겠습니다. 우선 앞서 한국어 charset의 이름인 korean으로 변경해줍니다.

다음으로 dataset에 my_name 저의 경우는 sin_printed로 변경해줬습니다.

그리고 너무 길어서 짤렸지만 charset_train 부분에는 charset의 한국어 character을 입력해줍니다. 다음에 charset_test역시 마찬가지로 한국어 character로 변경해주시면 됩니다.

 

main.yaml (2)

다음으로 직접 수정할만한 부분은

batch_size : 메모리 가용성에 따라 설정해주시면 됩니다.

 

img_size : 사용하려는 차원으로 설정 합니다. 모든 이미지는 이 크기로 조정됩니다.

 

이 두 부분을 조금만 건드려도 성능향상에 기여할 수 있다고 지금 글을 쓰면서 생각했습니다. ㅎㅎ

 

root_dir : lmdb 데이터가 저장된 root위치를 지정해주시면 됩니다.

train_dir : 이미 dataset.yaml로 지정해줬지만 한번 더 지정해줬습니다.

 

gpus : 사용하려는 GPU 수로 설정 합니다.

여기서 저는 학교 서버를 사용하고 있어서 multi gpu를 사용하려고 했는데 학교 서버의 경우 pytorch framework에러가 게속나서 에러를 최대한 수정한 후 multi gpu가 아닌 1개의 gpu로 학습을 진행했습니다.

 

https://mz-moonzoo.tistory.com/7

에러 디버깅 글입니다.

 

val_checker_interval : 에포크당 배치 수보다 작은 값으로 설정. 

어차피 큰 값으로 설정 되면 실행이 안되기 때문에 error 코드를 보고 수정해주시면 됩니다.

 

추가로 gpu를 사용하실 분들은 train.py도 수정해주셔야할 필요가 있어서 하나더 추가해보도록 하겠습니다.

 

3-3-4. train.py

 

아무것도 건드리지 않고 train.py를 실행시키면 한국인은 버티지 못할 답답함을 느끼실 수 있습니다. gpu가 있고 없고의 차이가 속도차이가 엄청 납니다...

밑에서 trainer 코드의 acceleratior='cpu'를 acceleratior='gpu'로 변경해주시고 추가로 gpus 갯수로 devices=n 설정해주시면 됩니다. 혹시 몰라서 저는 gpus = config.trainer.get('gpus',1)도 같이 변경해줬습니다.

 

이렇게 설정해주시면 학습준비가 완료 됐습니다.

 

4. 학습

여기까지 잘 설정 했다면 train.py코드를 실행시켜주시면 지금까지 한게 아무것도 아닌것처럼 실행이 됩니다.

!python train.py

multi gpu 쓸 생각에 val_check를 30으로 했더니 너무 많이 나오고.. warning 메시지가 좀 많이 뜨긴 하지만 문제없이 학습이 잘 되고 있습니다. 모델의 inference와 성능 비교는 학습이 모두 완료되고 진행해보도록 하겠습니다.

 

5. Development

위와 같이 학습을 진행해서 test데이터셋 inference을 진행해서 submit을 제출해봤습니다.

 

2023-01-04

 

Problem

pubilic_score 0.72로 베이스라인보다 성능이 향상 됐지만 sota모델을 사용한 것에 비해 성능이 크게 향상되지 않았습니다.

 

TRY

파라미터 튜닝 - 그래서 img_size를 [64,224] main.yaml 파라미터의 remove_whitespace를 true로 설정했습니다

데이터셋 재구축 - 제공된 학습 데이터 중 1글자 샘플들의 단어사전이 학습/테스트 데이터의 모든 글자를 담고 있으므로 학습 데이터로 우선 배치했습니다. 학습 데이터로 우선 배치한 1글자 샘플들과 분할된 2글자 이상의 학습 샘플을 concat하여 최종 학습데이터로 사용하여 학습을 진행했습니다.

 

Next

파라미터 변경과 데이터셋 재구축으로 성능향상이 보인다면 추가로 Data Augementation을 진행할 예정입니다.

큰 변화가 없다면 새로운 모델을 찾아보는 것도 고려하고 있습니다.

 

(2023-01-16 수정) 대회 종료 시점으로 깃허브 업로드 완료했습니다.

https://github.com/moonjoo98/DACON/tree/main/%5BDACON%5D%EA%B5%90%EC%9B%90%20OCR%20%EC%B1%8C%EB%A6%B0%EC%A7%80

 

GitHub - moonjoo98/DACON: 2021~2022년에 참여한 DACON 공모전 정리입니다.

2021~2022년에 참여한 DACON 공모전 정리입니다. Contribute to moonjoo98/DACON development by creating an account on GitHub.

github.com