반응형

 

서론


굉장히 오랜만에 블로그 포스팅을 진행하는 것 같다.

2월부터 ICDAR이라고 하는 Document Analysis and Recognition 학회에서 열리는 Competition을 나가게 되었는데,대회가 끊임없이 무한 연장되면서 거의 2달간을 밤을 지새우며 대회에만 집중했다.

 

Upstage KR이라는 회사 이름을 걸고 대회에 참전하는 대신, 기존에 진행하던 업무들은 잠시 다 내려두고 대회에만 집중할 수 있도록 회사에서 배려해주셨다.

 

Purdue에서 Kaggle로 Pneumonia Detection을 수박 겉핥기식으로 진행했던 경험이 전부였던 내게,굉장히 큰 도전 같은 업무였다.

 

현재 내가 회사에서 맡고 있는 역할은, OCR이라고 하는 글자 읽어주는 AI 모듈중글자를 찾아주는 검출기(Detector), 글자 영역을 읽어서 텍스트로 인식하는 인식기(Recognizer)중 인식기를 담당하고 있다.

 

그러다보니, 자연스럽게 Recognizer의 기술력이 필요한 Task를 찾게 되었고,그렇게 시작된 것이 IHTR이었다.

 

IHTR?


IHTR은 Indic Handwriting Text Recognition의 약자로, 말 그대로 인도어 손글씨 인식 대회이다.

굉장히 당황스러웠던 점은, 대회의 취지가 "인도어 인식"이 아니라 "인도어군 인식" 이었다는 점이다.

 

이게 무슨 뜻이냐면,

인도는 인구가 많은 만큼 언어도 굉장히 다양한데, (비공식적으로 3000개의 언어가 있다고 한다.)

