데이터/자료 관리자를 위한 인공 지능 시리즈 (3/4)
2018년이 되면서 이제는 인공 지능이 그리 멀리 있는 것처럼 느껴지기보다는 우리 삶 속에 천천히 알려져 남녀노소 막론하고 어느 정도는 관심이 있어하는 현실인 것 같습니다. 카카오 미니, 네이버 웨이브, 아바존 에코, 구글 홈등 각종 기기에는 인공 지능(AI)이 사람 말을 잘 이해하는지 어느 정도 피부로 느낄 수 있을 정도로 편리한 기능들이 탑재되어 있죠. 여기서 중요한 점은 - 현재 발전하고 있는 인공 지능들은 자료/데이터가 꼭 필요하다는 겁니다. 어느 기기나 서비스도 데이터 없이는 인공 지능의 배움도, 발전도 있을 수 없어요. 데이터는 '클라우드에 있다' 혹은 '내 컴에 자료가 있다'라고 쉽게 치부하려고 해도 실질적으로 뭘 해보려면 데이터를 연결해야 조그마한 결과를 내볼 수가 있습니다. 그래서 4 부분으로 시리즈를 시작했고, 오늘은 데이터를 인공 지능에게 제공하는 데이터 저장소와 딥러닝에 대해 연계해서 다뤄보려 합니다.
- 처음 1부에서는 인공 지능의 역사를 살펴보고, 왜 지금 뜨고 있는지
- 2부에서는 인공 지능, 머신 러닝 (기계 학습), 딥러닝의 차이점에 대해 설명하고
- 오늘 3부에서는 딥러닝 프로젝트에 효과적인 테이터 저장 방법을 알아볼 거고
- 4부에서는 제가 NoSQL 시스템을 딥러닝에 사용하는 설명과 함께 예제를 다루려 합니다.
딥 러닝은 음성 인식, 자연 언어 처리 및 이미지 분류와 같은 영역에서 기존에 특히 어렵고 크게 여겨졌던 문제를 최근에 성공적으로 해결함으로 세계적 관심을 끌었던 기계 학습(machine learning)에 포함된 방식입니다. 딥 러닝은 2부에서 설명한 바와 같이 인간의 뇌가 학습하고 문제를 해결하는 방법을 "느슨하게"모방하는 ANN (artificial neural-network: 인공 신경망)을 개선한 것입니다. 따라서 우선 ANN이 어떻게 작동하는지 먼저 이해하는 것이 중요하겠죠?
ANN은 사람의 두뇌의 신경망 (neural network)와 유사한 방식으로 상호 연결된 시스템입니다.
단순한 수준에서 말하자면, 신경망 속 각 뉴런은 많은 수의 입력 (xi)을 수신하고 입력에 대한 계산을 수행 한 다음 출력을 네트워크의 다른 노드 또는 뉴런으로 보냅니다. 가중치 (wj) 또는 매개 변수는 입력 연결의 강도를 나타내며 양수 또는 음수 일 수 있습니다. 입력에는 연결된 가중치 (x1 w1, x2 w2,..)가 곱해지고 뉴런은 모든 입력의 출력을 더합니다. 마지막 단계는 뉴런이 계산 (또는 활성화 함수를) 수행한다는 것입니다. 정품 인증 기능 (Sigmoid 기능이 널리 사용됨)을 사용하면 단순한 모델이 올바르게 나타내지 않을 수 있는 복잡한 경우에 ANN이 비선형 패턴을 모델링할 수 있습니다.
옆의 표는 뉴런의 여러 개의 층으로 구조된 가장 기본적인 형태의 신경망을 나타내고 있죠. 첫 번째 층을 입력 계층이라고 하며, 여기서 자료 값(x1, x2, x3)이 우선 제공됩니다. 두 번째 층을 숨겨진 (또는 은닉) 계층이라고 합니다. 입력 또는 출력 계층이 아닌 모든 계층은 은닉 계층입니다. 딥러닝은 은닉 계층이 여러 단계로 나뉘어 있고, 특히 XOR경우를 포함하여 계층의 수가 늘어날수록 역전파 (Back-Propagation) 알고리즘의 효과가 줄어드는 문제를 다루도록 무게 값 (weight)의 초기값을 설정하기 용이하도록 만들어진 개념입니다. 일반적으로 3개 이상의 숨겨진 계층을 포함하며, 이미지나 동영상 자료 군을 처리하는 경우처럼 100개 혹은 몇천 개 이상의 숨겨진 계층을 포함하는 경우도 볼 수 있습니다.
여기서 잠시 알파고 대 이세돌의 사례에서 쓰인 강화 학습 (reinforcement learning)을 짧게 설명하는 걸 시도해보겠습니다. (제가 2부를 마칠 때 인간의 뇌가 배우는 방법과 비교한다고 했지만 사실 여느 동물의 뇌가 배우는 방법과도 다른 점은 없습니다) 우선 강화 학습은 경우에 따라서 잘못된 학습이 일어날 경우가 가장 크다고 볼 수 있습니다. '세 살 버릇 여든까지 간다'라는 속담이 기계에 비슷하게 적용되는 거죠.
쉽게 보면, 환경을 해석하는 존재가 환경에 변화를 주는 행위를 하는 존재 (에이전트) 에게 '잘했다' 하면서 긍정적 피드백을 주느냐, 아니면 '그건 아니지' 하면서 부정적 피드백을 주느냐 하는 방식입니다. (물론 해석하는 존재가 환경 자체일 수도 있습니다) 그리고 에이전트는 긍정적 피드백을 받기 위해서 수정을 계속하면서 자료를 더 쌓아나가는 거죠. 그리고 자율주행을 비롯한 강화 학습에 특히 좋은 결과를 내고 있는 문제들에는 현재 많은 투자와 발전이 이루어지고 잇습니다. 하지만 아직도 복잡한 경우, 또한 한 가지 이상의 목표가 가능한 경우 (예: 차 사고는 내지 말아야 한다 vs. 인명 피해를 줄여야 한다)에 좀 더 많은 연구가 필요한 것으로 알고 있습니다.
저 역시 궁금했던 점입니다. 우선 저장되는 데이터의 양이 크고, 정형 (structured) 및 비정형 (unstructured) 데이터를 수집하고 저장할 수 있는 능력이 기본일 것입니다. 몇 가지 나열해볼까요?
딥 러닝에서는 데이터를 세 가지 단계, 즉 입력 (input) 데이터, 교육 (training) 데이터 및 결과 (output) 데이터로 볼 수 있고, 이 관계는 지속적이어야만 합니다. 또한 딥 러닝에서는 일반적으로 중요한 실험을 반복적으로 새로운 데이터로 학습시킨다는 것이 중요하고요. 예를 들어, 실험 (R&D)를 하는 동안 여러 상황이 발생하고, 변화를 거듭할 수밖에 없죠 - 비정형 데이터가 추가되거나, 요구되는 출력 결과물이 바뀌기도 합니다 - 심지어 입력되는 값들에 필터/어답터를 걸어야 하기도 하니까요. 따라서 스키마 변경을 할 때 드는 노력이나 비용이 가장 적을 수 있게 저장하는 게 좋겠습니다. (물론 출력 시 변화하는 방법이 있지만, 이것 또한 매번 사이클을 잡아먹죠)
딥 러닝을 하면서 모델을 교육 (train) 시키는 부분이 어떻게 보면 가장 큰 어려움이 있는 곳이고, 시간이 많이 필요한 도전인 것입니다. 예를 들어 경사 하강법 (gradient descent)과 같은 알고리즘으로 딥 러닝을 하는 경우 수십억 개의 변수를 포함하는 엄청난 매트릭스가 연결되며 반복까지 필요할 수 있게 때문에, 교육/훈련시키는 데 몇 주가 걸릴 수 있습니다. (그래서 시간을 단축하기 위해서 딥 러닝 프레임워크들은 가능하면 여러 개의 서버로 분산시켜 부하를 나누어 병렬화하려고 시도하는 거겠죠?) 교육 병렬화는 두 가지로 볼 수 있습니다:
자료의 병렬화. 저장소를 여러 노드에 거쳐 분할 또는 처리하는 방법 - Apache Spark/Hadoop 또는 MongoDB와 같은 분산 시스템을 통해 지원됩니다.
모델의 병렬화. 소프트웨어상의 모듈에 의해 지원되는 모델 혹은 관련된 계층을 여러 노드에 분할하는 방법 - Tensorflow, Caffe 및 Theano에서 지원되지만 노드 간의 출력을 조정하는 데 성능 비용 발생에 신경을 써야 합니다.
교육 이후에도 당연히 입력 데이터는 증가하겠죠? 심지어는 필드 수까지 증가하는 경우가 허다합니다. 알고리즘에 따라서 이건 단일 서버의 메모리 한계 (비용/효율성 한계)를 초과하는 것을 의미하고, 병렬적 확장으로 관련 데이터를 여러 노드에 분산해서 수행할 수 있게 해주도록 하도록 노력을 해야 합니다.
대부분의 딥 러닝 알고리즘들은 데이터를 처리하면서 구간을 정하고, 사용하여 실패 시 교육 데이터를 복구합니다. 그러나 자주 체크할 구간을 생성하려면 상당한 시스템 오버 헤드가 발생합니다. 이것과 다른 방법은 개별 노드에서 직접 데이터 복제본을 사용하는 것입니다. 이러한 복제본은 시스템의 최상위 노드의 소모를 최소화하면서 이중화 및 데이터 가용성의 결과를 가져오기도 합니다.
많은 경우의 딥 러닝을 도입한 시스템에서는 데이터 일관성을 이루기 위해 분산 데이터베이스 클러스터의 각 노드는 데이터의 최신 복사본에서 작동하지만, 확률적 경사 하강법(Stochastic Gradient Descent)과 같은 일부 알고리즘은 일정 수준의 일관성 결여를 허용할 수 있습니다. 일관성이 강하면 가장 정확한 결과를 얻을 수 있지만, 더 빠른 훈련 시간이 정확도보다 더 중요한 특정 상황에서는 궁극적으로 일관성이 인정될 수 있어야 합니다. 정확성과 성능을 최적화하기 위해 데이터베이스는 일관성 레벨을 조정 가능하게 해야 한다고 할 수 있겠죠.
딥 러닝 설명을 깊이 있게 하지 않았습니다만, 좀 더 기술적인 설명은 다른 글들에 맡기겠습니다. 하지만 저장소의 기능에 충실하면서 딥 러닝에 좀 더 효과적으로 서비스를 제공하기 위한 점들을 다뤄 봤고요. 마지막 4부에서는 NoSQL 기반의 시스템의 효용 가능성과 예제를 두고 글을 써보겠습니다.