ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • EMNIST 데이터 셋 기반 손글씨 인식기
    Projects 2022. 4. 1. 20:39

    처음이니까 HELLO

     

     배경

     Coursera에서 Machine Learning 강좌를 수료하고 배운 것을 활용하여 실제로 무언가를 만들어보고 싶었다. 그래서 파이썬 , numpy, pandas, scikit-learn 등의 라이브러리를 사용하여 머신 러닝 알고리즘을 구현하는 연습을 하였다. 어느 정도 구현이 익숙해졌을 무렵 머신 러닝계의 Hello World라고 할 수 있는 MNIST 셋을 사용한 프로젝트를 하기로 결심했다. 숫자만 구분하는 것은 뭔가 재미없을 것 (?) 같아서 , EMNIST 셋을 사용하여 알파벳도 구분해 보기로 했다.

     

    생각보다 어렵네?

     계획했던 개발 순서는 다음과 같다.

     

    1. PyQt로 GUI 프로그램을 개발하자.

    2. CNN 신경망 모델을 학습하자.

    3. 학습된 모델로 손글씨를 분류하고 str 데이터로 뽑아내자.

     

     간단해보이는 계획이었지만 , 일은 항상 계획대로 되지 않는 법이다.. 일단 PyQt를 한번도 해보지 않아서 필요한 함수들과 사용법을 익히는데 조금 시간이 걸렸다. C++과 Flutter로 GUI 어플리케이션을 만들어 본 경험이 있어서 금방 익숙해지긴 했다. GUI는 하루만에 만들긴 했는데, 원래 내가 생각했던 구상안에서 자꾸 문제가 발생했다.

     손글씨 캔버스 위의 삼색등 중 노란색 불이 ON이라면 사용자가 글씨를 쓰고 있다는 표시이다. 다 썼다면 깜빡깜빡 두번 점등하고 학습된 모델이 글자 분류 예측을 하여 str 데이터로 변환한 뒤, 초록불이 들어오고 캔버스가 초기화되는 시퀀스였다. 그런데 이 깜빡하는 부분이 꽤나 문제가 되었다. 아직 쓰고 있는데도 초록불로 바뀌거나 , 제대로 깜빡거리지 않거나 쓰는 도중인데도 캔버스를 초기화시키는 등의 버그가 속출했다. 원인은 깜빡거리는 애니메이션에 있다고 보았다. 애니메이션 동작 중에 사용자가 글씨를 다시 쓴다면 애니메이션 도중 인터럽트하여 다시 노란색 등을 점등시키는 로직이 필요했다. 분명히 그런 기능이 있겠지만, 그리고 다른 우회하는 방법도 있겠지만 (ui 스레드를 할당한다거나..) 프로젝트의 메인 목적이 PyQt 프로젝트는 아니고 이 문제로 꽤 시간을 쓰고 있어서 깜빡거리는 기능을 빼기로 결정했다. 

     

     그 다음 신경망 구축 단계로 넘어갔다. 사실 아직 딥러닝과 CNN 모델에 대해 제대로 알고 있지 않기 때문에, 한 Kaggle 에서 코드를 가져와 학습에 사용했다. 이번에는 어떤 식으로 모델 생성하였고 하이퍼 파라미터는 어떻게 튜닝하였는지 알아보는 것에 중점을 두기로 했다. 즉 첫 프로젝트이니 깊은 이해없이 일단 구현과 돌아가는 것에 의의를 두고 성취감과 자신감을 좀 올려보기로 했다 ㅎㅎ 참고한 커널은 이 쪽에 링크를 건다.

     

    링크 : EMNIST Letter Dataset 97.9%:acc & val_acc: 91.78% | Kaggle

     

    EMNIST Letter Dataset 97.9%:acc & val_acc: 91.78%

    Explore and run machine learning code with Kaggle Notebooks | Using data from EMNIST (Extended MNIST)

    www.kaggle.com

     

     여기서도 꽤 문제가 많았다. 우선 개발 환경 구축부터 꽤 애를 먹었다. tensorflow와 cuda 설치는 꽤나 민감해서 버전과 설치 방법을 잘 신경써야 한다. 한번에 gpu를 사용하는 딥러닝 개발 환경에 성공하기 쉽지 않다는데, 나 역시도 몇번 실패를 하였다 ㅎㅎ. 이 과정에서 tensorflow-gpu를 설치해야 한다. keras와 tensorflow의 버전은 맞춰야 한다. conda나 numpy의 버전이 낮으면 코딩에서 문제가 생길 수 있다. 등등의 troubleshooting을 하고 조치법을 배우게 되었다. 개발 환경 구축에 참고한 블로그는 여기.

     

    [Setup] 딥러닝 개발 환경 구축 한방에 끝내기 · TheoryDB

     

    [Setup] 딥러닝 개발 환경 구축 한방에 끝내기

    개요 딥러닝이라는 긴 여정을 위한 첫 단계. 딥러닝 개발 환경 구축을 위한 포스팅입니다. 환경설정으로 인한 시간낭비를 최소화 하고자 대부분의 내용을 총정리합니다. 목차 사전 확인사항 및

    theorydb.github.io

     

     가급적이면 하이퍼 파라미터만 참고하고 기타 구현 부분(전처리, 필요한 함수 정의 등등)은 스스로 하려고 노력했다. 그러다가도 문제가 생기면 결국 다른 코드를 참조하여 짜서 조금 더 실력 향상이 필요한 부분이다..

     

     3단계, 손글씨를 인식하여 분류하는 과정은 정말 예상외였다. 잘 학습된 모델만 있다면 내가 그린 글씨도 테스트 셋과 유사한 정확도가 나올 줄 알았는데.. 전혀 아니었다.

     1이나 l , 0과 O 같이 사람이 봐도 구분하기 힘든 글자들의 정확도가 낮은 것은 이해할 만 하다. 그러나 너무 당연한 글자들의 인식 정확도도 심하게 떨어져서 원인을 찾으려고 시도해보았다.

      손글씨는 EMNIST 데이터 셋과 동일하게 28x28 사이즈이다. 데이터 셋을 유심히 관찰해보니 , EMNIST 셋은 적절하게 데이터가 축소되어 픽셀의 밝기 분포가 균등하다. 즉 글씨의 명암이 존재한다. 반면 내 글씨는 픽셀 값이 0 아니면 255로 저장이 되어 있다. 이것이 문제가 될 수도 있을 것 같아서, 이미지 축소 시 보간법을 바꾸어 보기도 했다. 또 EMNIST 셋은 데이터가 정위치에서 회전 + 색 반전이 적용되어 저장되어 있다. 손글씨도 동일하게 처리해주었다. 이런 과정을 거치지 체감 인식률이 조금 향상되었지만 만족할 정도는 아니었다.

     CNN은 이미지의 특징을 추출하여 분류에 사용한다. 그렇기 때문에 유사한 특성들을 가진 문자들은 조금 어렵지 않을까? 더 다양하고 변형된 이미지 셋을 사용하면 정확률이 더 올라갈 것 같다. 그 외로 글자를 크게 쓴다거나 대문자를 쓰면 인식률이 잘 나오는 등의 경험에 근거한 노하우(?)도 얻었다. 어찌됐건 체감 인식률 60~70% 정도 되는 필기 인식기 프로젝트 완성~

     

    아쉬운 점

    •  딥러닝과 CNN에 대한 깊은 이해없이 코드를 가지고 사용했다. 
    •  좋은 결과가 나오지 않았을 때 명확하게 이유를 설명하기 힘들었다.
    •  결과적으로 만족할 만한 인식률이 나오지 않았다.

     

    앞으로 목표

    •  딥러닝 모델에 대한 근본적인 원리를 공부하고 이해하여 적용하자.
    •  조금 더 현실에서 쓰일 만한 데이터로 프로젝트를 진행하자.
    •  데이터 분석을 통해 인사이트를 도출하고 문제가 발생하면 이유를 명확하게 설명해보자.

     

    혹시 코드를 보고 싶으시다면:

    HappyReni/curvyy: A handwriting classifier based on EMNIST image set (github.com)

     

    GitHub - HappyReni/curvyy: A handwriting classifier based on EMNIST image set

    A handwriting classifier based on EMNIST image set - GitHub - HappyReni/curvyy: A handwriting classifier based on EMNIST image set

    github.com

     

    댓글

Designed by Tistory.