인도어군에서 대표적으로 사용되는 10가지 문자 (Bengali, Devanagari, Gujarati, Gurumukhi, Kannada, Malayalam, Odia, Tamil, Telugu, Urdu 를 모두 인식해야하는 Task였다.

 

https://ilocr.iiit.ac.in/ihtr/task.html

2달간의 사투


대회는 정말 끝도 없이 연장되었고, 처음엔 한 달 정도 에너지를 쏟을 각오로 임했으나 결국 두 달을 풀로 써서야 대회가 마무리되었다. 이런 대회를 제대로 참여해본적은 처음이라 어떻게 시작해야할지도 막막했으나, 회사에 존재하는 케글러분들의 도움을 받아 대회 방향성을 잡을 수 있었다.

 

본 대회에서 좋은 성적을 얻을 수 있었던 이유를 데이터적 관점, 전처리 테크닉, 후처리 테크닉 세가지로 나눠서 기록해보고자 한다.

 

좋은 모델의 기본은 좋은 데이터!


소제목 그대로, 좋은 모델을 만들려면 양질의 데이터가 필요하다.

IHTR 대회는 특이하게도, 대회에서 제공하는 데이터 외의 추가 데이터도 무제한 허용되는 대회였다.

 

이러한 점을 적극 활용하기 위해서 첫번째로는, Kaggle과 각종 Paper에 존재하는 온갖 부류의 Indic Text 데이터셋을 수집했다. 거의 열흘을 데이터 수집에만 몰두한 결과 총 18개의 오픈 데이터를 취득할 수 있었다.

 

그러나 18개의 오픈데이터의 한계점은 명확했다.양이 너무 적었고, Bengali, Devanagari 같이 비교적 많이 쓰이는 문자에 대한 데이터셋은 많이 존재했지만, 본 대회에서 다루는 10가지 언어중 일부는 아예 수집 자체를 못했기 때문이다.

 

그래서 추가적으로, Text Rendering 툴 Pango를 사용하여 그럴듯한 합성 데이터를 찍어내기로 했다.Upstage 내부적으로도 훌륭한 합성 데이터 엔진이 있었지만, Right-to-Left, 글자 4개가 합쳐져서 1개의 글자가 되는 복잡한 인도어의 특성상 기존 영문/국문 합성 데이터 엔진과는 호환이 되지 않는 문제가 있어서 간단하게 Pango라는 CLI 기반 렌더링 라이브러리를 적용하기로 했다.

 

아래 데이터는 실제로 직접 생성한 합성데이터의 예시이다.최대한 렌더링에 사용되는 폰트는 손글씨와 비슷해보이는 폰트를 선택하였고, 배경은 종이 질감 이미지를 구해서 사용하였다.

인도어 합성데이터 예시

위와 같은 합성데이터를 언어별로 100,000장씩 생성하여 학습에 이용하였고, 성능이 크게 개선되었다.

 

 

전처리 테크닉


위와 같이 다양한 데이터를 수집하여 정확도를 끌어올리는 것은 성공하였으나, 그럼에도 불구하고 만족스러운 성능이 나오지는 않았다. 특이한점은 Train Set에서의 정확도는 거의 100%에 loss도 정상적으로 훅훅 줄어드는데, Validation Set에서의 성능이 70% 정도 수준에서 오르지 않고 제자리 걸음이었던 점이다.

 

데이터를 직접 까보니, 아래 그림과 같이 Train Set과 Validation Set의 이미지 형태가 너무 달라서 발생하는 문제라는 것을 깨닫고 아래의 2가지 방법을 시도했다.

왼쪽 그림이 Train Set, 오른쪽 그림이 Validation/Test Set

 

1. 기존 Upstage의 Recognizer가 잘 동작한 이유는, Detector가 이미지 내의 Word 영역을 Tight하게 Crop해주었기 때문이다. 이걸 Rule Base로 잘라보면 어떨까?

 

cv2의 otsu threshold를 이용하여, 아래와 같이 이미지의 Word 영역만 잘라줘서 Train을 진행한 후 정확도가 크게 상승했다.

왼쪽 :  원본 이미지 오른쪽 : Thresholding
최종 Cropped Word Image

2. Train Set의 해상도는 전반적으로 고화질이고,  배경색이 깔끔한 흰색 종이 바탕인 반면, Validation Set은 핸드폰 카메라로 마구 찍은 것 처럼 화질도 좋지 않고, 노이즈도 심한 상태였다. 이를 Neural Style Transfer로 맞춰주면 어떨까?

 

Neural Style Transfer는 Image를 통계적으로 유사하게끔 Augmentation 해주는 모델로, 사람이 직접 Augmentation 파이프라인을 개발할 필요 없이 샘플 이미지만 입력으로 넣어주면, 해당 샘플 이미지와 비슷한 형태로 이미지를 만들어주는 장점이 있다. 이를 활용하여 아래와 같은 결과를 얻을 수 있었다.

 

Train Set과 Validation Set의 색감과 노이즈 차이
왼쪽 : Neural Style Transfer 적용, 오른쪽 : 위에서 언급했던 Cropping 적용

위 두가지 방법론을 적용하여 드디어 정확도 90%대를 달성할 수 있었고, 대회 리더보드 1위를 달성했다.

 

 

후처리 테크닉


위 결과에서 정확도 90%대로 대회 리더보드상으로 압도적인 1위를 하며 방심할 때 즈음,

ICDAR 2021에서 클로바팀을 꺾고 우승을 했던 PERO OCR이라는 강팀이 나타났고,

우리의 1위를 빼앗아갔다.

 

대회 마감 1주일 전이었다.

하지만 우리에게도 아직 남겨둔 카드가 있었다.

 

Kaggle 같은 대회의 꽃, Ensemble이다.

나와 본 대회에 같이 참여했던 동료분은 OCR Recognizer만 회사에서 1년째 담당하고 있으신 상태로, 수많은 대기업 PoC를 진행해오면서 점수를 끌어올리는 방법론에 일가견이 있는 상태였다.

 

인식 Charset 제한, Multilingual로 Pretrain한 후, Single Language 특화 모델로 Fine-tuning등등 PoC로 다져진 모델 찍어내기 능력과 회사의 빵빵한 A100 장비와 AI 플랫폼 클러스터를 활용하여 언어별로 수백개의 Single Model을 만들었고,

 

각각의 모델의 Output을 투표하여 합치는 Weighted Hard Voting 방식으로 정확도 95.775%를 달성, 대회 마지막날 기적적인 역전승에 성공하게 되었다!

 

결과 및 후기


https://ilocr.iiit.ac.in/ihtr/leaderboard.html

 

두 달간 잠도 못자고 열심히 달린 결과 당당히 1위를 달성했고, 

우리 팀 외에도 ICDAR Competition에 참가하신 다른 팀분들도 무려 3팀이나 추가로 1위를 달성하시면서 아래와 같은 뉴스 기사가 쏟아지게 되었다.

 

주니어 AI 개발자로써, Kaggle이나 학회 Competition등에 한번쯤은 참가해서 좋은 성적을 받아보고 싶다는 생각이 있었는데, 모처럼 너무 좋은 기회를 만나서 멋진 경험을 할 수 있었다. 두 달간 사실 회사 매출엔 딱히 도움이 안되는 ICDAR Competition에 100% 집중할 수 있게끔 배려해주신 팀원분들과 리더분께 감사를 표하고 싶다.

 

근데 리더보드가 매일 뒤바뀌는 막판엔 정말 너무 힘들었어서......

당분간은 이런 대회는 피하고 싶다... ㅎㅎㅎㅎ

충분한 회복기를 거친 후에, Kaggle에 도전해보는 걸로!

 

Reference: https://ilocr.iiit.ac.in/ihtr/

반응형
블로그 이미지

Hyunsoo Luke HA

석사를 마치고 현재는 Upstage에서 전문연구요원으로 활동중인 AI 개발자의 삽질 일지입니다! 이해한 내용을 정리하는 용도로 만들었으니, 틀린 내용이 있으면 자유롭게 의견 남겨주세요!

,
반응형


tqdm이 Jupyter notebook에서 Hbox로 보일 때

Progress Bar를 통해 보다 시인성 좋은 반복문을 만들어주는 tqdm은, Jupyter에서 사용될 때에는 별도의 위젯을 설치해주어야 한다. tqdm 내부적으로 Jupyter 환경이면 tqdm_notebook이 실행되기 때문인데 만약 위젯을 설치하지 않은 채로, tqdm을 실행하게 되면 아래와 같이 깨진 형태가 나오게 된다.

 

최신 버전의 jupyter는 기본적으로 해당 위젯을 포함하는 것 같기도 하지만, 버전에 따라 이슈가 발생할 수 있다.

HBox(children=(IntProgress(value=1, bar_style='info', max=1), HTML(value='')))

 

해당 이슈를 해결하기 위해서는 아래와 같은 절차를 거치면 된다.

먼저 ipywidgets를 설치해야한다.

pip install ipywidgets

jupyter nbextension enable --py widgetsnbextension

 

그 후, Jupyter의 FigureWidget을 설치한다.

jupyter labextension install @jupyter-widgets/jupyterlab-manager
반응형
블로그 이미지

Hyunsoo Luke HA

석사를 마치고 현재는 Upstage에서 전문연구요원으로 활동중인 AI 개발자의 삽질 일지입니다! 이해한 내용을 정리하는 용도로 만들었으니, 틀린 내용이 있으면 자유롭게 의견 남겨주세요!

,
반응형


Jupyter Lab / Jupyter Notebook 에서 Token 확인하는 방법

Jupyter Lab과 Jupyter Notebook을 사용하시다보면, 아래와 같은 화면을 수도 없이 자주 보게 될 것이다.

 

생각보다 의외로 많은 분들이 위와 같은 token 입력 창에서 어떻게 토큰을 다시 확인하는지 몰라서,

Jupyter 서버 자체를 껏다가 키는 경우가 종종 있다는 사실을 알게 되어 가볍게 포스팅을 진행한다.

 

Jupyter 관련 프로그램 모두 보고 싶은 경우


jupyter server list

=====Output=====
Currently running servers:
http://{your_IP}/?token={your_token}

대부분 위처럼 server 커맨드를 사용하여 token을 찾을 수 있지만,

다중 GPU가 세팅된 서버에서 jupyter notebook과 jupyter lab이 동시에 켜져 있는 경우가 종종 있다.

(대학원 연구실 등등)

 

이 때, 특정 유형의 서버만 보는 명령어도 존재한다.

 

Jupyter Lab만 보고 싶은 경우


jupyter lab list

=====Output=====
Currently running servers:
http://{your_IP}/?token={your_token}

 

Jupyter Notebook만 보고 싶은 경우


jupyter notebook list

=====Output=====
Currently running servers:
http://{your_IP}/?token={your_token}

 

 

Token= 뒤에 붙어 있는 부분을 복사하여 password or token 입력 박스에 넣고 Log in 버튼을 누르면 된다!

이 때, 유의사항은 접속하는 장비가 달라질 경우, password를 설정했더라도 최초 1회는 token으로 로그인을 해야 한다는 점이다. 만약 invalid credential 에러가 발생할 경우 token으로 로그인을 시도해보자!

반응형
블로그 이미지

Hyunsoo Luke HA

석사를 마치고 현재는 Upstage에서 전문연구요원으로 활동중인 AI 개발자의 삽질 일지입니다! 이해한 내용을 정리하는 용도로 만들었으니, 틀린 내용이 있으면 자유롭게 의견 남겨주세요!

,
반응형


Pushing the Performance Limit of Scene Text Recognizer without Human Annotation

현재 근무하고 있는 OCR Recognizer팀의 Workshop에서 발표했던 논문 리뷰를 블로그 포스팅으로 다시 정리해본다.

해당 논문은 Consistency Regularization(CR)이라고 불리우는 최근 Semi-Supervised Learning(SSL)의 핫한 방법론을 Scene Text Recognition(STR)에 적용한 논문으로, Human Annotation 없이도 이전 SOTA 모델들의 최고정확도를 갱신했다는 점에서 큰 의미가 있다. 본 논문의 저자들은, 일반적으로 STR에서 학습에 사용하는 합성데이터(Synthetic Text)들은 Real Scene Text와 Domain Gap이 커서 정확도에 안좋은 영향을 미치기 때문에 Annotation되어 있지 않은 Real Scene Text 데이터를 학습하는 방법을 제안한다.

 

 

 

Abstract


  • STR은 대부분 fully supervised manner로 학습되기 때문에 어마어마한 양의 labeled data를 필요로 한다.

  • 비록 Synthetic Data의 연구로 인해 STR의 학습이 보다 원활해졌지만, Real-to-Synthetic의 Domain Gap으로 인해 STR의 정확도 상승에 제약이 있다.

  • 본 연구는 Synthetic Data를 사용하여 Supervised Learning을 하는 동시에, 다수의 Unlabeled Real Data를 활용하여 STR의 정확도를 향상시키는 방법을 다룬다.

  • STR은 일종의 Sequence Generation Task이기 때문에, 이를 고려한 Character-Level Consistency Regularization(CCR)을 활용한 STR 프레임워크를 제안한다.

  • 다양한 Case에 대한 실험을 진행한 결과, 기존에 존재하는 STR 모델들에 적용했을 때 성공적으로 정확도를 상승시켰으며, 새로운 SOTA를 달성했다.

  • 본 논문은, STR에 CR을 최초로 적용한 논문이다.

 

Introduction


  • 일반적으로 STR Task는 Fully supervised manner로 학습되지만, Real Labeled Dataset은 어마어마한 Annotation 비용으로 인해서 대부분 Sample수가 그다지 크지 않다.

  • 그렇다보니, 다양한 Text를 특정 background image에 합성해서 만들어낸 합성데이터(Synthetic Data)인 MJSynth와 SynthText와 같은 Open Synthetic Dataset이 주로 학습에 사용되고 있다.

  • 그러나 Synthetic Data와 Real Data는 사람이 보기에도 확연히 그 Visual Feature가 다르고, 이러한 Domain Gap으로 인해 STR은 실제 Test Set에서 어느정도의 성능 하락이 발생하고 있으며, 해당 내용은 아래 논문에서 어느정도 입증되었다. ["What If We Only Use Real Datasets for Scene Text Recognition? Toward Scene Text Recognition With Fewer Labels"]

  • 즉, STR 데이터는 Real Data에 굶주려 있는 상태이며, 이러한 Real Data는 Annotation 비용이 높을 뿐, 데이터 자체는 인터넷에서 크롤링등의 방법을 통해서 손 쉽게 얻어낼 수 있다.

  • 따라서 저자들은, Consistency Regularization이라는 SOTA Semi-supervised Learning(SSL) 방법론을 STR Task에 적용하여 Real Unlabeled Data(RU)를 사용하여 STR 모델들의 성능을 올리는 실험을 진행하였다.

Proposed Method


  • 본 논문에서 제안하는 STR Framework의 전체 구조는 위 그림과 같으며,  CR Architecture를 사용하여 Synthetic Labeled Data와 Real Unlabeled Data 각각에서 정보를 추출하여 학습하는 방식으로 학습을 진행한다.

  • 해당 CR Architecture는 UDA논문["Unsupervised data augmentation for consistency training."]에서 영감을 받아 Supervised Branch와 Unsupervised Branch의 2가지 Branch로 구성되어 있다. 

  • Supervised Branch는 Synthetic Data 활용하여 Supervised Learning을 진행하고, Unsupervised Branch에서는 Unlabeled Real Data를 받아서 Strong Augmentation과 Weak Augmentation을 진행하고 각각의 Input에 대한 Output이 최대한 비슷하게 출력되도록 학습된다.

  • Unsupervised Branch는 BYOL["Bootstrap your own latent: A new approach to self-supervised Learning"]의 논문에서 영감을 받아, 같은 Architecture에 Parameter만 다른, 2개의 모델(Online Model, Target Model)을 사용하여 학습을 진행한다. Online Model는 Supervised Branch에서 학습된 모델과 Parameter를 공유하고, Target Model은 Unsupervised Branch에서 Online Model과 EMA 방식을 활용하여 학습이 진행된다.

  • 저자들은 STR이 Sequence Generation Task라는 점을 고려하여 Character-Level Consistency Regularization(CCR)을 제안한다.

  • 해당 방식의 아이디어는 매우 심플한데, Sequence Generation을 위해 Teacher Forcing을 할 때, Time Step t마다 Target Decoder와 Online Decoder의 Input으로 들어오는 t-1 Step의 output값을 서로 다른 값을 쓰게 되면 Character Alignment에 안좋은 영향을 미치게 학습될 수 있으므로, 무조건 Target Model의 t-1 step의 Output을 t step의 입력으로 받게끔 하는 방식이다.
    ex) "Hello"라는 글자를 읽을 때, Target 모델이 "H"로 읽고 Online 모델이 "T"로 읽었어도, 양쪽 Decoder에는 다음 Step에 무조건 Target 모델의 Output "H"를 입력하도록 하여 Context를 공유하도록 함

  • 또한 저자들은 Synthetic Data와 Real Data의 Domain Gap을 줄일 수 있도록, 위 (6)과 같은 Domain Adaption Loss를 추가하였다.

  • 해당 Loss는 간단히 말하면, Synthetic 모델에서 뽑아낸 Feature Map과 Real 모델에서 뽑아낸 Feature Map의 유사도를 높이게 만들어서 양쪽 데이터에서 최대한 비슷한 추상화된 Feature를 뽑아낼 수 있도록 유도하는 역할을 한다.

