건프의 소소한 개발이야기

My Workflow of Supervised Learning - 지도학습의 자세한 나만의 워크플로우 본문

개발 이야기/Machine Learning 이야기

My Workflow of Supervised Learning - 지도학습의 자세한 나만의 워크플로우

건강한프로그래머 2017. 9. 7. 17:27

안녕하세요, 건프입니다.


손글씨 우편번호 데이터셋 MNIST 를 시작으로, Google 의 Tensorflow Open Source Project 에 힘입어, 

모두가 한번쯤은 딥러닝(Deep Learning)을 해보는 시기가 되었는데요.


학교 수업이나 기타 머신러닝 강의들에서 흔히 볼 수 있는 Workflow 과 실제로 프로젝트를 하면서 느꼇던 Workflow 는 조금 큰 차이가 있었습니다.

그간 SWMaestro 과정에서 Object Detection & Tracking 프로젝트를 진행하며 느꼈던 Deep Learning Program Development Workflow 를 제 기준으로 정리해보고자 합니다.


이 길을 함께 걸어가고 있을 누군가에게 도움이 될 수 있기를 바랍니다.


일반적으로 우리가 흔히 볼 수 있는 지도학습(Supervised Learning) 를 나타내는 흐름도는 다음과 같습니다.

적절합니다. 모든 지도학습은 위의 도면에서 크게 벗어나지 않도록 설계를 합니다. 하지만 디테일이 떨어지죠.

학습데이터만 있고 바로 Learning Algorithm 을 적용한다면, 딥러닝을 할 수 있을까요?

그 과정은 실제로 적용해 보았을 때, 생각보다 쉽지 않았습니다.



이것은 제가 나름대로 작성해본, Supervised Learning Project 를 진행할 때, 디테일하게 챙겨야하는 Factor 들입니다.

하나의 큰 프로젝트를 돌리기 위해서는 위의 각각 모듈들을 빠짐없이 잘 작성해야 하더라구요.


이러한 Workflow 에 맞춰서 제가 최근에 공부하고 있는 GAN 학습(Generative Adversarial Networks) for MNIST Generating) 의 코드를 예로 들겠습니다.

Tensorflow 는 MNIST Data set 를 쉽게 받을 수 있는 기능을 제공합니다.

다행이 MNIST 는 구글에서 손수 Labeling 이 된 데이터를 준 것이죠.

만약 X 데이터만 있고, Y labeling 은 없다면?

만드셔야 합니다!


실제로 제가 Object Detection 프로젝트(RapidCheck) 를 할때는 

CCTV 영상에서 "사람" 과 "자동차"를 구분해서 잡아내야 하는데

CCTV 각도(45도 정도 상위각도에서 아래를 내려본 시야) 에서 위 데이터가 Labeling 이 된 데이터는 찾을 수가 없었습니다.

따라서 이것을 손수 Labeling 하는 웹사이트를 직접 구축해서 사용했었죠.

필요하다면, Labeling 도 직접 진행해야 합니다.



그 후, 데이터의 상태를 먼저 확인해야 합니다. 

이미지라면 크기와 차원이 몇으로 되어 있는지, 

몇개의 데이터가 있는지

어떻게 생겼는지 등을 챙겨서 확인해야 합니다.

이미지 데이터의 경우에는 직접 보는게 좋고,

공장데이터와 같이 individual row data 의 경우에는 각 Column 별 Graph 를 그려서 보는 것이 도움이 많이 됩니다.




Neural Networks 를 깊이 쌓아 만드는 Deep Learning 을 적용하기로 마음 먹었다면

네트워크를 구성해야 합니다.

GAN 에서 사용하는 기법에 대해서는 설명하지 않겠습니다. 여기서는 네트워크를 미리 구성한다는 점이 포인트입니다.

이 과정에서 중요한 것은 Batch Size 를 신경써줘야 한다는 것입니다.

Deep Learning 은 그 깊이가 깊어질 수록 연산할 Parameter 의 종류도 많아질 뿐더러, 시간도 오래걸립니다.

따라서 병렬처리를 할 수 있는 한도내에(GPU 메모리가 버티는 한도) 최대한의 Batch Size 를 끌어올려 학습시간을 단축시켜야 합니다.

처음에는 3차원 이미지 -> 4차원 Metrix 로 변환해서 생각하는게 그렇게 쉽지는 않은데

익숙해져야 합니다.



