출처: https://brunch.co.kr/@mapthecity/15

출처: 확률적 프로그래밍 기초 원리 - 신승환


확률적 프로그래밍 기초 원리 - 1


o 고전적 확률 

-> 사건이 일어날 수 있는 경우의 수를 가능한 모든 경우의 수로 나눈 값

-> 동전 던지기에서 가능한 모든 경우의 수는 앞면과 뒷면, 두 가지이므로 고전적 확률은 1/2 = 0.5


o 빈도적 확률

-> 어떤 사건을 반복했을 때 일어나는 상대 빈도수로 보는 것

-> 동전 던지기를 10회 했을 때 앞면이 3회 나왔다면 빈도적 확률은 3/10 = 0.3


o 시행 횟수가 무한대로 수렴한다면 빈도적 확률과 고전적 확률은 동일해진다.


o 사전 확률

-> 어떤 사건을 관찰하기 전에 관찰자가 갖는 학률


o 사후 확률

-> 어떤 사건을 관찰하고 나서 관찰자가 갖는 확률


o 객관적 확률   

-> 관찰자에 관계없이 동일한 결과를 얻는 확률로서, 고전적 확률과 빈도적확률이 여기에 속한다.


o 주관적 확률

-> 관찰자에 따라서 동일한 실험 결과를 두고 다른 결과를 얻게 되는 확률


o 시행

-> 무작위적으로 발생하는 사건의 결과를 관찰하는 과정


o 근원사건

-> 시행에서 발생할수 있는 모든 결과


o 표본 공간

-> 근원 사건의 집합


o 표본 공간의 부분집합을 사건이라 한다.


출처: http://t-robotics.blogspot.kr/2015/05/deep-learning.html


요즘 딥 러닝(Deep Learning)이 핫합니다. 몇 년전부터 기계학습(Machine Learning)이 일반인들에게 알려지기 시작하더니, 지금은 기계학습의 한 종류인 딥 러닝이 아예 기계학습이란 단어를 대체할 듯한 기세인 듯 합니다. 특히 구글이 딥 러닝 전문가 기업인 딥 마인드(Deep Mind)를 인수하고, 페이스북이 딥 러닝 대가인 뉴욕대학의 얀 러쿤(Yann LeCun) 교수를 인공지능 센터장으로 모셔갔으며, 중국의 구글이라 불리는 바이두에서도 기계학습 분야의 스타 학자 스탠포드 대학의 앤드류 응(Andrew Ng) 교수를 모셔가는 등, 지금은 바야흐로 딥러닝 인재전쟁에 가까운 모습입니다.

페이스북 인공지능 연구소 수장, 얀 러쿤(Yann LeCun) 교수 (사진출처)


그렇다면 딥 러닝이란 과연 무엇일까요? 오늘은 딥 러닝의 전반적인 개념에 대해 거칠게 한번 훑어보도록 하겠습니다.
(업데이트) 이 글의 후속편인 Convolutional Neural Network에 대한 이해가 업데이트 되었습니다. 이 글을 읽으신 후 꼭 한번 읽어보세요!

출처 : Terry's Facebook, https://goo.gl/Yo3Tvi

딥 러닝은 사실 새로운 개념이 아닙니다. 오래전부터 있어오던 인공신경망(Artificial Neural Network, ANN)과 크게 다를 바 없죠. '인공신경망'이라고 하면 단어에서 나오는 뽀대(?) 때문인지 막 복잡한 뇌 구조가 생각하면서 꿈 같은 이야기가 펼쳐질 것 같은 느낌 드는데요, 사실 인공신경망은 그렇게 판타스틱한 개념은 아닙니다.

그저 선형 맞춤 (linear fitting)과 비선형 변환 (nonlinear transformation or activation)을 반복해 쌓아올린 구조에 불과하죠. 다시 말해, 인공신경망은 데이터를 잘 구분할 수 있는 선들을 긋고 이 공간들을 잘 왜곡해 합하는 것을 반복하는 구조라고 할 수 있습니다. 선 긋고, 구기고, 합하고, 선 긋고, 구기고, 합하고, 선 긋고, 구기고, 합하고...(먹고 뜯고 맛보고 즐기고...-_-..)