Experiments


  • 전반적으로 정확도가 향상된 모습을 보여주었다.

  • Synthetic Data로 만들기 까다로운 Irregular Text에서 정확도가 큰 폭으로 상승하였다.(SVTP 86.4% -> 93.3%)

  • 2.5M의 Data만을 사용한 TRBA-cr이 14.5M의 Synthetic Data를 사용한 TRBA-pr보다 정확도가 1.7% 향상되었다.
    (학습시간은 거의 1/6 수준)

Conclusion


  • 본 논문의 저자들은 Human Annotation이 아예 없이도 Real Scene Data에 대해서 높은 정확도를 가지는 STR Framework를 제안하였다.

  • Synthetic Data와 Real Data의 Gap을 줄여주는 식으로 학습을 유도하기 위해 Domain Adaption Loss, Consistency Loss등을 사용하였다.

  • Synthetic과 비슷한 크기로 구축하는게 현실적으로 불가능한 Labeled Real Data의 한계점을 극복하기 위해 Semi-supervised Learning을 도입하였다.

  • BYOL 논문의 방식에서 영감을 받아 Projection Layer를 추가하여 학습을 안정화하였다.

  • STR이 Sequence Generation Task인 점을 고려하여 Target Model로 Teacher Forcing을 진행하는 Character Level Consistency Regularization 방법론을 제안하였다.

  • OCR Recognizer에 적용해볼 수 있는 Simple하면서도 효과적인 연구가 아닐까 개인적으로 생각된다!
    바쁜 일이 끝나면, 한번 직접 구현해서 실험해볼 예정이다!
