Skip to content
Atica edited this page Jun 18, 2021 · 35 revisions

P stage 4-OCR 한사랑 개발회 Wiki

이 Wiki는 P stage 4-OCR 수식인식기 프로젝트에 대해서 서술하는 페이지입니다.

[2021-06-18 Fri] Wiki 내용 갱신되었습니다.

[2021-06-17 Thur] Wiki 내용 갱신되었습니다.

[2021-05-27 Thur] Wiki 페이지 개설했습니다.

목차

Github Link

p4-ocr-hansarang

팀원 소개

팀 활동

Git을 활용한 협업

팀원 대부분 협업의 경험이 전무했기 때문에 Pull Request 혹은 Merge에 대해 능숙하지 않았습니다. 하지만 개발자에게 있어 협업은 매우 중요하다고 생각되어 협업 도구로 널리 알려진 Github의 기능을 최대한 활용하여 협업을 원활하게 진행하고자 했습니다. 또한 Git 작성 규칙을 정하고 이에 따르며 효율적으로 Git을 사용하고자 했습니다.

  • discussion

discussion 탭에는 각 팀원이 학습을 하면서 서로 공유하면 좋겠다고 판단되는 정보, 코드 등을 작성하여 올렸습니다.

"

  • issue

issue 탭은 각 팀원이 학습을 진행하면서 발견한 문제점을 작성하여 올렸습니다.

논문 조사 및 정리

text detection 및 text recognition에 관한 배경지식을 얻기위해 여러 논문을 읽고 서로 리뷰하는 시간을 가졌습니다. 리뷰한 논문의 요약본 리스트는 아래와 같습니다.

Data EDA

발견한 문제

일부 token의 data 부족

아래의 그림과 같이 train data에 등장하는 token들 중 빈도수가 가장 적은 50개를 뽑아 그래프로 확인했습니다. 이를 통해 10회 미만으로 등장한 token들에 대한 추가적인 data가 필요하다고 판단했습니다. 사이트를 활용하여 부족한 token들을 포함하는 수식을 train파일에 50개 정도의 data를 추가해주었습니다.

세로로 된 수식이미지

일부 이미지의 경우 세로형태의 수식 이미지가 있음을 발견할 수 있었고 실제 학습할 때 세로 이미지를 잘 인식하지 못하는 결과를 얻었습니다.

이와 관련하여 aspect ratio을 확인해보니 aspect ratio가 최솟값인 이미지인 경우 위와 같이 세로로 세워진 이미지임을 확인할 수 있었습니다. 이와 관련하여 aspect ratio의 분포를 확인한 결과 아래의 그림과 같이 나왔습니다.

수식 이외에 발견되는 요소

일부 이미지의 경우 배경에 선이 그어져 있거나 형광펜 표시가 있거나 특정 위치에 원형 표시를 하는 등 학습과정에서 노이즈(noise)로 작용할 수 있는 요소들을 발견하였습니다.

색칠 형광펜

EDA 결론

EDA를 통해 얻은 결론을 정리하면 아래와 같습니다.

  • data의 수가 적은 token에 대해 외부 data를 추가해주어야 함
  • 세로로 된 이미지를 인식할 수 있는 방법을 고안해야 함
  • 이미지의 노이즈(noise)를 최대한 줄이는 방법을 고안해야 함

Data Augmentation

Resize

EDA를 통해 Aspect Ratio가 평균적으로 4.0에 가깝다는 것을 확인하여 기존 input 이미지의 사이즈 128 X 128에서 100 X 400으로 이미지 크기를 재설정(Resize)하여 dataset을 구성하였습니다.

Rotate

EDA에서 언급한 바와 같이 세로로 된 이미지의 인식률을 높이기 위해서는 이미지를 90도 반시계(혹은 시계) 방향으로 회전시킬 필요가 있었습니다. 저희는 opencv 라이브러리가 제공하는 rotation 함수를 이용해 이미지를 불러와 세로로 긴 이미지를 50% 확률로 시계방향 회전, 50% 확률로 반시계방향으로 회전하도록 dataset을 구성하였습니다.

아래는 rotation를 적용하는 코드의 예시입니다.

def rotate_img(self, img):
    '''
    input : PIL image
    output : rotated image
    '''
    img = np.array(img)
    prob = np.random.rand(1)
    if prob < 0.5:
        img_rotated = cv2.rotate(img, cv2.ROTATE_90_CLOCKWISE)
    else:
        img_rotated = cv2.rotate(img, cv2.ROTATE_90_COUNTERCLOCKWISE)
    return Image.fromarray(img_rotated)

binarization

이진화(binarization)은 이미지의 모든 픽셀을 오로지 흑과 백으로만 표현하는 것을 말합니다. 이진화를 할 때는 gray scale을 적용한 뒤 이진화를 진행합니다.

이진화를 적용할 경우 이미지에서 수식 token을 제외한 나머지 노이즈(noise)를 줄여 학습의 효과를 더 높일 수 있습니다.

Normalization