중간단계에서 내가 원하는 대로 동작하는지 확인하는 작업은 필수입니다.

큰 프로그램을 작성할 때, 작은 단위의 Unit Test 를 거치지 않는다면,

이 후 문제가 생겼을 때, 대응 시간이 기하급수적으로 증가하기 때문이죠.



이제는 Training 자체를 위한 Tensorflow 를 구축하는게 포인트입니다.

각각의 generator 와 discriminator 가 리턴하는 결과는 네트워크가 기가막히게 연결되어있는 Tensor 의 Start Point  입니다.

우리는 이 결과물을 Loss Fuction 에 연결하여, 네트워크의 Forward Path 뿐 만 아니라

Backward Path 역시 구축해줄 겁니다.



Loss Function 은 누가 정해준 것이 아닙니다.

그저 내가 하고자 하는 목표에 가장 적합한 Loss Function 을 구축하고, 적용하여, 효과를 보면 되는 것이죠.

물론 사람들이 자주 사용하는 MSE 나 Logistic Loss function 같은 경우에는 Tensorflow 뿐만 아니라 Keras, TFLearn 과 같은 

유용한 라이브러리에서도 제공하기 때문에 적극적으로 이용해주면 되지만,

만약 내가 하고자 하는것이 좀만 더 복잡해도, Custom 하게 작성해야 합니다.

RapidCheck 프로젝트는 제가 직접 Custom Loss Function 을 작성해서 학습시켰습니다.

이 과정에서 Keras 나 TFLearn 과 같은 라이브러리는 자유도가 떨어진다는 단점을 크게 깨달았죠. 


우리가 Row Code 작성을 할 줄 알아야 하는 유일한 이유입니다.




Trainer 의 개념이 생소할 수 있으나,

SGD, ADAM, MOMENTUM 등의 최적화 알고리즘을 말합니다.

Gradient Descents (경사하강법) 의 종류이지만, 각각의 내부동작은 목적에 따라 다릅니다.

자신에게 필요한, 또 효과적인 최적화 알고리즘(Trainer)를 적용하면 됩니다.

일반적으로는 Adam 을 선호하더군요?



이제 학습을 준비합니다.

학습 중에 학습이 잘 되고 있는지 모니터링 하는 것도 굉장히 중요합니다.

딥러닝 학습은 안드로이드 빌드처럼 뚜딱하고 빌드하여 결과를 볼 수 있는 것이 아니니까요 ㅠ_ㅠ

모니터링 하는 방법은 여러가지 방법이 있습니다.

개인적으로는 print 로 loss 값과 그때 그때 prediction 값을 Step 별로 찍어보는 것을 선호합니다.

Tensorflow 의 경우에는 Tensorboard 라는 기능을 제공하기 때문에,

한번 공부해보는 것도 좋을 것 같네요.



이제 비로소 학습을 진행하게 되는 것입니다.

학습을 한뒤에는 일정 체크포인트(CheckPoint) 마다 중간저장 작업을 포함하는 것을 권장합니다.

워낙 프로그램을 오래 돌려야하는 것도 있고,

중간에 memory issue 로 인해서 프로그램이 터지기라도 하면, 

중간 저장 기능이 없었을 때, 눈앞에서 10시간 학습할 결과가 사라지는 경우도 있죠..

저장은 생명입니다.



학습 -> 중간 저장 한 weights 들을 다시 끌어 올려 작업하는 것도 분명 중요한 기능 중 하나입니다.

결과를 사용하기 위해서 이기도 하고

추가학습(continue learning)을 하기 위해서 이기도 하고

전이학습(transfer learning) 을 위해서기도 합니다.


개인적으로 학습 weights 를 save 하고 load 하는 기능은 

keras 와 tflearn 이 훨씬 잘되어 있는 것 같습니다.

둘은 tensorflow low 코드와 거의 호환됩니다. 

참고하시면 좋습니다.



1년 간의 무수한 삽질과 최근 Google Machine Learning Challenge 2017 예선통과 -> 본선진출하여 문제를 풀면서 느꼈던 실질적인 문제들을 정리해보았습니다.

사람들의 기대가 큰 분야인만큼 생각보다 쉽지는 않은 것 같습니다.

누군가에게는 굉장히 뻔한 이야기 였을지 모르지만,

도움이 되었을 누군가를 희망하면서

이만 마치겠습니다.


감사합니다. 

Comments