반응형
블로그 이미지

Hyunsoo Luke HA

석사를 마치고 현재는 Upstage에서 전문연구요원으로 활동중인 AI 개발자의 삽질 일지입니다! 이해한 내용을 정리하는 용도로 만들었으니, 틀린 내용이 있으면 자유롭게 의견 남겨주세요!

,
반응형


GPU 메모리 비우기, 프로세스 전부 종료하기

pytorch나 tensorflow와 같은 인공지능 프레임워크를 사용하다보면, 중간에 예기치 않게 프로그램이 종료될 때가 있는데, 이 때 문제점이 data_loader의 num_worker 수만큼 발생한 서브프로세스들이 부모 프로세스가 종료되었다는 사실을 인지하지 못하고 계속 작업을 수행하는 경우가 발생한다.

 

즉, 프로그램이 종료되었는데도 불구하고, GPU 메모리는 모두 반환되지 않는 상태가 종종 발생한다.

매우 단순한 해결 방법을 알아보자!

 

해결 방안


for i in $(lsof /dev/nvidia1 | grep python | awk '{print $2}' | sort -u); do kill -9 $i; done

위 명령어를 통해서, nvidia gpu를 점유하고 있는 모든 python 프로세스를 종료시킬 수 있다.

multi-gpu 환경이라면, nvidia1을 nvidia2로 바꾸는 등 인덱스에 맞게 여러번 실행시키면 된다.

 