딥러닝 학습 과정에서 발생할 수 있는 Overfitting 문제를 보완하기 위해 이미지의 각 픽셀 값을 0~1 사이의 값으로 정규화(normalization)시켰습니다.

Model

SATRN

SATRN은 self-attention mechanism을 활용하여 이미지 상의 텍스트에 있는 글자의 two dimensional spatial dependency를 파악해 학습합니다. 결과적으로 임의적으로 배치된 텍스트를 기존 모델보다 잘 인식하고 irregular text 벤치마크에서 기존의 STR 알고리즘들 보다 평균적으로 5.7pp만큼 앞선다고 알려져있습니다.

satrn_overview 그림 1. SATRN 구조 개요

저희는 수식 이미지에서 임의로 배치되어 있는 텍스트가 학습에서 큰 비중을 차지할 것이라 예상했습니다. 그래서 SATRN을 기본 model로 정하면서 구조 변경, optimizer 변경 등 여러 조건들을 변경하면서 다양한 실험을 진행했습니다.

구조 변경

  • locality-aware feedforward layer

    기존 baseline에 구현된 Fully-connected feed forward를 논문에서 제시한 Convolution feed forward로 교체하고 실험을 진행했습니다.

  • Adaptive 2D positional Encoding

    기존 baseline에서 구현된 일반적인 2D positional encoding을 논문에서 제시한 학습가능한 adaptive 2D positional encoding으로 교체하고 실험을 진행했습니다.

    아래의 그림은 ~~~~

  • Backbone

    Encoder의 backbone을 다양한 CNN model을 적용하여 실험을 진행했습니다. 사용한 backbone model은 아래의 리스트와 같습니다.

Mini SATRN

다양한 실험을 빠르게 진행하기 위해 SATRN 의 size를 줄인 뒤 실험을 진행했습니다.

Layer Parameter 수정

  • Decoder Layer 수 증가

    Mini SATRN 실험환경에서 Decoder Layer의 수를 추가할 수록 성능이 향상됨을 확인했습니다.

<img src = "https://user-images.githubusercontent.com/43458619/122513936-0a0f6000-d046-11eb-843a-6dd861c8a678.png", width = "80%">

  • Active Function 교체

    Encoder의 backbone이 ShallowCNN인 실험환경에서 activation function을 ReLU대신 mish를 사용하여 실험을 진행했습니다.

Optimizer

SATRN model에 적용한 optimizer의 종류는 다음과 같습니다.

  • Adam
  • Adadelta
  • AdamW
  • AdamP
  • MADGRAD
  • NAdam

기타 시도

  • Beam search

Beam search는 Greedy search과 함께 많이 사용되는 휴리스틱 방법입니다. 각 step에서 탐색의 영역을 K개의 가장 가능도가 높은 토큰들로 유지하며 다음 단계를 탐색합니다. Beam search는 Beam 개수(K) 만큼 출력값을 도출하여 다양성을 주기 때문에 틀린 답을 내놓더라도 다른 sequence보다 더 알맞는 답을 도출했을거라 유추할 수 있고 이 과정을 통해 최적의 답에 가까워질 수 있습니다. 여기서 K는 사용자가 지정하는 hyper-parameter입니다. K를 크게할 수록 넓은 영역을 탐색해 보다 좋은 target sequence를 생성할 수 있지만, 그만큼 속도가 느려지기 때문에 적절하게 조절하는 것이 중요합니다. 일반적으로 5 또는 10으로 설정한다고 알려져 있습니다.

저희는 수식 인식기 프로젝트에 적합한 Beam search 를 구현하기 위해 token을 뽑을 때 argmax를 사용해 각 step마다 beam size K 만큼 token을 뽑아 최대한 적합한 sequence를 선택하려 시도했습니다.

  • Ensemble

다양한 augmentation을 적용한 model들을 한번에 load하여 soft voting 방식으로 ensemble하려 시도했습니다. 이때 baseline에는 존재하지 않는 torch.nograd로 memory 를 절약하고자 했습니다.

Language Model

Robust Scanner

Robust Scanner는 RobustScanner: Dynamically Enhancing Positional Clues for Robust Text Recognition에서 제안한 모델로, 기존 attention 기반 text recognition model이 임의로 배치된 text 를 잘 인식하지 못한다는 한계점을 보완한다는 점에서 의의가 있습니다.

Demo

간단한 demo를 개발함으로써 저희의 수식인식기 프로젝트가 실제 서비스로 구현될 가능성을 가짐을 보이고자 했습니다. 개발은 steamlit 오픈 소스 프레임워크를 이용하여 웹 프로그래밍을 진행했습니다. 실제 demo 사이트 링크를 통해 이미지를 업로드 하거나 마우스로 수식을 써서 결과를 확인할 수 있습니다.

아래의 사진은 링크를 클릭하면 나오는 첫 화면입니다.

아래의 사진과 같이 하나의 수식 이미지를 업로드한 뒤 도출된 결과를 확인하여 정상적으로 작동함을 확인할 수 있습니다.

Clone this wiki locally