파란선과 빨간선의 영역을 구분한다고 생각해보자. 그냥 구분 선을 긋는다면 아마 왼쪽처럼 불완전하게 그을 수 있을 것이다. 하지만 공간을 왜곡하면 오른쪽 같이 아름답게 구분선을 그릴 수 있다. 이처럼 인공신경망은 선 긋고, 구기고, 합하고를 반복하여 데이터를 처리한다. (사진출처: colah's blog)

예를 들어 컴퓨터가 사진 속에서 고양이를 검출해내야 한다고 생각해보죠. '고양이'라는 추상적 이미지는 아마 선, 면, 형상, 색깔, 크기 등 다양한 요소들이 조합된 결과물일 것입니다. 이것은 아마 '선 30cm 이상은 고양이, 이하는 고양이 아님', 또는 '갈색은 고양이, 빨간색은 고양이 아님' 처럼 간단한 선형 구분으로는 식별해 낼 수 없는 문제겠죠. 딥러닝은 이 과제를 선 긋고 왜곡하고 합하고를 반복하며 복잡한 공간 속에서의 최적의 구분선을 만들어 내는 목적을 가지고 있습니다.(1)

그럼 어떠한 규칙으로 선을 긋고 공간을 왜곡하냐고요? 바로 데이터에 근거하는 거죠. 일단 대충 선을 긋고 그것들을 살살살살 움직여가며 구분 결과가 더 좋게 나오도록 선을 움직이는 겁니다. 이러한 과정을 최적화(optimization)이라고 하는데요, 딥러닝은 아주 많은 데이터와 아주 오랜 시간의 최적화를 통해 데이터를 학습합니다. 양에는 장사 없다고나 할까요?

여러 개의 뉴런(선형 맞춤 + 비선형 변환)이 합쳐지면 복잡한 형상의 함수도 추정할 수 있다. (사진출처)

사실 인공신경망은 1940년대에 이미 개발된 방법이었고, 1980년대에 역전파(back propagation) 방법이라는 최적화 방법이 소개되며 인공신경망 연구가 절정기애 이른 바 있습니다. 이후 인공신경망은 영상처리, 인공지능, 제어 등 다양한 분야에 적용 되었는데요, 90년대에 이르러 그 연구가 포화 상태에 이르고, 이내 한계가 보이기 시작하더니 곧 암흑기를 만나게 됩니다. 심지어 2000년대 초반 논문 심사에서는 '인공신경망'이란 단어만 나오면 '뭐야, 이거 옛날거자나?'라며 리젝을 하기도 했었으니까요. 그렇게 인공신경망은 사라져 갔고, 2000년 대에는 비선형 함수를 이용한 다양한 커널 방법(e.g. Support Vector Machine, Gaussian Process)들이 기계학습의 대세를 이루게 됩니다.

딥 러닝의 일등 공신, 토론토 대학의 힌톤 교수 (사진출처: 토론토대학)

모두가 인공신경망을 외면하던 암흑기 시절, 그래도 꿋꿋하게 인공신경망 외길을 걸어오던 학자가 있었으니 바로 그가 딥러닝의 일등 공신, 토론토 대학의 제프리 힌톤(Geoffrey Hinton) 교수입니다. 인공신경망이 외면받는 여러 한계들 중 대표적인 문제는 바로 최적화가 쉽지 않다는 점이었습니다. 생각해보세요. 수 만개의 뉴론들이 수 백만개의 선들에 의해 연결되어 있고 여러분들은 이 선들에 적당한 값들을 할당해야 합니다. (일명parameter training이죠.) 

이걸 최적화 알고리즘을 통해 해줘야 하는데, 최적화 알고리즘이 만약 진짜 최적값이 아닌 잘못된 최적값에 도달하면 어쩌죠? 예를 들어 최고 높은 산봉오리에 올라가야 하는게 목적이라고 하면, 앞만 보고 막 달려서 산 봉우리에 올랐더니 '엥? 이 산이 아닌게벼...?'라고 하면 어쩌냔 말입니다. 인공신경망은 그 구조가 워낙 복잡했기에 이런 문제가 발생했을 때 그야 말로 속수무책이었죠. (그래서 제 예전 지도교수님은 인공신경망을 'black magic'이라고도 하셨으니까요ㅎㅎ)

하지만 힌톤 교수는 이러한 함정(local minima)들을 데이터의 전처리과정(pre-training)을 통해 크게 해결할 수 있음을 밝혔습니다. 이 연구가 바로 "A fast learning algorithm for deep belief nets"라는 2006년의 논문인데요, 힌톤 교수는 이 논문을 통해 인공신경망의 각 층들을 먼저 비지도학습 방법(unsupervised learning)을 통해 잘 손질해주고, 그렇게 전처리한 데이터를 여러 층 쌓아올려 인공신경망 최적화를 수행하면 '이 산이 아닌게벼?' 없이 훌륭한 결과를 만들어 낼 수 있다는 것을 보였습니다.

출처 : Terry's Facebook, https://goo.gl/Yo3Tvi

이 논문을 기점으로 인공신경망 연구는 새 전기가 열리게 됩니다. 특히 인공신경망은 빅데이터와 찰떡궁합이었죠. 2006년 이전의 많은 연구들이 데이터에 대한 구체적 형상 파악에 그 노력을 쏟았었다면, 이젠 그냥 어마어마한 구조의 인공신경망에 엄청난 데이터를 막 때려 넣는겁니다. 그리고선 2006년 이후 개발된 세련된 최적화 기법을 써서 몇날 며칠을 학습하면 '짜잔~'하고 최고의 결과를 내놓는다는 거죠. 딥러닝 기법은 이 후 각종 머신러닝 대회의 우승을 휩쓸며 (그것도 압도적인 성능으로...) 자신이 유아독존의 기법임을 과시했고, 현재는 다른 기계학습 방법을 통해 영상처리, 음성인식 등을 연구하셨던 분들 역시 딥러닝으로 대동단결하는 양상을 보이고 있습니다.

기계학습 관련 기업들. 이 중 Facebook, Google, Baidu 등은 모두 딥러닝에 사활을 걸고 있다. (사진출처)

그렇다면 그토록 오랜 암흑기였던 인공신경망을 성공적인 딥러닝으로 환골탈태하게 한 요인은 뭘까요? 그 요인에는 크게 다음과 같은 네 가지를 꼽을 수 있습니다.

1. Unsupervised Learning을 이용한 Pre-training

앞서 힌톤 교수가 2006년에 제안했던 것이 바로 이 방법입니다. Unsupervised learning이라고 하면 (대충 말해서) '이건 사과', '이건 고양이', '이건 사람' 이런 "가르침" 없이그냥 사과, 고양이, 사람을 다 던져놓고 구분하라고 시키는 학습 방법인데요, 그렇게되면 아무래도 컴퓨터는 비슷한 것끼리 군집(cluster)을 찾게 되겠죠. 알고리즘은 군집화하는 과정 속에서 특이한 놈들은 과감하게 개무시(;;), 결과적으로 노이즈 감소의 효과를 얻게 됩니다. 이렇게 unsupervised learning 방법으로 데이터를 고르게 잘 손질할 수 있고, 이것을 깊은 인공신경망(=딥러닝망)에 넣으면 앞서 제기한 함정들에 훨씬 적게 빠진다는 것입니다. 이것이 바로 딥러닝의 최초 진일보였죠.

2. Convolutional Neural Network의 진화

기계학습은 data→knowledge 로 바로 학습을 진행할 수도 있지만 보통 중간 단계인 특징 추출(feature extraction)을 거쳐 data→feature→knowledge 의 단계로 학습하는 것이 보통입니다. 예를 들어 사진 속에서 사물을 인식하기 위해 픽셀 값에서 먼저 특징적인 선이나 특징적인 색 분포 등을 먼저 추출한 후 이를 기반으로 '이건 사과다' '이건 바나나다'라는 판단을 내리는 것이죠. 이러한 중간 표현단계를 특징 지도 (feature map)이라고 하는데요, 기계학습의 성능은 얼만큼 좋은 특징들을 뽑아내느냐에 따라 그 성능이 매우 크게 좌지우지 됩니다. (이는 이미지 처리 뿐만 아니라 음성 인식, 자연어 분석 등 대부분의 기계학습에 적용되는 이야기입니다.) 

원본 이미지(우측)와 convolutional network에 의해 추출된 특징 지도(좌측) (출처: M. Zeiler)

딥러닝의 성공 요인 중 하나를 꼽자면, 예전엔 사람의 예측에 의해 뽑히던 이 특징들을 지금은 이 마저도 기계학습을 이용해 뽑는다는 것입니다. 다시 말해, 예전엔 '선들을 추출해서 학습시키면 사물인식이 잘 될거야'와 같이 사람이 먼저 이 선들을 추출하는 알고리즘을 만들어 주었는데, 이제는 특징 추출과 학습 모두가 딥러닝 알고리즘 안에 포함되었다는 것이죠. 다단계로 특징을 추출해 학습하는 Convolutional Neural Network은 현재 딥러닝의 대세로서 특히 이미지 인식에서 큰 발전을 이룩하고 있습니다.

3. 시계열 데이터를 위한 Recurrent Neural Network

딥러닝 알고리즘을 크게 세 분류로 나누자 대략적으로 다음과 같이 나눌 수 있습니다.
- Unsupervised Learning을 기반으로 한 방법
  (e.g., Deep Belief Network, Deep Auto-encoder)
- Convolutional Neural Network의 다양한 변형들
- 시계열 데이터를 위한 Recurrent Neural Network와 게이트 유닛들
  (e.g. Long-Short Term Memory (LSTM))
시계열 데이터(Time-series data)란 시간의 흐름에 따라 변하는 데이터를 말하는데요, 예를 들면 주가도 시간에 따라 변하고, 사람의 움직임도 시간에 따라 변하고, 비디오도 시간에 따라 변하고... 이러한 시계열 데이터에서 탁월한 성능을 보여주는 딥러닝 방법이 바로Recurrent Neural Network (RNN) 입니다. RNN은 매 순간마다의 인공신경망 구조를 쌓아올렸다고 생각하시면 되는데요, 예를 들면 100초면 100개의 인공신경망을 쌓아올린거죠. (그래서 딥러닝 중에 가장 깊은 구조라고도 불립니다.)

예전의 RNN은 인공신경망이 너무 깊어서 오랜 시간 전의 데이터들을 까먹는 현상(vanishing gradient problem) 때문에 학습이 힘들었는데요, Jurgen Schmidhuber 교수의 Long-Short term Memory (LSTM) 이란 게이트 유닛을 각 노드마다 배치하여 이러한 문제를 극복, 현재는 Convolutional Network의 가장 강력한 경쟁 상대로 자리매김하고 있습니다.

매 순간의 인공신경망을 쌓아 올린 Recurrent Neural Network (사진출처)

4. GPU 병렬 컴퓨팅의 등장과 학습 방법의 진보

사실 예전엔 '많은 데이터로 가지고 이렇게 저렇게 하면 아마 잘 될거야...'라는 생각들은 가지고 있더라도 그것을 구현하는 것이 쉽지 않았습니다. 잘 될지 안될지도 모르는데 수십 대의 컴퓨터를 몇 달간 돌리고 있을 수는 없는 노릇이니까요. 하지만 GPGPU (General-Purpose computing on Graphics Processing Units)이란 개념이 개발되며 저렴한 가격으로 CPU와 병렬처리를 할 수 있는 GPU 제품들이 출시되었고, 이를 효율적으로 이용하는 언어구조(e.g. CuDA)들이 개발되며 딥러닝은 그 컴퓨팅 시간이 수십분의 일로 줄어 들었습니다.

연구에 사용할 수 있는 데이터 풀도 많아져 예전엔 기껏해야 몇 만개의 손 글씨 데이터(e.g.MNIST)가 전부이던 것이 지금은 천 만장의 고해상도의 사진들(e.g. ImageNet)은 물론, 필요하다면 구글이나 유튜브에서 자료를 끌어올 수도 있었으니 말이죠.

그리고 인공신경망 알고리즘적인 문제로는 비선형 변환에 쓰이는 Rectified Linear Unit (ReLU)의 개발과 거대 망을 선택적으로 학습하는 Drop-out의 발견이 딥러닝의 성능을 크게 향상 시켰답니다. 이러한 잔기술(?)에 대해서도 할 얘기가 많지만 깊은 얘기는 언젠가 또 해드리도록 하죠. ('언젠가 밥 한번 먹자'와 비슷 한 얘기입니다..;;)

구글은 2012년 1000대의 컴퓨터로 1000만 개의 유튜브 이미지를 딥러닝으로 분석해 사람과 고양이를 구분해 냈다. 내게도 컴퓨터 지원 좀 해달라... (출처 : Q. Le)

지금까지 딥러닝에 대해 알아봤습니다. 요약하자면 딥러닝은 사실 오래 전부터 있어오던 인공신경망과 크게 다를 바 없지만 알고리즘적인 발전과 하드웨어의 발전, 그리고 빅데이터의 힘에 의해 현재 최고 성능을 가진 기계학습 방법으로 평가받고 있으며, 미래 인공지능의 희망으로 떠오르고 있다는 이야기였습니다.

그렇다면 딥러닝 말고 다른 기계학습 방법들은 모두 사라져야 하는 걸까요? 물론 그것은 아닙니다. 일단 딥러닝은 많은 양의 데이터와 많은 컴퓨팅 자원을 필요로 합니다. (저도 이번에 80만원짜리 GPU를 구매...ㅠ) 따라서 핸드폰이나 웨어러블과 같은 포터블 기기는 이러한 컴퓨팅이 불가능할테니 딥러닝을 적용하기 쉽지 않겠죠. 또한 로봇과 같이 실시간성(real-time)이 보장되어야 하는 분야 역시 다른 기계학습 방법을 취하는게 좋을 수도 있을 것입니다. (이건 마치 컴퓨터엔 윈도우, 핸드폰엔 안드로이드와 같은 맥락이라 할 수 있죠.)

하지만 그렇다고 딥러닝이 이들 분야와 무관하냐하면 꼭 그렇지만은 않습니다. 여러분이 컴퓨터가 좋아서 구글 검색 결과가 좋나요? 다 구글 서버에서 알아서 처리해주니 그런거지요. 딥러닝도 마찬가지로 만약 디바이스가 사물인터넷을 이용해 머리 좋은 서버와 잘 교신한다면 포터블 디바이스 역시 딥러닝의 은총을 받을 수 있을 것이라 생각합니다. 특히 구글이 로봇의 미래라 생각하는 클라우드 로보틱스를 구현한다면 여러 로봇이 집단 지성을 발휘하며 문제를 해결해 나가는 것을 미래에 볼 수도 있겠지요. (참고: "구글의 새 로봇 수장, 제임스 커프너는 누구인가")

딥러닝, 인공지능의 가장 희망적인 미래임은 분명합니다. 이 분야와 관계 없으시더라도 여러분도 아마 공부 좀 하셔야 할걸요? ^^ 앞서 말씀드렸듯 이 글의 후속편인 Convolutional Neural Network에 대한 이해도 꼭 한번 읽어보세요!

(1) 쉽게 말씀드리려고 제가 딥러닝과 classification 문제를 섞어서 말씀드린 건데요, 사실 딥러닝은 real-value를 다루는 regression문제에도 적용될 수 있습니다. 

* T-Robotics의 글은 facebook과 rss reader로도 받아보실 수 있습니다.


출처: http://ishuca.tistory.com/entry/Image-Classification-Datadriven-Approach-kNearest-Neighbor-trainvaltest-splits


CS231n Convolutional Neural Networks for Visual Recognition


http://cs231n.github.io/classification/ 의 번역인데, 발번역임. 

내 공부를 돕고자함. 

저작권 문제는 없는 듯하나 문제가 생길 경우 바로 삭제함

발번역이어도 내용은 제대로 이해하고 있으니 질문 있으면 댓글 남겨주세요

=======================================================================================Image Classification: Data-driven Approach, k-Nearest Neighbor, train/val/test splits

L1/L2 distances, hyperparameter search, cross-validation


이것은 이미지 분류 문제와 데이터에 기반한 접근법을 컴퓨터 비젼 외부 사람들에게 소개하기 위한 입문 강의임


이미지 분류(Image Classification)


동기(Motivation). 이 장에서 우리는 카테고리가 고정된 집합으로부터 하나의 라벨을 입력 이미지에 할당하는 작업인 이미지 분류 문제를 소개할 것임. 이것은 단순함에도 불구하고, 실제 응용의 많은 다양성을 가지고, 컴퓨터 비젼에서 주요 문제 중 하나임. 게다가 이 코스에서 후에 볼 것이지만, 많은 다른 겉보기에 달라보이는 컴퓨터 비젼 작업들(예를 들면, 물체 검출, 분할 등)은 이미지 분류로 축소할 수 있음


예(Example). 예를 들면, 아래 이미지에서 이미지 분류 모델은 하나의 이미지를 택해, 4개의 라벨 {cat, dog, hat, mug} 에 확률을 할당한다. 이미지에서 보여지는 것처럼, 컴퓨터에게 이미지는 매우큰 3차원 배열로써 표현된다. 이 예에서, 고양이 이미지는 너비 248 픽셀, 높이 400 픽셀이고, 3개의 색 채널 Red, Green, Blue ( 짧게 RGB)을 가지고 있다. 그러므로, 이미지는 248 x 400 x 3 의 숫자들이고, 이는 총 297,600  개의 숫자다. 각 숫자는 정부로 0(검은색) 으로부터 255(흰색)까지의 범위를 갖는다. 우리의 작업은 매우 큰 숫자를 하나의 라벨 "cat"으로 바꾸는 것이다.




이미지 분류에서 이 작업은 주어진 이미지에 대해 하나의 라벨(혹은 우리가 표시한 것처럼 라벨들의 분포를)을 예측하는 것이다. 이미지들은 0부터 255의 정수들인 3차원 배열로 너비 x 높이 x 3 의 크기를 갖는다. 이 3은 세개의 색 채널 Red, Green, Blue을 표현한다.


문제(Challenges). 시각적 개념 (e.g. 고양이 cat)을 인지하는 작업은 사람이 수행하기에는 상대적으로 쉽다. 컴퓨터 비젼 알고리즘의 관점에서 문제를 고려할 가치가 있다. 아래에 현재의 문제 목록이 있다. 이미지는 밝기의 3차원 배열로 표현되었다는 것을 명심해라


관점의 변화(Viewpoint variation). 한 객체의 개별 실체(single instance)는 카메라에 대하여 많은 방법으로 얻어질 수 있다.

규모의 변화(Scale variation). 시각적 클래스는 자주 그들의 크기에서 변화를 보인다(이미지 내에서 보이는 그들의 크기 뿐만 아니라 실제 세상에서의 크기)

변형(Deformation). 관심 있는 많은 객체는 일정한 형태가 아니고, 극단적으로 변형이 올 수도 있다.

안 보임?(Occlusion). 관심 있는 그 객체는 안 보일 수 있다. 때때로 어느 객체의 아주 작은 부분만이 관찰가능 할 수도 있다.

조명 조건(Illumination conditions). 조명의 효과는 픽셀 수준에서 극단적이다.

배경 어수선함(Background clutter). 관심 있는 그 객체는 그들의 환경 속에 섞여 있을 수 있고, 그들을 식별하기 어렵게 만든다. 

클래스 내 변화(intra-class variation). 관심 있는 클래스들은 자주 상대적으로 넓어질 수 있다. 의자 같은것처럼. 이들은 이들 그들 자신의 외모와 함께 각 객체의 많은 다른 타입이 있다. 


좋은 이미지 분류 모델은 클래스간 변동에는 예민함을 유지하면서 이 모든 변화에 불변해야한다. 



자료에 따른 접근법(data-driven approach). 어떻게 우리가 이미지를 개별 카테고리에 분류할 수 있는 알고리즘을 작성할 수 있을까? 예를 들어, 숫자의 리스트를 정렬하는 것과 같은 알고리즘을 작성하는 것과 달리, 이미지에서 고양이를 식별하기 위한 알고리즘을 작성하는 방법은 명확하지 않다. 그러므로, 코드에서 직접적으로 관심있는 대상의 카테고리가 무엇인지 특정지으려는 시도 대신에, 어린아이와 같은 방법을 취하는 접근법이다. 우리는 컴퓨터에게 각 클래스의 많은 예제를 제공하고, 각 클래스의 시각적 특성에 대해 배우는 알고리즘을 개발한다. 이 접근법은 자료에 따른 접근법(data-driven approach)과 관련이 있다. 이것은 첫재로 이름 붙여진(labeled) 이미지의 학습 자료집합을 누적할 필요가 있다. 이것은 다음과 같은 데이터집합의 예제이다.




4개의 시각적 카테고리에 대한 학습 집합의 예제이다. 실제는 우리는 수 천개의 카테고리와 각 카테고리에 대한 수십만의 이미지를 가지고 있다.


이미지 분류 파이프라인(The image classification pipeline). 우리는 이미지분류에서 이 작업이 하나의 이미지를 픽셀의 배열로 표현하고, 거기에 라벨을 할당하는 것을 보았다. 우리의 완벽한 파이프라인은 다음과 같이 공식화될 수 있다.


입력(Input): 우리의 인풋은  K개의 다른 클래스 중 하나로 라벨된  N개의 이미지의 집합으로 구성된다. 우리는 이 데이터를 학습 집합(training set)이라고 부른다.

학습(Learning): 우리의 작업은 학습 집합을 사용해서 그 클래스의 모든 것이 무엇으로 보이는지 학습하는 것이다. 우리는 분류기(classifier)를 학습하는 것(혹은 모형을 배우는 것)으로 이 단계를 나타낸다. 

평가(Evaluation): 결국, 우리는 이전에 보지 못했던 이미지의 새로운 집합에 대한 예측 라벨을 물어봄으로써 분류기의 질을 평가한다. 우리는 분류기에 의해 예측된 것과 이들 이미지에 실제 라벨ㅇ을 비교한다. 직관적으로 우리는 실제 답(우리는 이를 ground truth라 부른다)과 맞는 예측이 많기를 바란다.


최근접 이웃 분류기(Nearest Neighbor Classifier)


우리의 첫번째 접근법으로써, 우리는 우리가 최근접 이웃 분류기라 부르는 것을 개발할 것이다. 이 분류기는 Convolutional Neural Networks 콘볼루션 신경망과 관련 없고, 실제로 쓰이는 일이 매우 드믈다. 그러나 이것은 이미지 분류 문제에 대한 기본적인 접근법에 대한 아이디를 얻을 수 있도록 한다.


예제 이미지 분류 집합:CIFAR-10 (Example image classification dataset: CIFAR-10). 유명한 모형 이미지 분류 집합은  CIFAR-10 dataset이다. 이 데이터셋은 높이와 너비가 32 픽셀인 6만 개의 작은 이미지들로 구성되어있다. 각 이미지는 10개의 클래스의 하나로 이름 붙여져있다 (예를 들면, "비행기, 자동차, 새, 기타 등등"). 이들 6만개의 이미지들은 5만 개의 학습 이미지와 1만 개의 테스트 이미지 집합으로 나뉘어져있다. 아래 이미지에서 10개 클래스에서 랜덤한 10개의 예제를 볼 수 있다.




왼쪽: CIFAR-10 데이터셋으로부터 예제 이미지. 오른쪽: 첫 열은 테스트 이미지이고, 다음은 학습데이터셋에서 픽셀별 차이에 해당하는 10개의 최근접 이웃을 보여준다.


우리는 이제 CIFAR-10 학습 5만개의 학습 집합(모든 라벨 별로 5천개의 이미지)이 주어졌다고 가정하고, 우리는 남은 1만 개를 이름 붙이고  싶다. 이 최근접 이웃 분류기는 하나의 테스트 이미지를 택해, 학습 이미지의 모든 개별 이미지와 비교하고, 가장 가까운 학습 이미지의 라벨을 예측한다. 위에 이미지에서 오른쪽에 10개의 테스트 이미지에 대한 이런 과정의 결과의 예를 볼 수 있다. 10개의 예제 중 약 3개만이 동일 클래스로 검색되고, 나머지 7개의 예제는 다른 사례이다. 예를 들어, 8번째 행의 말에 대한 최근접 학습 이미지는 빨간 차이다. 아마 강한 검은 배경 때문일 것이다. 그 결과, 말의 이미지는 차로 잘못 분류된다.


너는 우리가 32 x 32 x 3의 두 블록 인 두개의이미지를 비교하는 정확한 방법의 자세한 설명을 언급하지 않고 남겨둔 것을 눈치 챘을 수도 있다. 가장 단순한 가능중 하나는 픽셀별로 이미지를 비교하고 이 모든 차이를 더하는 것이다. 즉, 두개의 이미지가 주어지고, I1, I2 벡터로써 그들을 표현하면, 그들을 비교하기 위한 합리적인 선택은 L1 거리일 수 있다. 




이 과정을 시각화하면 다음과 같다.




L1 거리(이 예제에서는 하나의 색 채널에 대한)와 함께 두개의 이미지를 비교하기 위해 픽셀별 차이를 사용한 예제. 두개의 이미지들은 요소별로 빼지고, 모든 차이는 하나의 숫자로 더해졌다. 만약 두 이미지가 동일하다면 그 결과는 0이 될 것이다. 하지만 이미지가 많이 다르다면, 그 결과는 매우 클 것이다.


코드에서 우리가 어떻게 이 분류기를 구현할 수 있는지 살펴보자. 머넞, CIFAR-10 데이터를 메모리에 4개의 배열로 불러오자: 학습 데이터/ 학습 라벨 데이터와 테스트 데이터/ 데스트 라벨 데이터. 아래에 코드에서 Xtr(50,000 x 32 x 32 x 3의 크기)는 학습 집합에서 모든 이미지를 가지고 있고, Ytr( 50,000의 길이) 1차원 배열은 해당하는 학습 라벨 (0부터 9까지)를 가지고 있다.


Xtr, Ytr, Xte, Yte = load_CIFAR10('data/cifar10/') # 우리가 제공하는 마법의 함수
# 모든 이미지들을 1차원으로 만든다
Xtr_rows = Xtr.reshape(Xtr.shape[0], 32 * 32 * 3) # Xtr_rows 는 50000 x 3072 shape가 된다.
Xte_rows = Xte.reshape(Xte.shape[0], 32 * 32 * 3) # Xte_rows 는 10000 x 3072 shape가 된다.


이제 우리는 행으로 만든 모든 이미지들이 있다. 여기에 우리가 분류기를 학습하고 평가할 방법이 있다.


nn = NearestNeighbor() # 최근접 이웃 분류기 클래스를 생성한다.
nn.train(Xtr_rows, Ytr) # 학습 이미지와 라벨에 대해 분류기를 학습한다.
Yte_predict = nn.predict(Xte_rows) # 테스트 이미지에 대해 라벨을 예측한다.
# 올바르게 예측한 예제의 평균 숫자로 분류기의 정확도를 나타낸다.

print 'accuracy: %f' % ( np.mean(Yte_predict == Yte) )


평가기준으로써 정확도(accuracy)가 일반적으로 쓰인다. 이것은 올바르게 예측한 비율로 측정된다. 모든 분류기는 우리가 공통된 API를 만족시키게 만들 것이다. 그들이 가진 train(X,y) 함수는 데이터와 라벨로부터 배운다. 내부적으로, 그 클래스는 라벨의 모형의 몇가지 종류와 그들이 데이터로부터 예측할 수 있는 방법을 만든다. 그래서 predict(X) 함수는 새로운 데이터를 취해서 라벨을 예측한다. 여기에 L1 거리로 단순한 최근접 이웃 분류기의 구현이 있다.


import numpy as np

class NearestNeighbor(object):
  def __init__(self):
    pass

  def train(self, X, y):
    """ X는 각 행이 예제인 N x D 크기의 행렬이다. Y는 N 크기의 1차원이다. """
    # 이 최근접 이웃 분류기는 단순히 모든 학습 데이터를 기억한다.
    self.Xtr = X
    self.ytr = y

  def predict(self, X):
    """ X 는 우리가 예측하고 싶어하는 각 행이 예제인 N x D 행렬이다. """
    num_test = X.shape[0]
    # 입력 형과 출력형이 같도록 만든다.
    Ypred = np.zeros(num_test, dtype = self.ytr.dtype)

    # 모든 테스트 데이터 행들에 걸쳐 반복을 한다.
    for i in xrange(num_test):
      # i번째 테스트 이미지에 대해 가장 가까운 학습 이미지를 찾는다 
      # 절대값 차이의 합인 L1 거리를 사용해서
      distances = np.sum(np.abs(self.Xtr - X[i,:]), axis = 1)
      min_index = np.argmin(distances) # 가장 작은 거리를 갖는 인덱스를 얻는다
      Ypred[i] = self.ytr[min_index] # 가장 가까운 예제의 라벨로 예측한다

    return Ypred


이 코드를 실행해봤다면, 너는 CIFAR-10 에 대해 이 분류기가 38.6%만 성취한 것을 보았을 것이다. 이것은 더 랜덤(10개 클레스에 대해 10% 정확도를 기대하는)으로 예측하는 것보다는 더 낫지만, 최신 기술인 콘볼루션 신경망이 달성한 약 95%나 사람수준의 성능(약 94% 정도로 측정된다)에는 근처에도 못 간다.


거리의 선택(The choice of distance). 벡터 간의 거리를 계산하는 다른 많은 방법이 있다. 또다른 일반적인 선택은 두 벡터간의 유클리디안 거리를 계산하는 기하학적 해석인 L2 거리를 대신 사용할 수 있다. 이 거리는 다음의 형태를 갖는다.




즉 우리는 이전처럼 픽셀 별 차이를 계산하는데, 동시에 모든 것들에 대해 제곱을 하고, 전부 더하고 마지막으로 제곱근을 취한다. numpy에서 위의 코드는 한줄이면 된다. 


distances = np.sqrt(np.sum(np.square(self.Xtr - X[i,:]), axis = 1))


나는 위에서 np.sprt를 불렀다. 그러나 실제 최근접 이웃에서는 생략할 수 잇다. 왜냐면 제곱 근은 보이는 것만 바꾸기 때문이다. 즉, 이것은 거리의 절대적 크기를 바꾸지, 순서를 바꾸지는 않는다. 그래서 최근접이웃은 이걸 넣으나 빼나 동일하다. 만약 이 거리로 최근접와 함께 CIFAR-10에 대해 최근접 이웃 분류기를 실행하면, 35.4% 정확도를 얻는다(우리의 L1 거리 결과보다 약간 더 낮다)


L1 vs. L2. 이것은 두 지표 간의 차이를 고려할때 흥미롭다. 특히, L2 거리는 두 벡터간의 차이를 얻을 때 L1 거리보다 관대하다. 즉, L2 거리는 하나의 큰 것보다 많은 중간 불일치는 선호한다. L1과 L2 거리는 가장 일반적으로 사용되는 p-norm의 특별한 경우이다.


k개 최근접 이웃 분류기(k - Nearest Neighbor Classifier)


우리가 예측을 만들때 가장 가까운 이미지의 라벨만을 사용하는 것을 이상하게 여겼을 수도 있다. 이것은 항상 k 최근접 이웃 분류기라 불리는 것을 사용해 더 나아질 수 있다. 이 아이디어는 단순하다 학습 데이터 셋에서 가장 가까운 하나의 이미지만을 찾는 것 대신의 k 개의 가까운 이미지를 찾고, 테스트 이미지의 라벨에 대한 투표를 하는 것이다. 특히 , k가 1 일때, 우리는 최근접 이웃 분류기라 한다. 직관적으로 k의 큰 수는 이상치에 대해 더 강건한 분류기를 만드는 스무딩 효과를 갖는다.



2차원 점과 3개의 클래스(red,blue,green)을 사용한 최근접 이웃과 5 최근접 이웃 분류기 사이의 차이에 대한 예제이다. 색칠된 지역은 L2 거리로 분류기에 의한 결정경계(decision boundaries)를 보여준다.하얀 지역은 적어도 두개의 클래스가 같은 수의 클래스 투표를 받은 애매모호한 분류 점을 나타낸다. 최근접 분류기의 경우에, 이상치 데이터(파란 점 가운데에 초록색 점)는 올바르지 않은 예측의 작은 섬을 만든다. 반면 5 최근접 이웃 분류기는 이러한 비정규성을 극복하고, 테스트 데이터(보이지는 않은)에 대해 더 일반적일 것으로 예상할 수 있다. 5 NN 이미지에서 회색 지역은 최근접 이웃 사이에서 투표에 동일 표 때문에 발생했다.


실제에서, 너는 대게 항상 k 최근접 이웃을 사용하길 원할 것이다. 그러나 k의 어떤 값을 사용할 것인가? 다음에서 이 문제로 넘어간다


하이퍼 파라미터 조정을 위한 검증 집합(Validation sets for hyperparameter tuning)


k 최근접 이웃 분류기는 k의 설정이 필요하다. 그러나 어떤 숫자가 가장 좋은지 알 수 있을까? 게다가, 우리는 L1, L2 거리나 내적(dot product)과 같은 수 많은 거리 함수 선택이 있다. 이들 선택을 하이퍼파라미터라고 한다. 자료로부터 학습하는 기계학습 알고리즘의 설계에서 자주 나온다. 값이나 설정을 어떻게 설정해야할지 명확하지 않기 때문이다.


가장 좋은 값을 찾기 위해 수많은 다른 값을 시도할 수 있다. 좋은 아이디어다 그러나 실제로 우리가 할 것이다. 그러나 매우 조심해서 해야만 한다. 특히, 우리는 하이퍼파라미터들을 조정할 목적으로 테스트 집합을 사용할 수 없다. 너가 기계학습 알고리즘을 설계할때 마다, 테스트 집합은 끝날때까지 절대로 건드리지 말아야할 귀중한 것으로 생각해야만 한다. 그렇지 않으면, 진짜 위험은 너의 하이퍼파라미터 조정이 테스트 집합에서 잘 작동할 수 있다는 것이다. 그러나 만약 너가 모델을 구축한다면 성능이 유의미하게 감소하는 것을 볼 수 있을 것이다(테스트 집합을 사용해서 하이퍼파라미터를 만들면 이렇다는 것임). 우리는 이것을 너가 테스트 집합에 과대적합했다고 말한다.  테스트집합에 대해 하이퍼파라미터를 조정한다면, 테스트 집합을 학습 집합처럼 사용하는 것이고, 그래서 너의 모델을 구축할 때, 아주 낙관적인 결과를 얻을 수 있다. 그러나 네가 마지막에만 테스트 집합을 사용한다면, 너의 분류기의 일반적 능력을 측정하는 아주 좋은 대리변수가 될 것이다(우리는 이 클래스에서 후에 일반화를 둘러싼 많은 논의를 살펴볼 것이다)


테스트 집합에 대한 평가는 가장 마지막에 단 한번만 해라


운좋게도, 테스트 집합은 전혀 건들지 않고 하이퍼파라미터를 조정하는 올바른 방법이 있다. 이것은 학습 집합을 두개로 나누는 것이다.  학습 집합보다 조금 더 작고, 우리는 이것을 검증 집합(validation set)이라 부를 것이다. 예제처럼 CIFAR-10을 사용할 때, 우리는 4만 9천개를 학습집합으로 사용하고, 1천개를 검증을 위해 남겨둔다. 이 검증 집합은 하이퍼파라미터를 조정하기 위한 가짜 테스트 집합 처럼 사용한다.


# 이전과 같이 Xtr_rows, Ytr, Xte_rows, Yte 를 가정한다
#  Xtr_rows 는 50000x 3072(32x32x3) 행렬이다
Xval_rows = Xtr_rows[:1000, :] # 검증을 위해 처음 1천개를 고른다
Yval = Ytr[:1000]
Xtr_rows = Xtr_rows[1000:, :] # 학습에는 49,000개만 사용한다
Ytr = Ytr[1000:]

# 검증 집합에 가장 잘 작동하는 하이퍼파라미터를 찾는다
validation_accuracies = []
for k in [1, 3, 5, 10, 20, 50, 100]:

  # 특정 k의 숫자를 사용해서, 검증 자료에 대해 평가한다
  nn = NearestNeighbor()
  nn.train(Xtr_rows, Ytr)
  # 여기서 우리는 최근접이웃 클래스가 k를 입력값처럼 사용하도록 수정했다.
  Yval_predict = nn.predict(Xval_rows, k = k)
  acc = np.mean(Yval_predict == Yval)
  print 'accuracy: %f' % (acc,)

  # 검증 집합에 대해작동하는 것을 저장한다
  validation_accuracies.append((k, acc))


이 과정의 끝에서, 우리는 k의 값에 대한 그래프를 그릴 수도 있다. 우리는 이 값으로  고정시키고, 실제 테스트 집합에 대해 한번만 평가한다.


너의 학습 집합을 학습 집합과 검증 집합으로 나눠라. 모든 하이퍼파라미터를 조정하기 위해 검증 집합을 사용해라. 마지막에 테스트 집합에 대해 한번만 하고, 성능을 보고해라


교차검증(Cross-validation). 너의 학습 집합의 크기가 작아서 검증 집합도 작을 경우에 하이퍼파라미터 조정을 위한 더 정교한 기법을 사용한다. 이를 교차검증(Cross-validation)이라 부른다. 이전 예제에서, 이 아이디어는 애매하게 뽑은 첫 1천 개를 검증집합으로 나누고 나머지를 학습 집합으로 두는 대신에, 다른 검증 집합 들에 걸쳐 반복적으로 특정 k에 대해 측정하고 이들 성과를 평균하는 방법으로 노이즈가 적고, 더 나은 추정을 할 수 있다. 예를 들면, 5겹 교차검증(5-fold cross-validation)에서, 우리는 학습 집합을 5개의 동등한 그룹으로 나누고, 이중 4개를 학습에 사용하고, 나머지 한개를 검증에 사용한다. 우리는 이걸 모든 검증 집합에 대해 반복하고, 성능을 평가하고, 성능을 평균낸다.



파라미터 k 에 대한 5겹 교차검증의 예. 각 k의 값에 대해 4개의 그룹으로 학습시키고, 5번째로 평가한다. 그런 이유로, 각 k는 검증 그룹에 대해 5개의 정확도가 나온다. 추세선은 각 k에 대한 결과의 평균선이고, 오차 막대는 표준편차를 나타낸다. 이 특정 사례에서, 교차 검증은 k를 약 7이 가장 좋다고 한다. 만약 너가 5겹보다 더 한다면, 더 부드러운 곡선을 기대할 수 있을 것이다.


실제는 교차검증은 계산적 비용이 매우 크기 때문에 사람들은 교차검증을 선호하지 않고, 한번 검증 집합을 나누는 것을 선호한다. 사람들은 주로 학습 집합의 50%-90%를 학습 집합으로 사용하고, 나머지를 검증으로 한다. 그러나 이것은 다양한 요인에 달려있다. 예를 들어 하이퍼파라미터의 수가 크다면 너는 아마 검증  집합을 나누는걸 크게하는 것을 선호할 수도 있다. 만약 검증집합의 예제의 수가 적다면(단지 수백정도라면,) 교차검증을 사용하는 것이 더 안전할 수 있다. 몇 겹을 할지는 너에게 달려있지만, 실제로는 3겹, 5겹 10겹의 교차검증을 주로 사용한다.




일반적인 데이터 나누기. 학습 집합과 테스트 집합은 주어진다. 학습집합은 예제에서 5개의 그룹으로 나눠진다. 1-4개의 그룹은 학습 집합이고, 노란색으로 되어있는 5번째 그룹은 검증 집합이 되어 하이퍼파라미터를 조정하는데 사요된다. 교차검증은 검증 집합을 바꿔가며 1-5까지 반복적으로 수행된다. 이것이 5겹 교차검증이라 부르는 이유다. 가장 좋은 하이퍼파라미터가 결정된면, 그 모델을 테스트 자료(빨강)에 평가된다.


최근접 이웃 분류기의 찬반양론(Pros and cons of Nearest Neighbor classifier)


최근접 이웃 분류기의 장점과 단점을 알아보자. 명확하게, 장점은 구현하고 이해하기 매우 단순하다는 것이다. 게다가, 이 분류기는 학습에 시간이 안 든다. 학습 자료를 색인하고 저장하기만 하면 된다. 그러나 우리는 매우 테스트 집합에 대해 매우 큰 계산 비용을 지불한다. 하나의 테스트 예제를 분류하기 위해 모든 학습 예제와 비교해야만 한다. 이것은 단점이다, 실제에서 우리는 자주 학습 시간을 효율적이게 하는 것보다 테스트 시간을 최적하는데 신경써야한다. 사실, 우리가 후에 개발할 딥러닝은 이 문제에 극단적으로 다른 면이다. 그들은 학습에 매우 큰 비용이 들고, 한번 학습을 완료하면, 새로운 테스트 예제를 분류하기 위해서는 매우 쉽게 된다. 이러한 작동 방식이 실제에서는 더 바람직하다.


최근접 이웃 분류기의 계산적 복잡함은 연구가 활발히 진행되고 있고, 몇가가 근사 최근접 이웃(approximate Nearest Neighbor ,ANN) 알고리즘과 라이브러리들이 존재해서 자료집합에서 최근접 이웃을 가속해서 찾을 수 있다. (e.g. FLANN) 이들 알고리즘은 검색 동안의 공간/시간적 복합도와 최근접 이웃의 정확성 사이의 상충관계에서 대게, k-means 알고리즘이나 kdtree 등과 같은 전처리와 인덱싱 단계에 의존한다.


최근접 이웃 분류기는 몇가지 문제에서는 좋은 선택이 될 수 있을 것이다(특히 자료가 저차원이라면), 그러나 이것은 실제 이미지 분류 설정에서는 매우 드믈게 사용된다. 한가지 문제는 이미지는 매우 고차원의 객체(그들은 매우 많은 픽셀을 갖는다)이고, 고차원의 공간에서의 거리는 매우 직관에 반대일 수 있다. 아래 이미지는 우리가 위에서 개발한 픽셀 기반의 L2 유사성이 인지적 유사성으로부터 매우 다른 것을 보여준다.



고차원 자료(특히 이미지들)에서 픽셀 기반 거리는 직관적이지 않을 수 있다. 원본 이미지(좌측) 과 3개의 다른 이미지들은 L2 픽셀 거리에서는 동등하게 떨어져 있지만, 명확하게 픽셀별 거리는 인지적이나 의미론적 유사성에 해당하지는 않는다.


여기에 픽셀 차이를 이용해 이미지를 비교하는 것이 불충한지 쉽게 보여주는 시각화가 있다. 우리는 이 시각화 기술을 t-SNE 라 부른다. 이것은 CIFAR-10 이미지들을 가지고 그들의 쌍별 거리를 잘 보전하는 2차원 공간에 임베드 시키는 것이다. 이 시각화에서 가까운 이미지들은 우리가 위에서 개발한 L2 픽셀별 거리에 따라 매우 가까운 이미지들로 생각한다.




CIFAR-10 이미지들을 t-SNE와 함께 2차원 공간에 임베드 시킴. 이 이미지에서 가까운 이미지들은 L2 픽셀 거리 기반으로 가까운 거로 생각한다. 배경의 강한 효과는 의미적 클래스 차이보다 더 크게 나타난다.  here 에 이 시각화의 더 큰 버젼이 있다.


각자에게 가까운 이미지들은 그들의 의미론적 식별보다 배경의 형태나 이미지들의 일반적 색 분포에 더 영향을 받는다. 예를 들어, 개는 흰색 배경이어서 개구리와 매우 가깝게 보인다. 이상적으로 우리는 변화나 개별특성(배경같은)에 관련 없이 그들의 클래스를 잘 나타내어 같은 클래스는 가까이 나타나게 하고 싶다. 그러나 우리가 이러한 특성읃기 위해서는 픽셀 기반을 넘어서야한다.


요약(summary)


우리는 이미지 분류의 문제를 소개했다.하나의 카테고리가 이름 붙여진 이미지 집합이 주어지고, 우리는 테스트 이미 집합에 대해 이들 카테고리를 예측하고, 예측 정확도를 측정한다.

우리는 최근접 이웃 분류기라 불리는 단순한 분류기를 소개했다. 우리는 다양한 하이퍼파라미터(k의 값이나 예제를 비교하는데 사용하는 거리의 유형)가 이 분류기와 관련있고, 이들을 선택하는 명확한 방법이 없음을 보였다.

우리는 학습 데이터를 둘(학습 집합과 검증집합이라 부르는 가짜 테스트 집합)로 나눠서 하이퍼 파라미터를 설정하는 올바른 방법을 보였다. 우리는 다른 하이퍼파라미터 값을 시도하고 검증 집합에 대해 가장 좋은 성능을 내는 값을 택한다.

만약 학습 데이터가 부족하다면, 우리는 교차검증이라 불리는 방법을 사용한다. 이것은 가장 좋은 하이퍼파라미터를 추정하는데에 있어서 노이즈를 줄여줄 것이다.

하이퍼 파라미터들을 찾으면, 우리는 그것을 고정시키고, 실제 테스트 집합에 대해 평가를 수행한다.

우리는 최근접 이웃이 CIFAR-10에 대해 약 40%의 정확도를 갖는 것을 보았다. 이것은 전체 학습 집합을 저장하기만 하면 되는 매우 단순한 구현이지만 테스트 이미지를 평가할 때 매우 큰 비용이 든다.

마지막으로, 우리는 픽셀값에 대한 L1이나 L2 거리를 사용하는 것이 불충분함을 보였다. 왜냐하면 거리는 그들의 의미적 맥락보다는 이미지의 색분포나 배경과 더 강하게 관련되어 있기 때문이다.


다음 강의에서 우리는 이들 문제를 해결하기 위해 90% 정확도를 갖고, 한번 학습이 학습 집합에 대해 완료되면, 테스트 이미지를 평가하는데 1000분의 1초보다도 더 작은 시간이 걸리는 모형을 개발할 것이다.


요약: 실제로 k NN 적용하기 (Summary: Applying kNN in practice)


만약 실제로 kNN을 적용하고 싶다면 다음의 과정을 따르라.


1. 자료를 전처리해라: 자료에서 특성들을 평균이 0이고 분산이 1로 정규화해라. 우리는 나중 장에서 이에 대해 논의할 것이고, 이장에서 자료의 정규화에 대해 얘기 안한 것은 이미지들에서 픽셀은 대게 동질적이고, 넓고 다른 분포가 아니기 때문이다.

2. 만약 너의 자료가 매우 고차원이라면, PCA(wiki refCS229refblog ref)나 Random Projections같은 차원축소 기법을 고려해라.

3. 너의 학습 자료를 랜덤하게 학습과 검증 집합으로 나누어라. 보통 70%-90% 정도는 학습으로 나눈다. 이 설정은 너가 가진 하이퍼파라미터의 수와 그들이 갖는 영향을 얼마나  볼 것인지에 달려있다. 만약 추정하고 싶은 하이퍼파라미터가 매우 많다면, 그들을 효율적으로 추정하기 위해 매우 큰 검증 집합을 선택하는 쪽이 낫다. 만약 너의 검증 자료의 수를 고려한다면, 학습 자료를 그룹으로 나누고 교차 검증을 수행하는 것이 최선일 것이다. 만약 너가 계산 비용을 감당할 수 있다면, 항상 교차 검증을 택하는 쪽이 안정하다(더 많은 겹은 더 좋지만, 더 많은 비용이 든다)

4. k의 많은 선택과 거리 지표에 대해 검증 자료로 kNN 분류를 학습하고 평가한다. 

5. 만약 너의 kNN 분류기가 너무 오래 돈다면, 근사 최근접 이웃 라이브러리를 사용해, 검색을 가속할 수 있다(정확도에 손실이 있긴함).

6. 가장 좋은 결과를 주는 하이퍼파라미터에 주의해라. 매우 큰 학습 자료 때문에 너의 학습 자료에 검증 데이터가 있었다면, 최적 하이퍼파라미터는 변할 수 있기 때문에 최적 파라미터를 전체 학습 자료에 사용할 것인지 하는 문제가 있다.  테스트 집합에 대해 최적 모형을 평가하고, 테스트 집합 정확도와 성능을 보고해라


더 읽을 것(Further Reading)


더 읽고 싶다면 관심있을 만한 거들이 있다.


A Few Useful Things to Know about Machine Learning, 특히 6장이 관련되어 있고, 전체 논문을 읽는 걸 추천한다


Recognizing and Learning Object Categories, ICCV 2005에서 객체 분류의 짧은 코스

출처:http://premium.chosun.com/site/data/html_dir/2016/04/01/2016040101289.html

random-160318051918.pdf



인간만이 갖고 있는 직관(直觀), 수많은 경험을 조합한 판단, 상대방이 두는 낯선 수에 대한 대응에 이르기까지 갓 태어난 알파고 앞에는 미지의 세계가 펼쳐져 있었다. 단지 기존의 인공지능처럼 계산 속도를 빠르게 하는 것만으로는 충분하지 않았다. 그래서 알파고는 사람처럼 바둑을 배우기 시작했다.

3주간 집중훈련

붙이면 젖혀라, 모자는 날일자로 벗어라…
행마·사활·기보를 ‘정책망’에 입력
인간의 뇌는 신경세포들의 연결체이다. 신경세포들은 전기신호를 주고받는다. 공부를 하거나 경험을 하면 신경세포의 연결망이 재조직되거나 연결 강도가 바뀌면서 기억이나 판단 능력이 생긴다. 알파고의 핵심 능력은 사람의 뇌를 본뜬 인공 신경망에서 나온다. 알파고의 인공 신경망은 크게 ‘정책망(policy network)’과 ‘가치망(value network)’으로 나뉜다. 먼저 세 종류의 정책망이 알파고가 만들어진 뒤 3주 동안의 집중 학습을 통해 형성됐다.
우선 ‘롤아웃(rollout) 정책망’에는 바둑의 기본이 들어 있다. 바둑에는 격언처럼 전해오는 일종의 규칙이 있다. ‘붙이면 젖혀라’, ‘젖히면 뻗어라’, ‘모자는 날일자로 벗어라’ 등 바둑을 배운 사람이라면 누구나 별다른 생각없이 가장 좋은 수로 여기는 규칙들이 롤아웃 정책망으로 학습된다. 이어 딥마인드는 알파고에게 아마추어 고수들이 인터넷에서 둔 바둑 기보(棋譜) 16만건을 공부시켰다. 특정한 상황을 보여주고 다음에 사람이 어디에 두었는지 맞히는 문제를 3000만개 풀었다. 이를 통해 얻은 경험은 ‘지도학습 정책망(supervised learning)’에 업데이트됐다.
하지만 16만건의 바둑 기보는 바둑을 알기엔 턱없이 부족하다. 이 때문에 알파고는 수없이 가상 대국을 두며 새로운 수를 찾았다. 알파고는 혼자서 하루에 3만번 바둑을 두면서 배운 것들을 하나하나 따져보고 검증했다. 기보에 없는 수를 둘 경우 어떻게 되는지, 어떤 수를 둬야 이길 확률이 높은지 자율학습을 통해 깨달은 것이다. 이 정보는 ‘강화학습(reinforcement learning) 정책망’에 쌓였다.
학생들이 수학을 배우는 과정에 비유하면 롤아웃은 공식, 지도학습은 연습 문제 풀이, 강화학습은 증명에 도전하는 과정이라고 할 수 있다. 어떤 상황에서 어떤 수가 좋다는 것을 알파고가 알게 된 것은 사람의 뇌에서 신경세포들의 연결이 변해 경험이 쌓이는 것과 비슷하다. 프로 바둑기사들은 다음에 둘 곳을 ‘직감’으로 몇 곳 추린 뒤 그 뒤에 벌어질 일을 예상해본다. 알파고는 정책망으로 프로기사처럼 다음 수를 어디에 둬야 좋은지 추릴 수 있게 됐다. 인간의 직관력을 흉내 내게 된 것이다.
이미지 크게보기
알파고가 착점하는 수에 따른 승률을 계산하는 가상도. /KBS

이기는 게임엔 무리수 안 둬

정책망을 통해 추려낸 수 후보들의 승률 분석
이 부분을 맡는 신경망이 ‘가치망’이다
알파고는 정책망으로 현재 상황에서 어떤 수가 좋다는 것은 비교적 잘 알게 됐지만, 전체적인 바둑이 유리한지 불리한지는 판단할 수 없었다. 형세를 판단할 수 없다는 뜻이다. 프로 바둑기사들은 ‘기분 좋은 형세’라는 말에서 알 수 있듯 감(感)으로 형세를 판단한다. 사람이 논리적으로 설명할 수 없는 것을 알파고에 입력하기는 힘들다. 알파고는 가치망이라는 또 다른 신경망을 이용, 정책망을 통해 추려낸 다음 수 후보들의 승률을 추정한다.
바둑판에서 한 점에 돌을 놓으면 그다음에 돌을 놓을 수 있는 다양한 점들이 나온다. 이 점들도 각각 그다음에 가능한 여러 점들을 쭉 나열할 수 있다. 이는 마치 한 가지에서 여러 가지가 계속 나오는 나무(트리) 모양새가 된다. 가치망에는 이와 같은 가지 중 일부를 선택하는 ‘몬테카를로 트리 서치(MCTS)’라는 방식이 사용된다. 다음 수 후보들을 뒀을 때 생겨나는 경우의 수 중 일부만을 무작위로 시뮬레이션해본 뒤 이를 근거로 승률을 얻어내는 방법이다. 마치 방송국에서 TV 프로그램 시청률을 집계하기 위해 일부 가구만 표본조사하는 것과 비슷하다. 시청률 조사는 많은 가구를 조사할수록 정확하다. 알파고는 후보 수마다 10만번에 이르는 시뮬레이션 결과를 얻어내는 것으로 알려져 있다. 가치망을 통해 알파고는 현재 상황에서 자신의 유불리를 파악할 수 있다. 정책망과 가치망을 활용해 알파고는 아무리 상대방이 최선의 수를 둬도, 그보다 더 승률을 높이는 수를 판단할 수 있게 됐다.



[출처] 본 기사는 조선닷컴에서 작성된 기사 입니다

출처: http://magazine.skcc.com/?p=4421


머신러닝과 딥러닝, 어떻게 다를까?

머신러닝이란 데이터를 분석해서 특정 패턴을 발견하고 이를 학습하는 모델을 구축하는 기술이다. 또 주어진 데이터에서 일반화된 지식을 추출하는게 목표다. 딥러닝 역시 이런 머신러닝의 일종이다. 다만 딥러닝은 이런 특정 패턴을 발견하고 학습하는 방식 자체가 자율학습이라는 게 가장 큰 차이다. 머신러닝은 데이터를 분석해서 패턴을 인지할 때 분류기를 사용한다. 이런 분류기는 인간이 직접 설계하고 정의한 것이다. 그렇기 때문에 정의되지 않은 내용에 대해서는 아무리 데이터에 다른 형태로 존재하는 패턴이 있더라도 반영되지 않는다.

이에 비해 딥러닝은 자율학습, 즉 인간이 만든 분류기가 아니라 전적으로 데이터에만 의존하는 학습이다. 주어진 데이터에 맞는 특징과 패턴을 추출할 수 있다는 얘기다. 딥러닝의 이런 장점은 구글이나 페이스북, 바이두 등 다양한 기업의 인공지능 기술에 활용되고 있다.

출처: http://deeplearning4j.org/kr-convolutionnets

컨볼루션 신경망을 적용한 하이퍼네트워크 개념망 생성.pdf


컨볼루션 네트워크

차례

컨볼루션 네트워크 소개

컨볼루션 네트워크는 그림이나 사진(이미지)에서 사물을 인식하는데 쓰이는 기술입니다. 예를 들어 사람의 얼굴이나 표지판, 동물, 식물, 자동차 등 온갖 종류의 사물이 그 대상이 될 수 있습니다. 또 문자나 단어를 인식하는데에도 쓰일 수 있으며, 더 나아가 음성 인식에서도 쓰이곤 합니다.

컨볼루션 네트워크(컨브넷)은 심층 신경망의 유행을 선도하고 있습니다. 최근에 있었던 컴퓨터 비전의 기술 발전은 거의 다 컨브넷과 관계가 있으며 자동 운전 기술, 각종 로봇 기술, 드론, 시각 장애인용 기술 등 산업계에도 크게 영향을 끼치고 있습니다.

이미지가 4차원 텐서인 이유

컨브넷은 이미지 데이터를 텐서 타입의 데이터로 받아들입니다. 참고로 텐서는 2차원 데이터인 행렬에 차원을 추가한 N-차원 어레이입니다.

4차원 텐서는 시각화하기가 까다롭습니다. 우선 간단한 비유를 통해 텐서를 설명 드리겠습니다. 일단, 스칼라 값은 숫자 하나에 해당하고(예: 7) 벡터는 숫자 여러 개의 어레이에 해당합니다(예: [7,8,9]). 그리고 행렬은 액셀 시트처럼 여러 행과 열을 숫자로 채운 것입니다. 차원으로 설명하면 스칼라는 0차원 점이고, 벡터는 1차원 선에 해당합니다. 행렬은 2차원 평면이 되고, 2차원 평면을 쌓으면 3차원의 직육면체가 됩니다. 그러면 이 직육면체를 이루고 있는 행렬의 성분(0차원 스칼라 값)을 벡터 형태의 피쳐 맵(Feature Map)으로 대체하면, 이 직육면체는 4차원 텐서가 됩니다. 예를 들어 볼까요? 우선 2x2 정방 행렬을 하나 만들어봅시다.

[ 1, 2 ] 
[ 5, 8 ]

텐서는 이 행렬의 각 성분을 더 큰 차원으로 바꿔주면 쉽게 만들 수 있습니다. 직육면체 형태의 3차원 텐서를 상상해보십시오. 액셀 시트를 두 장 포개놓은 것을 상상하시면 됩니다. 아래 그림은 2x3x2 크기의 텐서를 평면에 그려본 것입니다.

Alt text

이 텐서 데이터를 직접 코딩할 경우 [[[2,3],[3,5],[4,7]],[[3,4],[4,6],[5,8]]]가 됩니다. 아래 그림은 거대한 3차원 텐서를 입체적으로 그린 것 입니다.

Alt text

즉, 텐서는 어레이의 어레이라고 생각할 수 있습니다. 그리고 그 어레이를 또 다른 어레이에 넣어서 차원을 얼마든지 확장할 수 있습니다. 4차원 텐서는 그 중에서 그나마 간단한 형태라고 할 수 있습니다. 위의 그림에서 각 (스칼라)값을 벡터로 바꿔주면 전체 차원이 하나 증가하면서 4차원 텐서가 됩니다. 그리고 컨볼루션 네트워크는 4차원 데이터를 다룹니다. 아래 그림이 컨볼루션 네트워크가 다루는 4차원 데이터의 예 입니다.

Alt text

ND4J와 Deeplearning4j는 NDArray로 텐서를 표현합니다. 말 그대로 N차원 어레이를 담을 수 있는 데이터 타입으로, 이를 차수(order)를 이용해 표현하기도 합니다. 예를 들어 4차 어레이는 4차원의 어레이입니다.

이미지의 너비와 높이는 특별한 설명이 필요하지 않겠죠? 이미지는 너비와 높이만 있으면, 즉 2차원 행렬로 설명할 수 있지만 이미지 데이터는 3차원 행렬이 필요합니다. 이 세 번째 차원을 깊이(depth)라고 합니다. 깊이가 필요한 이유는 컴퓨터에서 이미지 데이터를 저장할 때 RGB(Red-Green-Blue)로 인코딩을 하기 때문입니다. 즉, 각 Red/Green/Blue 색깔 별로 2차원 행렬이 하나씩 필요합니다. 이 3가지 색깔을 나타내는 깊이 차원을 채널이라고도 합니다. 따라서 이미지 데이터는 3개의 채널로 이루어져 있습니다. (한편 컨브넷의 층에서는 더 많은 채널을 사용해 피쳐를 나타내며 이를 피쳐 맵이라고 합니다. 자세한 설명은 뒤에 이어집니다.)

이렇게 한 장의 이미지는 3차원 데이터로 나타낼 수 있습니다. 그런데 컨브넷 트레이닝 과정에서는 여러 장의 이미지를 사용하는 경우가 일반적입니다. 결과적으로 우리가 가진 이미지 데이터는 3차원 데이터의 어레이, 즉 4차원 텐서가 되는 것 입니다.

컨브넷 정의

컨볼루션의 어원은 라틴어 convolvere이고 그 뜻은 두 가지를 같이 돌돌 마는 행동을 의미합니다. 수학에서 컨볼루션은 두 가지 함수가 얼마나 겹치는지를 적분을 이용해 측정하는 것 입니다. 두 함수를 하나로 합치는 것이라고 이해해도 됩니다.

이 링크의 애니메이션을 보면 더욱 정확히 이해할 수 있습니다. 링크의 애니메이션은 x축 방향으로 함수 f(붉은 색)과 함수 g(파란 색)가 얼마나 겹치는지를 컨볼루션을 통해 구하는 과정입니다. 그리고 그 결과가 초록색 함수입니다. 두 함수가 얼마나 겹치는지를 측정하기 위해 우선 빨간색 함수 f를 고정시키고 파란색 함수 g를 x축으을 따라 이동시키면서 두 함수를 곱해준 것 입니다.

컨볼루션 네트워크에서, 우리는 이미지를 고정시키고 필터를 이동해가면서 이미지를 쭉 훑습니다. 그리고 훑어가면서 각 위치에서 행렬의 성분끼리 곱해주는 것이 컨브넷의 컨볼루션 과정입니다. Andrej Karpathy의 애니메이션을 보시면 더욱 정확히 이해할 수 있습니다. 링크의 “Convolution Demo”를 참고하십시오.

컨브넷에서는 하나의 이미지에 여러 가지 다양한 필터를 컨불루션 하는데, 각 필터는 서로 다른 모양을 잡아내는 역할을 합니다. 초기 단계의 컨볼루션 층에서는 수평선, 수직선, 대각선 등 단순한 모양을 잡아냅니다. 그리고 그 정보를 모으면 이미지의 아웃라인을 그려낼 수 있습니다.

이렇게 다양한 종류의 필터를 이용하면 이미지의 피쳐맵을 만들 수 있습니다. 피쳐맵이란 말 그대로 어디에 어떤 피쳐가 있는지 지도를 그리는 것 입니다. 예를 들어, 수평선을 잡아내는 필터를 사용한 피쳐맵은 각 이미지에서 어디에 수평선이 있는지를 나타내는 피쳐맵이 됩니다.

(이 작동 방식은 RBM과 매우 다릅니다. RBM은 이미지 전체를 보고 피쳐를 잡아내는 반면 컨브넷은 이미지를 작은 부분으로 나누어 피쳐를 뽑아냅니다.)

즉, 컨브넷은 이미지 위에서 특정한 모양을 검색한다고 할 수 있습니다. 작은 돋보기를 들고 큰 이미지를 위에서 아래로, 왼쪽에서 오른쪽으로 차근차근 훑어 나가는 과정을 생각해보십시오. 그리고 그 돋보기로 수직선 찾아 다닌다고 생각해보십시오. 즉 작은 수직선 전문 필터로 이미지 전체를 쭉 훑어 나가는 것 입니다.

그리고 수직선이 발견되면 그 결과를 피쳐맵에 반영합니다. 즉, 피쳐맵에는 어디에서 수직선이 발견되었는지를 기록합니다. 마치 보물지도에서 어디에 보물이 있는지를 점으로 찍어놓는 것 처럼 말입니다. 그리고 컨브넷은 수직선, 수평선, 대각선 작업에 필요한 다양한 모양을 찾아서 각각을 피쳐맵에 저장합니다.

이렇게 모든 위치에서 다양한 필터로 컨볼루션을 수행하기 때문에 컨브넷의 연산량은 꽤 많은 편입니다.

컨볼루션 층 하나를 통과하고 나면, 비선형 함수를 하나 거치게 됩니다. 하이퍼탄젠셜(tanh) 함수나 *ReLU(Rectified Linear Unit) 등이 이 비선형 함수에 해당합니다. 이 비선형 함수는 입력 데이터를 -1에서 1 사이의 값으로 압축해주는 역할을 합니다. (ReLU의 경우 조금 다르게 이를 수행합니다.)

컨볼루션과 컨볼루션 층

우선 컨브넷이 이미지를 처리하는 방식은 사람이 이미지를 보는 것과는 조금 다르다는 것을 알아야 합니다. 컨브넷이 이미지를 어떻게 보는지 설명드리겠습니다.

컨브넷은 이미지를 부피가 있는 3차원의 직육면체로 봅니다. 위에서 설명드렸듯이 이는 이미지 데이터가 3차원 행렬로 저장되기 때문입니다. 우리가 보는 이미지는 3개 채널의 R, G, B값을 합친 색깔이지만 데이터에서는 이를 따로 저장해야 하는 것 입니다. 최초에 컨브넷이 보는 이미지는 3장의 이미지를 포개놓은 형태입니다.

이미지의 너비와 높이는 가로/세로에 있는 이미지의 픽셀 수가 됩니다. 그리고 깊이, 혹은 채널 수는 3개가 됩니다.

이미지가 컨볼루션 층을 통과하면 우리는 이 입력/출력 데이터의 부피를 따져볼 수 있습니다. 일반적으로 30x30x3과 같이 가로x세로x깊이(채널)의 형태로 이 부피를 표기합니다. 그리고 데이터의 부피는 층을 통과할 때 마다 달라지는 경우가 많이 있습니다.

앞으로 각 층을 거칠때마다 이미지의 부피가 변하는데 이 숫자를 눈여겨보시기 바랍니다.

정리하면, 이미지 데이터에서 행렬의 각 성분은 (R,G,B)의 세기를 표현하는 벡터로 이루어져 있습니다.

이 (R,G,B)값은 컨볼루션 네트워크의 입력 값이 됩니다. 즉 컨볼루션 네트워크는 이 이미지를 보게 됩니다. 이 입력 데이터도 피쳐 중에서 네트워크가 감지하는 감응 피쳐라고 생각할 수도 있습니다. 그리고 일반적인 뉴럴넷과 마찬가지로 컨브넷은 이 숫자를 보고 이미지를 분류하는데 필요한 의미있는 신호를 감지하는 작업을 합니다.

컨브넷은 보통 이미지의 일부분을 정방형으로 잘라서 (이 잘린 부분을 패치라고 함) 필터에 통과시킵니다. 필터는 패치와 같은 크기입니다. 필터는 때론 커널이라고 불리기도 하는데 SVM에서 사용하는 커널과 같은 의미입니다. 즉, 이 필터는 픽셀에서 (혹은 피쳐맵에서) 원하는 패턴을 찾아줍니다.

이 애니메이션은 Andrej Karpathy가 만든 컨볼루션 데모입니다.*

30x30의 행렬(이미지)와 3x3의 행렬(필터)을 상상해 보십시오. 즉, 이 필터는 이미지의 1/3 길이로 된 필터입니다.

이제 이미지에 필터를 곱하려고 합니다. 이 곱(dot product)은 행렬곱이 아니라 성분끼리 곱하는 곱셈(element-wise multiplication)이라는 점을 유의하세요. 따라서 만일 두 행렬이 같은 위치에서 큰 값을 가지고 있다면 그 위치의 계산 결과도 큰 값이 나올 것입니다 (100x100). 반대로 둘 중 하나만 값이 크다면 작은 결과가 나오고 (100x1), 둘 다 작다면 더욱 더 작은 값이 나오게 됩니다 (1x1). 그러므로 특정한 값을 갖는 필터를 이용하면 어떤 위치에서 이미지의 픽셀 패턴이 필터와 얼마나 비슷한지를 구할 수 있습니다. 이는 상관계수(correlation)을 구하는 과정과도 같습니다.

예를 들어 우리의 필터가 수평선 패턴이라고 생각해봅시다. 가장 쉬운 예는 [[0,0,0],[1,1,1],[0,0,0]] 필터입니다. 맨 위와 아래 행은 작은 값을, 가운데 행은 큰 값을 갖는 행렬은 수평선 패턴 필터로 작동하게 됩니다. 이제 이 필터를 왼쪽 위에서부터 오른쪽 아래까지 쭉 이미지를 훑어 내려온다고 생각해 보십시오. 이렇게 훑어 내려올 때, 한 칸씩 옮겨가며 곱셈을 수행할 수도 있지만 더 여러 칸씩 옮겨가며 곱셈을 수행하기도 합니다. 이렇게 필터를 몇 칸씩 옮겨 가는지를 stride라고 부릅니다. 예를 들어 stride=2라고 지정한 경우에 두 칸씩 옮겨가며 곱셈을 수행합니다.

자리를 옮겨갈때마다 곱셈을 수행하고, 그 결과를 액티베이션 맵(activation map)에 저장합니다. 따라서 활동 맵의 크기는 가로/세로로 곱셈을 수행한 횟수와 같습니다. stride값이 크면 액티베이션 맵의 크기가 작아지고, stride가 작으면 맵의 크기가 커집니다. 이 내용은 컨브넷을 디자인할 때 아주 중요합니다. stride가 작을 수록 많은 곱셈을 수행해야 하는데, 컨볼루션 네트워크는 연산량이 많이 필요하기 때문에 이 값을 적절히 조절해 주어야 합니다.

만일 stride가 3이라면 이 필터는 이미지의 1-3행에서 곱셈을 수행한 뒤 이미지의 4-6행으로 옮겨서 다시 곱셈을 수행할 것 입니다. 결과적으로 입력 이미지는 30x30이었지만 출력으로 나온 액티베이션 맵은 10x10 행렬이 됩니다. 위에서 설명한 수평선 필터는 R, G, B채널 3개를 모두 훑으며 수평선이 있는지를 각각 계산합니다. 그리고 최종적으로 이 수평선 필터가 만드는 한 액티베이션 맵은 R, G, B를 훑은 결과의 평균이 됩니다.

이미지는 수평선 뿐만 아니라 다양한 방향의 선으로 이루어져 있습니다. 따라서 수평선 필터 뿐만 아니라 다른 모양의 필터도 사용해야 합니다. 예를 들어 컨브넷이 96개의 다른 패턴을 조사해서 96개의 액티베이션 맵을 만들도록 디자인 할 수 있습니다. 즉 최종 결과는 10x10x96 행렬이 됩니다. 아래 그림을 참고하십시오.

Alt text

그동안 컨볼루션에 대해 자세히 다뤘습니다. 내용을 잘 이해했으면 컨볼루션을 복잡한 개념이 아니라 그저 두 행렬의 성분끼리 곱하는 것으로 편하게 생각하면 됩니다.

이미지는 데이터의 크기가 크기 때문에 이미지를 처리할 때에는 늘 연산량에 신경써야 합니다. 컨볼루션 네트워크는 여러 가지 방법을 사용해 이미지의 크기를 줄입니다. 위의 컨볼루션 네트워크에서 stride를 통해 결과로 나오는 행렬(액티베이션 맵)의 크기를 줄이는 방법을 소개했습니다. 또 다른 방법은 다운 샘플링입니다.

맥스 풀링/다운 샘플링

이 층은 맥스 풀링(max pooling), 다운 샘플링(downsampling), 서브 샘플링(subsampling) 등 여러 이름을 가지고 있습니다. 위의 컨볼루션 층의 결과로 나온 액티베이션 맵은 일반적으로 다운 샘플링 층의 입력이 됩니다. 다운 샘플링 과정은 컨볼루션 층과 비슷하게 작은 패치 단위의 연산을 여러 번 수행하도록 되어있습니다. 컨볼루션 층과 달리 여기에선 행렬 곱보다 훨씬 간단한 작업을 합니다. 맥스 풀링은 이미지 패치에서 최대값을 결과로 출력합니다.

Alt text위의 이미지는 Andrej Karpathy가 만든 이미지입니다.

따라서 패치 내에서 제일 큰 액티베이션 값만 결과로 남고 나머지는 버려집니다. 컨볼루션의 역할을 생각하면, 패치 내의 여러 위치 중에서 필터의 패턴과 가장 잘 일치하는 부분만 살아남게 됩니다.

결과적으로 최대값이 아닌 나머지 모든 정보가 버려지고, 이를 대체하는 다른 방법도 많이 연구되고 있습니다. 어쨌든 이 다운 샘플링 과정을 통해 데이터의 크기가 작아지므로 메모리와 연산량에서 큰 이득을 보게 됩니다.

여러 층을 조합하는 방법

아래 그림은 컨볼루션 네트워크 전체를 시각화한 것 입니다.

Alt text

왼쪽부터 구성 요소를 살펴보겠습니다.

  • 입력 이미지가 들어오면 필터를 통과합니다. 위의 그림에서는 액티베이션 맵이 아닌 피쳐맵으로 표시되었습니다.
  • 필터가 여러 종류이기 때문에 액티베이션 맵도 여러 종류의 맵을 쌓게됩니다.
  • 그리고 그 맵은 다운 샘플링 과정에서 더 작게 압축됩니다.
  • 그 결과가 C1에 해당합니다.
  • 그 뒤를 새로운 컨볼루션 층과 다운 샘플링 층이 잇게 되고 최종적으로 C2가 나옵니다.
  • 마지막으로 이렇게 나온 피쳐맵은 일반적인 인공 신경망의 층(Fully-connected layer)로 들어갑니다. 그 결과로 분류하려는 라벨 하나당 노드 하나씩 값을 출력합니다.

여러 단계를 지날수록 처음 이미지에 있던 정보는 손실되고, 대신 특정 패턴이 어디에 존재하는지만 남게 됩니다. 이 과정이 직관적이지 않더라도 자세히 살펴보시기 바랍니다.

DL4J 예제 코드

아래 예제를 참고하면 Deeplearning4j에서 어떻게 컨브넷을 사용할 수 있는지 알 수 있습니다.

그 외 참고 자료

다른 초보자 가이드


출처: http://scienceon.hani.co.kr/376916


몬테카를로 트리서치, 무작위 시뮬레이션 통해 승률계산

00dot.jpg 

몬테카를로 트리 서치, 이게 뭘까? 설명 자료를 찾다보면, 조금씩 이해할 수 있습니다. 엄청나게 많은 수를 일일이 다 다루지 않더라도 그 가운데에서 샘플링을 하여 확률적 연산을 수행함으로써 최선의 수를 찾아가는 기법으로 알려져 있습니다. 게임 프로그램에서는 이미 많이 사용된다고 합니다.


요즘 제가 인공지능과 관련해 궁금한 점을 자주 여쭙곤 하는 유신 교수께 물었더니 대강 이런 설명을 해주시는군요.


“둘 만한 수가 5개가 있다고 칩시다. 그러면 컴퓨터는 각각의 경우를 다 살펴보고서, 그 가운데 아주 조금이라도 승률이 높은 수를 선택합니다. 그런데 승률을 계산하는 과정에 샘플링이 들어가지요. 가능한 수 5개 가운데 제1번 수를 둘 때, 이후에도 무수한 수가 펼쳐질 겁니다. 그러니 컴퓨터는 제1번 수를 두고 이어서 이렇게 두는 방법, 저렇게 두는 방법 등등으로 많을 텐데 무작위로 100번, 1000번을 둔다고 해봅시다. 거기에서 승률을 얻습니다. 제2번 수를 둘 때도 마찬가지로 계산을 합니다. 이렇게 제3번 수, 제4번 수, 제5번 수를 두고서 얻어진 승률을 비교해, 가장 높은 수치의 수를 선택할 수 있습니다.” (전화통화 정리)


몬테카를로 방법이 확률적 연산과 관련이 있다는 것으로 이해됩니다. 무작위로 샘플링한 시뮬레이션을 해보고서 거기에서 승률을 얻으니까요. 샘플링을 10개 할 때와 100개, 1000개… 100만 개… 해서 승률을 계산할 수 있다면 훨씬 더 좋겠지요. 더욱 빠른 컴퓨터가 있다면 정해진 시간 안에 지금 두려는 수의 승률을 근사적으로 미리 파악할 수 있을 테니까요.


이런 몬테카를로 방법은 게임 프로그램의 알고리즘을 만들 때에 많이 응용되고 있는 듯합니다. 이미 시중에 나온 바둑 프로그램들이 이런 방법을 활용하니까요.


그런데, 알고리즘의 측면에서 보자면 기존 바둑 프로그램에는 없던 바둑 고수 알파고만의 비결이 따로 있습니다. 그게 이름도 생소한 “딥러닝(deep learning, 심화학습)”이라는, 최근 인공지능 분야에서 인기를 얻고 있는 알고리즘 기법이 아닌가 합니다. 그러니 알파고 바둑 프로그램에서 새롭게 탑재된 위력의 무기는 “딥러닝”이라고 말해도 지나치지 않을 듯합니다.



+ Recent posts