일반적으로 torch.dist와 같은 multi-gpu training의 경우엔 nvidia1에 해당하는 프로세스만 꺼줘도 모두 정상 반환되는 것을 확인할 수 있었다.

반응형
블로그 이미지

Hyunsoo Luke HA

석사를 마치고 현재는 Upstage에서 전문연구요원으로 활동중인 AI 개발자의 삽질 일지입니다! 이해한 내용을 정리하는 용도로 만들었으니, 틀린 내용이 있으면 자유롭게 의견 남겨주세요!

,
반응형


AttributeError : Can't get attribute '_unpickle_block' on 

<module 'pandas._libs.internals' from ' /internals.cpython-38-x86_64-linux-gnu.so'>

 

에러 메시지


AttributeError: Can't get attribute '_unpickle_block' on <module 'pandas._libs.internals' from ' /internals.cpython-38-x86_64-linux-gnu.so'>

 

에러 발생 지점


model = torch.load('/checkpoint/path')

 

해결법


checkpoint를 생성한 pandas 버전과 현재 읽어오려고 하는 local machine의 pandas의 minor version이 다를 때 발생하는 이슈이다. 

 

필자의 경우, 모델을 학습하는데에 사용했던 pandas는 1.4.1이었고, load 하려는 쪽에 깔려있던 pandas 버전은 1.3.1이었다. 버전을 1.4.1로 Upgrade 후, 문제가 해결되었다!

 

# Use Pip
pip install pandas==1.4.1

# Use Conda
conda install -c conda-forge pandas==1.4.1
반응형
블로그 이미지

Hyunsoo Luke HA

석사를 마치고 현재는 Upstage에서 전문연구요원으로 활동중인 AI 개발자의 삽질 일지입니다! 이해한 내용을 정리하는 용도로 만들었으니, 틀린 내용이 있으면 자유롭게 의견 남겨주세요!

,
반응형


Python JSON 파일 한글 깨짐 해결법

파이썬을 사용하다보면, Dict 형태의 자료형을 json.dump()와 함께 json으로 저장하는 일이 빈번하다.

하지만, JSON 파일을 열어보면 한글이 \u290과 같은 유니코드 형태로 변경되어 있는 경우가 많다.

 

매번 해결하고도, 까먹어서 다시 검색하는 일이 잦아 아예 포스팅을 하기로 결정했다.. ㅋㅋ

해결 방법을 알아보자!

 

문제 상황


import json

json_dict = {
	"file_path" : "/data/project",
    "model_type" : "Recognizer",
    "version" : "V1.1.0",
    "current_status" : "개발"
}

with open("./my.json", "w", encoding="utf-8") as f:
	json.dump(json_dict, f, indent="\t")

# 결과
# {
# 	"file_path" : "/data/project",
#	"model_type" : "Recognizer",
#	"version" : "V1.1.0",
#	"current_status" : "\uac1c\ubc1c"
# }

 

별도의 옵션 없이 json dump를 뜨면 일반적으로 한글은 저렇게 깨져서 유니코드 형태로 출력되게 된다.

이는 기본적으로 json.dump가 ascii만을 다루게끔 설정이 되어 있기 때문인데, 이를 ensure_ascii 라는 flag 형태로 False로 변경할 수 있다.

 

해결 방안


import json

json_dict = {
	"file_path" : "/data/project",
    "model_type" : "Recognizer",
    "version" : "V1.1.0",
    "current_status" : "개발"
}

with open("./my.json", "w", encoding="utf-8") as f:
	json.dump(json_dict, f, indent="\t", ensure_ascii=False)

# 결과
# {
# 	"file_path" : "/data/project",
#	"model_type" : "Recognizer",
#	"version" : "V1.1.0",
#	"current_status" : "개발"
# }

 

반응형
블로그 이미지

Hyunsoo Luke HA

석사를 마치고 현재는 Upstage에서 전문연구요원으로 활동중인 AI 개발자의 삽질 일지입니다! 이해한 내용을 정리하는 용도로 만들었으니, 틀린 내용이 있으면 자유롭게 의견 남겨주세요!

,
반응형


Jupyter Notebook/Lab 에서 파이썬 스크립트를 반복문으로 실행하는 방법

 

필자처럼 ML쪽 업무를 하는 사람이라면, Jupyter Notebook 혹은 Jupyter Lab을 매우매우 자주 활용하게 된다. 

