🎁🎁 케라스 창시자에게 배우는 딥러닝 개정2판 5~6장 을 참고하였습니다!
전체적인 머신러닝 워크플로를 정리해봤다. 책을 많이 참고했고 책보다 최대한 재미있게 써보려고 노력했다. 제목 어그로 죄송
맨날 따라치는 실습만 하다가 이 책에서 전체적인 개념과 관점을 배울 수 있었다. 대학 강의처럼 딱딱하지도 않고 훨씬 재밌다. 딥러닝에 관심있다면 위에 책을 한 번 꼭 읽어보길 바란다.
흔히 머신러닝 워크플로에서 데이터 정제가 가장 중요하다고 한다.
하지만 가장 간지나는 일은 모델 개발 아닌가? 그래서 다들 모델 개발 쪽에 공부하는 시간을 많이 투자하는 것 같다. 사실 나도 모델 개발 공부가 가장 전문적이고 재밌어보인다.
재밌는 일만 할 수는 없으니까..
1번에서는 작업 시간의 대부분을 잡아먹는 문제 정의 및 데이터 정제 파트를 이야기한다. 나름 이 파트도 깊게 파고들면 확률적인 데이터 클리닝 방법론이 많다. 물론 여기서는 전체적인 워크플로를 볼 것이기 때문에 깊게 들어가진 않는다.
머신러닝을 쓴다고 항상 문제가 해결되진 않는다. 오히려 전통적인 통계 모델링이 더 효과적일 수 있다. 그렇기에 문제를 자세히 파고들어 룰을 이해하고 가장 적합한 솔루션을 찾아야 한다. 물론 인공지능 성능이 너무 좋아서 대충 때려넣어도 해결될 때가 있지만... 그러면 안된다.
- 입력 데이터는 무엇인가? 무엇을 예측하려고 하는가?
- 이진분류인가? 다중분류인가? 스칼라 회귀인가? 벡터 회귀인가? 이미지 분할? 강화학습?
- 기존 솔루션은 어떤 것이 있을까?
- 고려해야 할 특별한 제약이 있을까? 모델이 엔드-투-엔드로 엄격히 암호화되어 있어 모델을 꼭 사용자의 디바이스에 넣어야 한다든지..
일단 문제를 들어가기 전에 물음표를 계속 던질 필요가 있다. 기획 단계에서 최-대한 꼼꼼하게 해두지 않아서 후반 단계에서 차질이 생기면 일을 다시해야 할 수도 있다.
또 이 문제를 머신러닝으로 풀겠다는 것은
1. 주어진 입력으로 타깃을 예측할 수 있고
2. 데이터가 결과에 대한 충분한 정보를 담고있다고 가정한다.
나는 이걸 제대로 안해서 프로젝트를 통째로 날려먹은 적이 있다...
문제가 뭔지 파헤치면서 작업 특성을 이해하고, 입력과 타깃이 무엇인지 알게되면 데이터를 수집하기 시작한다. 책에서는 '노동집약적인 파트'라고 고급지게 표현했지만 내 표현이 더 적절한 거 같다.
대부분 연구소에서는 이런 일을 막내에게 시키거나 외주를 맡긴다 (그게 나다). 혹시 학교 학부연구생에게 라벨링을 시킨다고 하면, 내가 연구소에 배우러 가는지 일하러 가는지 비율을 진지하게 고민해봐야 한다.
시간은 많이 들겠지만 최대한 편한 라벨링 작업을 하기 위해 개발자들은 고민해야한다. 예를 들어 이미지, 영상에서 바인딩 박스를 어떻게 효율적으로 체크할 수 있을지 고민해보자. 온라인에서 '바인딩 박스 툴'을 다운받아 열심히 수작업으로 할 수도 있다. 하지만 이는 한계가 있으니 바인딩 박스를 만들어주는 인공지능 모델을 따로 만들 수도 있다. 모델이 작업한 박스를 검수만 하면 되니 시간이 훨씬 빨라진다. 간단한 토이 프로젝트일 경우 전자가, 규모가 비교적 큰 프로젝트면 후자가 좋은 선택지일 것이다.
또 라벨링을 누구나 할 수 있는지, 아니면 전문지식이 있는 사람만 할 수 있는지도 고려해야한다. 위의 바인딩 박스는 누구나 할 수 있다. 한편 신약 개발을 위한 유력 시료 판단을 한다고 해보자. 시료 후보군이 1만개가 있고, 하나의 시료를 약으로 만들어 실험해보는데 3시간이 걸린다고 하자. 만약 1만개를 전부 실험해보려면 3만시간이 걸린다. 이 신약 개발 주제로 박사 논문을 쓰다 잘못하면 졸업까지 10년이 걸릴 수도 있다. 그러니 유력 시료를 판단하는 딥러닝 모델이 필요하다. 이 모델에 들어가는 데이터는 시료에 대한 전문 지식일 것이다. 이런 모델은 전문가만 라벨링할 수 있다. 과연 전문 인력을 라벨링에 쓸 정도로 좋은 주제인가? 고민해봐야 한다.
데이터의 실효성은 반드시 고민해야 한다. 온라인에 올라온 음식점 음식 사진들과 내가 찍은 음식 사진은 많이 차이가 난다. 포토샵과 전문성에서 많이 밀린다. 만약 온라인의 전문 사진사가 찍은 사진으로만 모델을 학습시키고, 내 사진으로 예측을 한다면? 못 맞힐 수도 있다. 그러니 실제 예측에 사용될 데이터와 모델 학습 데이터를 최대한 일치시켜야 한다.
마지막으로 '개념 이동(concept dift)'도 주의해야 한다. 2013년에 훈련한 음악 추천 엔진으로 지금 추천을 부탁하면 영 시원찮은 결과가 나올 수 있다. 어휘, 표현, 장르의 트렌드가 시기에 따라 변하기 때문이다. 모델의 데이터도 트렌드에 맞춰야 한다. 지속적인 데이터 수집과 재훈련이 필요하다.
앞서 말했듯 데이터에 대한 이해 없이 대충 모델에 때려넣으면 될거라는 믿음은 가지면 안된다. 모델 훈련에 들어가기 전, 데이터를 탐색하고 시각화하여 예측 능력을 가진 특성이 뭔지 고민해봐야한다. 이를 특성 공학이라고 한다.
- 이미지나 자연어 텍스트는 직접 확인해볼 수 있다.
- 수치는 히스토그램을 그려 범위, 빈도를 확인해볼 수 있다.
- 데이터가 위치 정보를 포함하면 지도에 그려본다.
- 누락된 값을 전처리도 해야한다.
- 분류 작업이라면 각 클래스 별로 데이터의 수가 균등하게 있는지 고민해본다. 만약 하나에만 데이터가 몰려있다면 정확도에 악영향을 준다.
- '타깃 누출'을 확인한다. 타깃에 너무 직접적인 영향을 주는 특성이 섞여있다면 그 특성에만 가중치가 몰릴 수 있다.
그 다음 성공 지표를 선택한다. 정확도, 정밀도, 재현율, 고객 재방문율 등 모델의 목적에 따라 성공 지표가 달라진다. 모델의 단순한 수치 연산 결과를 고수준의 목표로 연결시키려면 논리적인 설명이 뒷받침되어야 한다.
데이터를 신경망에 넣으려면 부동 소수점 데이터로 이루어진 텐서 형태로 변환해줘야 한다. 이 단계를 데이터 벡터화라고 부른다.
이미지 데이터를 그레이스케일 인코딩인 0~255 사이의 정수로 인코딩하거나, 각기 다른 특성들의 범위를 0~1의 확률공간으로 압축시켜버리는 등의 정규화 작업을 할 수 있다. 키(cm)랑 몸무게(kg)로 성별을 맞추는데 값을 정규화 없이 넣으면 비교적 숫자가 높은 키에 편향된 결과가 나올 수 있다.
데이터에 NaN이나 Null 같은 빵꾸가 나있으면 학습이 덜 된다. 평균값, 최빈값, 앞에 값 끌어다 쓰기 등 일반적인 처리 방법부터 통계학적인 방법까지 다양한 처리 방법이 있다.
데이터를 넣고 훈련을 할 때 신경망 가운데 층이 너무 작지도, 너무 크지도 않아야 한다. 적당한 크기를 찾기 위해 작은 모델부터 점점 크기를 키워가며 적당한 신경망을 찾는다. 크기를 기우는 방법은
- 층 추가하기
- 층 크기를 키우기!
가 있다.
또 다른 방법으로 모델 규제와 하이퍼파라미터 튜닝이 있다.
- 다른 구조를 시도해본다. 층을 추가하거나 제거한다.
- 드롭아웃을 추가한다.
- 모델이 작다면 L1 또는 L2규제를 추가한다.
- 최적의 설정을 찾기 위해 하이퍼파라미터를 바꿔서 시도해본다.
- 데이터 큐레이션이나 특성 공학을 시도해본다.
인공지능 모델을 다 만들었다고 끝난게 아니다. 마지막으로 유저님 밥상에 가져다 놔야 한다.
우선 AI를 잘 모르는 사람들에게 내가 만든 AI를 잘 설명해야 한다. 이때 "98% 정확도의 모델입니다"라고 설명하면 비전문가는 반올림해서 100%로 알아듣는다. 이는 자칫 오해를 초래한다. 매일 평균 1만건의 메일 중에서 스팸 메일을 판별하는 모델이 있다면 하루 평균 2천건의 거짓 판별이 나온다. 그러므로 비전문가에게 말할 때는 거짓 음성 비율과 거짓 양성 비율을 정확히 말할 필요가 있다. 책에는 다음과 같은 예시를 들어주었다.
"이런 설정에서는 부정 거래 감지 모델이 5% 거짓 음성 비율과 2.5%의 거짓 양성 비율을 달성합니다. 매일 평균 200건의 유효한 거래가 부정 거래로 표시되어 수동 검토를 위해 전달됩니다. 평균적으로 14개의 부정 거래를 놓치며 266개의 부정 거래를 정확하게 감지합니다."
제품의 환경이 파이썬을 지원하지 않는다면 파이썬이 아닌 다른 방식으로 모델을 배포해야 한다. 여러가지 방법이 있는데 한번 훑어보자.
서버나 클라우드 인스턴스에 텐서플로를 설치하고 REST API로 모델의 예측을 요청하는 방식이다. 요새는 클라우드에서 Docker를 활용해 그 안에 파이썬 코드를 넣는다. Docker 사용법은 내 velog에 나와있으니 확인해보길 바란다..ㅎㅎ
플라스크로 직접 서빙 앱을 만들거나 텐서플로 자체 라이브러리인 텐서플로 서빙을 사용하면 된다. 단, 이 방법을 사용하려면 클라이언트가 서버에 접속 가능해야 하고, 응답 속도 면에서도 고려해야 하며, 데이터가 크게 민감하지 않아야 클라우드로 주고 받을 수 있다. 이런 부분들을 고려해야 한다.
모델을 장치에서 직접 구동해야할 경우 장치 안에 모델을 임베딩해야 한다. 이런 경우 모델을 장치에 들어갈 정도로 작게 최적화해야 한다. 장치의 사양에 따라 다양한 변수가 생길 수 있다.예를 들면, 바다를 가로지르는 배에 자율주행 모델을 심는다면 커다란 컴퓨터 장치를 싣을수 있으니 크기가 상관 없겠지만 드론은 꽤 제약이 있다. 해양에서는 클라우드로 육지의 서버와 통신도 어려우니 드론을 조종하는 장치에서 모든게 처리되어야 한다. 이런 작은 컴퓨터에서도 모델이 돌아갈 수 있도록 Llama2 같은 소형 모델들이 나오는 것이다.
아니면 회사 기밀 문서들을 학습시키는 모델 같은 경우 클라우드로 정보를 주고 받기 어렵다. 이러면 사내 장치로 모델을 돌릴 수 밖에 없다.
로컬에서 모델을 돌리려면 모델을 작게 만드는게 좋다. 최적화를 위해 보통 가중치 가지치기, 가중치 양자화 기법이 사용된다.
- 가중치 가지치기: 드롭아웃처럼 신경망 내의 텐서를 죽인다. 단, 여기서는 랜덤이 아니라 철저하게 필요 없는 텐서를 삭제한다.
- 가중치 양자화: 딥러닝 모델은 부동 소수점(float32) 가중치로 훈련된다. 이를 정수(int8)로 반올림하면 크기가 1/4로 줄어든다.
모델 배포를 마쳤다면 끊임없이 성과 지표를 확인하며 개선 방안을 모색한다. MLOps 직무가 이런 일을 하는 것 같다.
대학생이 이 전 과정을 거칠 수 있는 가장 좋은 방법은 공모전이 아닐까? Kaggle처럼 정제된 데이터로 연습할 수 있는 플랫폼이 있어 얼마나 다행인지 모른다.
공감하며 읽었습니다. 좋은 글 감사드립니다.