실시간으로 Line by Line 실행 결과를 확인하면서 디버그 하기도 용이하고, ML 모델이 잘 학습되고 있는지 로그 찍어보기도 편리하기 때문이다.

 

하지만 때로는 주피터 노트북 형태의 커널이 아니라, 일종의 서버 인터페이스용으로 주피터를 사용하며 파이썬 스크립트를 주피터 상에서 돌리는 경우도 있다.

 

이 때, 항상 아쉬웠던 점이 특정 인자를 바꿔가면서 다양한 실험을 해보고 싶을 때 !와 함께 사용하는 스크립트 실행으로는 모든 Argument를 하나하나 입력하는 방식으로 작성해놔야 한다는 점이었다. 단순히 반복문과 함께 ! 기능을 사용하여 실행시킬 수도 있지만, 이럴 경우 파이썬 스크립트가 에러가 나서 종료되었을 때, 에러 메시지를 뱉지 않고 다음 스크립트로 넘어가는 현상이 종종 있다.

 

다음과 같은 형태로 에러 걱정 없이 순차적으로 명령어를 수행시킬 수 있다.

아래 예시는 glob을 통해 추출한 다양한 checkpoint 파일에 대해서 inference를 수행하는 예시이다.

 

from glob import glob
from subprocess import check_all

model_list = glob('outputs/models/*.pth')

for m in model_list:
	run_name = m.split('/')[-1][:-4]
    check_call(["python", "evaluate.py", "--checkpoint", "{m}", "--run_name", "{run_name}"])

'''
아래와 같이 실행되는 효과를 지닌다.
python evaluate.py --checkpoint outputs/models/model1.pth --run_name model1
python evaluate.py --checkpoint outputs/models/model2.pth --run_name model2
python evaluate.py --checkpoint outputs/models/model3.pth --run_name model3
'''

 

 

반응형
블로그 이미지

Hyunsoo Luke HA

석사를 마치고 현재는 Upstage에서 전문연구요원으로 활동중인 AI 개발자의 삽질 일지입니다! 이해한 내용을 정리하는 용도로 만들었으니, 틀린 내용이 있으면 자유롭게 의견 남겨주세요!

,
반응형


Python으로 파일 복사 하는 방법

 

특정 디렉터리 안에 있는 모든 jpg 파일을 옮기거나, 머신러닝의 모델 파일들을 추려내거나, 특정 문자열을 포함한 파일만을 추출해서 복사하고 싶을 때, 파이썬을 통해 간편히 파일 복사가 가능하다.

 

import os
from glob import glob
import shutil

# 디렉터리 안에 계층 구조가 2단계 있을 때
jpg_list = glob.glob('target_dir/**/**/*.jpg')
# outputs 디렉터리 안에 있는 .pth만 가져오고 싶을 때
model_list = glob.glob('outputs/*.pth')

# 그 후, 원하는 위치로 복사
dest_list = ['your_target_dir', ..., 'your_target_dir']

for src, dest in zip(model_list, dest_list):
	# makedirs를 exist_ok 플래그와 함께 사용하면 해당 위치에 디렉터리가 없을 경우 생성함
	os.makedirs(os.path.dirname(dest), exist_ok=True)
    shutil.copy(src, dest)

 

위와 같이 glob을 통해서 특정 패턴의 파일 경로들을 추출하고, shutil을 통해서 복사하면 수작업으로 하면 굉장히 오래 걸릴 삽질을 순식간에 마무리 할 수 있다.

또한, 아마도 복사하면서 가장 많이 발생하는 이슈는, 해당 위치에 디렉터리가 존재하지 않을 때 발생하는 cannot find ~ 류의 에러일텐데, 이를 os.makedirs로 미리 만들어주고 사용하면 이슈 없이 활용이 가능하다.

반응형
블로그 이미지

Hyunsoo Luke HA

석사를 마치고 현재는 Upstage에서 전문연구요원으로 활동중인 AI 개발자의 삽질 일지입니다! 이해한 내용을 정리하는 용도로 만들었으니, 틀린 내용이 있으면 자유롭게 의견 남겨주세요!

,
반응형


2021년도는 여러모로 굉장히 바쁜 한 해였다.

석사 막 학년이기도 했고, 전문연구요원 취업을 해야했기 때문이다!

 

2021년을 분기별로 회고해보자면 다음과 같다.

 

1분기 (1월 ~ 3월)

  • 1월부터 운동 본격적으로 시작 (거의 90kg에 육박하는 몸무게에 충격)
    - 미국으로 교환학생 갔다온 뒤, 불어난 몸무게 상태로 딱히 다이어트를 안했음
    - 식습관이 자극적으로 바뀌고, 대학원에서 주로 앉아만 있다보니 몸무게가 계속 늘어남
    - 결국 마의 구간 90을 돌파해버렸다.
    - 심각성 느끼고 다이어트 결심!

  • 석사 연구 주제 선택
    - SW마에스트로에서 하던 DeepFake 관련 연구 추가 진행을 할까?
    - Kaggle에서 아예 새로운 프로젝트를 해볼까?
    - 이제 Vision은 그만 두고, NLP 외주 프로젝트를 해볼까?
    결론 : DeepFake 후속도 하고, 외주 프로젝트도 하자!!!

  • 정보처리기사 + 토익 공부
    - 막학기에 정신없어지기전에, 미리미리 따두자! (1달 집중 공부)
    - 정보처리기사 취득
    - 토익 925점으로 만족하고 Stop

  • Journal of Information Processing System(JIPS) 논문 제출
    - 과거 네이버, 맨텍 해커톤에서 금상을 수상했던 스마트팩토리 프로젝트를 바탕으로 작성한 논문을 제출
    - 구현을 딱히 대단하게 하지는 않아서 그냥 SCOPUS 저널에 제출 (SCI 제출할 정도로 노력을 기울이진 않았음)

  • SW마에스트로 하면서 제출했었던, NVIDIA TensorRT 컨트리뷰션 성공
    - 보낸지 오래되서 까먹었던 PR이 뜬금없이 새벽에 NVIDIA 팀에게 LGTM을 받았을 때의 쾌감이란..!

  • 군대 + 취업의 일반적인 컴공 취업 테크를 탄 동기들을 보며 전문연구요원의 길을 의심
    - 15학번 동기들이 대학원 진학한 친구들 외에는 모두 대기업/네카라쿠배/금융권으로 취업함(한명도 빠짐없이..)
    - 그들의 연봉을 들으며 전문연구요원 평균 연봉과 비교해보면서 자괴감을 느꼈다...

  • 외부 업체와 NLP 외주 계약!
    - 6개월간 Domain Specific BERT를 만들고, 특정 Domain의 문서를 분류, 요약하는 프로젝트
    - 어마어마한 양의 고품질 데이터를 얻었다. (4TB)

 

2분기 (4월 ~ 6월)

  • 성공적인 다이어트 진행
    - 과도하지 않은 식단 조절 (일반식에 밥만 절반 + 군것질, 탄수화물 자제, 닭가슴살 섭취)
    - 꾸준히 걷기 (10000~30000보 천천히 걷더라도 매일 매일 걷기)
    - 다이어트 시작 3개월만에 10kg 감량 달성! (근육량 증가, 체지방만 감소)
    - 바지 사이즈 (36 -> 32)
    - 상의 사이즈 (110 -> 100)
    - 주변에서 살 빠졌다고 격려를 잔뜩 받아 자존감 상승

  • 디파이 투자 개시
    - Defi가 대세라는 것을 알고는 있었지만, 참여를 안하고 있었는데 결국 투자를 감행
    - 제주도 학회 출장 중에 BUNNY 코인 해킹 사건 발생 ㅠㅠ
    - 투자하지 말걸....

  • JIPS 논문 메이저 리비전
    - 리뷰어들이 사실상 내용을 싹 다 갈아엎기를 바랬음
    - 하라면 해야지..... 논문 내용 전체 수정 및 추가 실험 진행
    - LSTM + SVM, OC-SVM 등등 다양한 모델을 통해 기기 Anomaly Detection 진행
    - 해당 내용 추가하여 논문 대거 수정
    - 최종 Accept! 

  • 즐거운 여행들!
    - 고등학교 친구들과 함께 떠난 여수-순천 여행!
    - 5월 광주 학회 출장
    - 5월 제주도 학회 출장
    - 6월 제주도 학회/연구실 워크샵

  • SW마에스트로 장관상 수상
    - 코로나 때문에 밀리고 밀려서 6월이 되어서야 장관상 시상식이 진행됨
    - 정장 풀 세트 사서 처음으로 정장입어봤음

  • 본격적으로 헬스장 등록
    - 홈트의 한계(등운동, 가슴운동 할 게 없음...)를 느끼고 헬스장 등록!

3분기 (7월 ~ 9월)

  • 다이어트 대성공!
    - 식단 조금 느슨하게 가끔씩 치킨도 먹고, 군것질도 함
    - 헬스장 루틴 만들고 습관화 완료
    - 1월대비 -15kg 달성!

  • NLP 외주 프로젝트 본격적으로 진행
    - 데이터가 너무 많아서 웬만한 GPU로는 어림도 없음 => TPU 시도
    - 삽질 무한 반복, 그래도 어마어마하게 성장한 계기
    - Tesla V100 2대로는 1달 가까이 걸리던 학습 시간을 TPU를 사용하여 일주일 정도로 대폭 향상시킴

  • DeepFake 탐지 후속 연구
    - NLP TPU로 학습 돌려놓고 결과 나오는 동안 DeepFake 연구 진행
    - Vision Transformer(ViT)가 굉장히 핫하길래 DeepFake 탐지에 적용시도
    - 정확도 자체는 엄청나게 낮았지만, CNN과 굉장히 다른 양상의 탐지 결과 발견
    - 측면 얼굴, 그림자 진 얼굴, 저화질 영상에서 CNN 대비 매우 높은 Generalization 성능을 확인
    - CNN + ViT를 Weighted Majority Voting Ensemble로 합쳐볼까? => 유의미한 성능 향상 확인 => 논문거리가 됨
    - IEEE Access (SCI Journal) 제출
    - 졸업논문 주제로 삼기로 결정

  • 전문연구요원 취준 시작
    - 자기소개서 작성
    - TOEIC 성적 안보고 OPIC만 보는 기업들이 있어서 100% 무베이스로 OPIC 급하게 신청해서 시험 응시, IM2 취득
    - SW마에스트로 멘토님께서 많은 기업을 알아봐주셨고, 나를 맘에 들어하시는 기업체들 만나서 면접 진행, 2개 기업 합격(근데 만족 X)

4분기 (10월 ~ 12월)

  • NLP 프로젝트 연장
    - 성능에 욕심이 생겨서 혼자서 연구 추가적으로 더 진행 (MLOps 강의 듣고 실험 자동화 진행)
    - 기존 BERT대비 8%이상 증가한 분류 성능과 실제 전문가(사람)을 뛰어넘는 분류 정확도
    - 문서 요약까지 그럴듯하게 구현 성공
    - 성공적으로 프로젝트 마무리

  • 논문 리뷰 및 구현 시작
    - 딥러닝 연구자로써 취준을 하려면 필수인 논문 리뷰와 구현을 시작
    - ResNet, VGG, ResNeXt, Bag of Tricks 등등 다양한 논문 구현 진행

  • DeepFake 논문 Access 까임 ㅠ
    - 너무 SOTA 이긴 것만 강조해서 리뷰어 한 분이 맘에 안들어함. (충분히 납득 가능한 이유였음)
    - 다른 리뷰어분들은 나름 호평해줬는데, 리뷰어 한명이 강하게 반대하면 일단 Reject 당하는 구조인듯...
    - 리뷰 내용 보완 및 실험 추가해서 논문 재작성 -> 논문 퀄리티가 전보다 좋아짐
    - 허접하지만 추가 실험에서 나름대로 유의미한 결과를 보여줬기에 과감하게 CVPR 내보려고 했으나, 제출 기한 3일 지남 : (
    - 취업 후에도 논문 때문에 얽매이기 싫어서 SCI 저널 제출 결정


  • 졸업 논문 준비
    - 미리 써둔 논문이 있었으니, 그냥 그대로 졸업 논문 작성 (언어만 국문으로 바꿔서)
    - 논문 발표 준비

  • 취업 스트레스!
    - 본격적으로 코딩테스트 공부 시작(14일동안 하루 10시간 이상씩 앉아서 알고리즘만 풀음. 연구실 후배 민상이(Tony9402)의 알고리즘 공부용 레포가 큰 도움이 됐음
    - 전문연구요원을 못가면 어떡하지라는 거대한 불안감, 일종의 학벌 컴플렉스(탑티어 논문 실적 빠방한 탑스쿨 졸업생들과의 비교)
    - 하던 운동 다 때려치고 스트레스가 너무 극심해서 폭식증에 가까운 음식 섭취(기껏 힘들게 빼놓고 다시 80kg로 돌아옴 ㅠㅠ)

  • 전문연구요원 최종 합격!
    - Deep Learning 관련해서는 탑티어 회사라고 자부할 수 있는 성킴교수님의 회사 Upstage(업스테이지)에 6단계의 기나긴 전형을 넘고 합류하게 되었음
    - 2주간 알고리즘에 반쯤 미친 연구실 후배(ACM-ICPC 19위)에게 추천받은 문제를 유형별로 다 풀어봄
    - Upstage 알고리즘 코딩 테스트 올솔 성공!
    - ML 코딩 테스트는 4일간 잠을 아예 안자며 다 쏟아부어 실험, 합격!
    - 기술 면접 때는 진행했던 프로젝트들 쭉 설명하는 위주로 진행, 합격!
    - 만족스러운 조건의 오퍼레터를 받고 합류 최종 결정
    - 회고를 달성하는 현재 (2022년 1월)기준 근무중!

 

총평

정말 바쁘게 살았던 한해였다.

다이어트도 꽤나 사람 스트레스 받게 하는데다가, NLP 외주 프로젝트만 해도 꽤 빡셌는데, DeepFake 후속 연구까지 추가로 진행을 했으니....게다가 취준까지...

 

취준 스트레스가 이렇게 큰 줄 몰랐다.물론 운이 좋아서 내가 가장 가고 싶었던 회사에 한 번에 붙어버려서, 취준생의 고충을 논하는 것이 우습게 보일 수도 있겠지만, 정말 머리카락이 막 빠질 정도로 심하게 스트레스에 시달렸다. 그리고 왜 취준생들이 자존감이 낮아지는지 절실하게 체험할 수 있었다. 자꾸만 나보다 우월한 사람과 나 스스로를 비교하며 한 없이 작아졌던 시기인 것 같다. 개인적으로는 인생 최악의 암흑기.

올 한해는 그래도 열심히 살았다고 스스로 인정할 수 있을 것 같다.내년에도 또 내 스스로 한계를 깨부실 수 있는 시간을 가졌으면 좋겠다.

 

근데 너무 아쉬운 점이 한가지 있다면,기껏 열심히 다이어트 해놓고 마지막에 너무 풀어진 게 조금 아쉽다.계속 건강하게 운동하고 그랬으면 -20kg도 충분히 도전해볼 수 있었던 것 같은데...

 

2022 목표!

  • 회사 생활 빠르게 익히고 회사에 기여할 수 있는 직원되자!

  • 다이어트 다시 진행하고 근육 좀 키워보자!

  • 클라이밍, 스키, 스쿼시 등등 다양한 활동 취미를 가져보자!
반응형
블로그 이미지

Hyunsoo Luke HA

석사를 마치고 현재는 Upstage에서 전문연구요원으로 활동중인 AI 개발자의 삽질 일지입니다! 이해한 내용을 정리하는 용도로 만들었으니, 틀린 내용이 있으면 자유롭게 의견 남겨주세요!

,