기존 완전연결 계층의 문제점은 데이터의 형상이 무시된다는 것. 예를 들면 (가로, 세로, 채널) 3차원 형태의 컬러 이미지 데이터가 들어오더라도 반드시 1차원 데이터로 변환하여 사용해야 했음.
반면, 합성곱 계층은 데이터의 형상을 유지하므로 형상을 통해 의미를 갖는 특징들을 살릴 수 있음!
특징 맵: 합성곱 계층의 입출력 데이터. (입력 특징 맵 & 출력 특징 맵)
합성곱 연산: 입력 데이터에 필터를 적용하는 필터 연산의 일종. 그림은 2차원 데이터에 대한 합성곱 연산의 예시이다.
필터를 입력 데이터 위에 겹쳐놓고 각 원소쌍끼리 곱한 후 그 총합을 상응하는 위치의 출력으로 저장함. (= 단일 곱셈-누산) 이 과정을 필터 윈도우를 일정 간격으로 이동해나가며 반복함.
CNN에서는 필터의 매개변수가 그동안의 '가중치'에 해당하며, '편향'은 항상 하나(1×1)만 존재하여 필터를 적용한 모든 원소에 더해짐.
패딩: 필터를 적용할수록 출력의 크기가 계속 줄어드는 것을 막기 위해, 입력 데이터 주변을 특정 값으로 채워 크기를 늘리는 기법.
스트라이드: 필터 적용 과정에서 필터의 이동 간격. 스트라이드가 커질수록 필터가 크게 크게 이동하므로 출력의 크기는 작아짐.
출력 크기 = (입력 크기 + 2*패딩 - 필터 크기)/스트라이드 + 1
컬러 이미지와 같은 3차원 데이터에 대한 합성곱 연산의 경우, 입력 데이터의 채널 수만큼 필터의 채널 수 역시 늘어남. (ex. 3채널 이미지 ⇒ 필터 3장)
필터 자체의 크기는 자유롭게 정할 수 있지만 모든 채널의 필터는 같은 크기여야 함.
이때 출력은 하나이며, 그 값은 각 채널끼리 수행된 합성곱 연산 결과의 총합임.
만약 출력 데이터를 한 장이 아닌 여러 장의 특징 맵으로 만들고 싶다면, 그만큼 필터를 여러 개 사용하면 됨. (⇔ 필터 하나를 구성하는 채널 수와 구분!)
이때 합성곱 연산에서도 배치 처리를 위해 각 계층을 흐르는 데이터의 차원을 하나 늘려 4차원 데이터 (데이터 수, 채널 수, 높이, 너비) 형태로 저장할 수도 있음. (데이터 N개에 대한 합성곱 연산 수행)
풀링 계층
세로 및 가로 방향의 공간을 줄이는 연산을 수행하는 계층. 이미지 인식 분야에서는 주로 최대 풀링(주어진 영역에서 최댓값을 구하는 연산)을 사용함.
풀링 계층의 특징: 따로 학습해야 할 매개변수가 없음, 입력 데이터의 채널 수를 그대로 유지함, 입력의 변화에 영향을 적게 받음 (강건함)
합성곱 계층 구현하기
합성곱 연산을 원래 데이터 형태 그대로 수행하려면 복잡한 중첩 for 문이 필요하다. 하지만 만약 (배치 차원을 포함한) 4차원 입력 데이터를 필터가 적용되는 영역마다 한 줄로 전개하여 2차원 행렬 형태로 변환한다면 연산이 훨씬 용이해진다.
이때 필터가 적용되는 영역은 겹칠 수도 있으므로 전개 후의 원소 수가 원래 블록의 것보다 더 많아질 수 있음.
책에서는 해당 변환 과정을 im2col() 함수로 정의하여 사용한다. 역전파 단계를 위한 역변환 함수인 col2im()도 존재한다. (GitHub)
im2col의 정확한 동작 방식에 대한 이해는 이 게시글을 참고하자. 핵심은 필터의 각 원소(위치)를 순회하면서, 해당 위치의 연산에 관여되는 입력 데이터 원소들을 인덱싱을 통해 가져오는 것이다.
이후 각 필터 역시 세로로 한 열씩 전개하여 2차원 행렬로 변환한 후 입력 데이터와 내적을 수행하고, 그렇게 계산된 출력 행렬을 다시 4차원 데이터로 변형(reshape)하면 된다.
np.reshape(): 인자로 -1을 지정하면 다차원 배열의 원소 수가 변환 후에도 똑같이 유지되도록 적절히 묶어줌.
np.transpose(): 인자로 주어진 인덱스에 맞게 다차원 배열의 축 순서를 바꿔줌.
풀링 계층 구현하기
마찬가지로 입력 데이터를 2차원 행렬로 전개하는 것은 같으나, 이때는 각 채널별로 독립적으로 전개한 후 쭉 이어붙인다는 점이 다르다.
풀링 영역마다 한 줄로 만들고, 이후 행별 최댓값을 구하여 적절한 형상으로 변환한다.
np.max(): 인자로 축(axis)을 지정하면 해당 축마다 최댓값을 구할 수 있음.
합성곱/풀링 계층의 실제 구현 코드는 본 책의 GitHub을 참고하고, 전체 과정을 그림으로 요약하면 이렇다.
그래서 CNN은?
CNN 구조에서 '가중치'의 역할을 하는 것은 필터다. 필터가 무엇을 학습했는지가 궁금하다면 이를 이미지로 시각화해보면 된다.
학습 전엔 무작위 노이즈에 가까웠던 모습이 학습 후에는 흰색에서 검은색으로 점차 변화하는 픽셀(에지)과 이들이 모여 덩어리진 형태(블롭)를 이루는 등 특정한 패턴을 띠게 되며, 이렇게 학습된 필터를 입력 이미지에 합성곱 처리하면 해당 필터가 '무엇을 보고 있는지'를 알 수 있다. (원본 이미지에 대해 필터가 반응하는 부분이 높은 값으로 나옴)
또한 깊은 계층으로 들어갈수록 필터는 점차 복잡하고 추상화된 정보를 학습하게 된다고 한다. (ex. 단순한 에지/블롭 → 텍스처 → 사물의 일부)
책에서는 대표적인 CNN으로 다음 두 가지를 소개한다. 네트워크 구성 면에서 둘은 크게 다르지 않으나, 빅 데이터와 GPU가 딥러닝 발전의 큰 원동력이었음을 강조하고 있다.
LeNet (1998)
합성곱 계층과 풀링 계층을 반복하고 마지막으로 완전연결 계층을 거쳐 결과를 출력
활성화 함수로 시그모이드 함수 사용
서브샘플링을 통해 중간 데이터의 크기를 줄임
AlexNet (2012)
활성화 함수로 ReLU 이용
국소적 정규화(LRN, Local Response Normalization) 계층 이용
드롭아웃 사용
8. 딥러닝
기존 신경망에서 정확도를 높이는 기법들로는 앙상블 학습, 학습률 감소, 데이터 확장 등이 유명하다.
데이터 확장: 훈련용 이미지를 알고리즘을 통해 인위적으로 확장하여 개수를 늘리는 것. (ex. 크롭, 좌우반전 등등)
한편, 층을 깊게 한 '심층 신경망'을 딥러닝이라고 하며, 그 이점은 다음과 같다.
층이 얕은 신경망보다 더 적은 매개변수로 그 이상의 표현력을 달성할 수 있음. (넓은 수용 영역)
정보를 계층적으로 분해하여 각 층이 학습해야 할 문제를 더 단순한 문제로 대체할 수 있음.
즉, 학습에 필요한 데이터의 양을 줄여 더 고속으로 학습을 수행할 수 있음.
대강 직관적으로 이해해 보자면, '얕은 층에서 한꺼번에' 학습하는 것보단 '깊은 층에 걸쳐 나눠서' 학습하는 것이 더 효율적이면서 높은 성능을 보인다는 뜻 같다.
딥러닝의 초기 역사
다음은 100만 장이 넘는 이미지를 담고 있는 데이터셋인 이미지넷을 활용한 대회 'ILSVRC'에서 우수한 성적을 거둔 3개의 유명한 신경망이다.
VGG: 합성곱 계층과 풀링 계층으로 구성되는 기본적인 CNN.
합성곱 계층 및 완전연결 계층을 총 16층(VGG16) 또는 19층(VGG19)으로 심화함.
3×3의 작은 필터를 사용한 합성곱 계층을 2~4회 연속으로 거치며 크기를 절반으로 줄이는 처리를 반복함.
GoogLeNet: '인셉션 구조'를 하나의 빌딩 블록(구성요소)으로 사용함.
인셉션 구조: 하나의 계층에 대해 크기가 다른 필터와 풀링을 여러 개 적용하여 결과를 결합함.
1×1 필터를 이용한 합성곱 연산을 통해 채널 쪽으로 크기를 줄여 매개변수 제거와 고속 처리에 기여함.
ResNet: VGG 기반에 '스킵 연결'을 도입하여 층의 깊이에 비례해 성능을 향상시킴.
스킵 연결: 입력 데이터를 합성곱 계층을 건너뛰어 출력에 바로 더하는 (그대로 흘리는) 구조.
역전파 때도 상류의 기울기에 아무런 수정을 가하지 않고 그대로 하류로 보내므로 기울기 소실 문제를 줄여줌.
전이 학습: 학습된 가중치 전체 또는 일부를 다른 신경망에 복사한 후, 그 상태로 새로운 데이터셋에 대하여 재학습(fine tuning)을 수행하는 것. 보유한 데이터셋이 적을 때 유용한 방법이다.
딥러닝 고속화
딥러닝에서는 합성곱 계층에서 단일 곱셈-누산(또는 큰 행렬의 내적)을 수행하는 데에 대부분의 시간을 소요한다. 이 연산 과정을 최대한 빠르게, 효율적으로 해내는 것이 중요하다.
GPU 컴퓨팅: 기존 CPU 대신 대량의 병렬 작업을 고속으로 처리할 수 있는 GPU에게 범용 수치 연산을 수행시키는 것.
분산 학습: 수많은 시험 반복을 위해서는 1회 학습에 걸리는 시간을 단축해야 함. → 수평 확장! 프레임워크의 힘을 빌려 다수의 GPU와 기기로 계산을 분산시킬 수 있음.
연산 정밀도와 비트 줄이기: 메모리 용량을 줄이고 버스 대역폭 병목을 막기 위해 중간 데이터의 크기를 최소화해야 함. 딥러닝은 높은 수치 정밀도를 필요로 하지 않으므로 16비트 반정밀도면 충분.
딥러닝의 활용
딥러닝은 이미지, 음성, 자연어 등 수많은 분야에서 뛰어난 성능을 발휘한다. 컴퓨터 비전 분야를 중심으로 몇 가지 소개된 활용 예시는 다음과 같다.
사물 검출: 이미지 속에 담긴 사물의 위치와 종류(클래스)를 알아내는 것. '이미지 어딘가에 있을 사물의 위치'까지 알아내야 하므로 일반적인 사물 인식 문제보다 어려움.
R-CNN(Regions with CNN): 이미지에서 먼저 사물이 위치한 '후보 영역'을 찾아내고, 추출한 각 영역에 CNN을 적용하여 클래스를 분류하는 기법.
분할: 이미지를 픽셀 단위로 식별하여 분류하는 문제. 픽셀 위로 객체마다 채색된 지도 데이터를 사용해 학습하며, 추론 시 입력 이미지의 모든 픽셀을 분류함.
FCN(Fully Convolutional Network): 기존 CNN에서의 완전연결 계층을 같은 기능을 하는 합성곱 계층으로 바꾼 버전. 모든 픽셀 각각을 추론하는 대신 단 한 번의 순전파 처리로 모든 픽셀을 분류할 수 있음.
사진 캡션 생성: 사진을 주면 사진을 설명하는 글을 자동으로 생성함.
NIC: 심층 CNN으로 사진에서 특징을 추출하고, 자연어를 다루는 순환 신경망(RNN)에 특징을 넘겨 텍스트를 생성하게 함. (⇒ 멀티모달 처리)
딥러닝의 미래
이미지 화풍 변환: 스타일 이미지와 콘텐츠 이미지를 받아 둘을 조합해 새로운 이미지를 생성함. 네트워크의 중간 데이터가 콘텐츠 이미지의 중간 데이터와 비슷해지도록 학습하는 식으로 동작.
이미지 생성: 먼저 대량의 이미지를 사용해 학습한 후, 아무런 입력 이미지 없이도 새로운 그림을 그려냄. 생성자와 식별자로 불리는 2개의 신경망을 서로 무한 경쟁시키는 GAN 기술 이용. (⇒ 자율 학습)
자율 주행: CNN 기반 신경망 SegNet은 입력 이미지를 분할(픽셀 수준에서 판정)하여 주변 환경을 정확하게 인식할 수 있음.
Deep Q-Network: 딥러닝을 사용한 강화학습 방법 중 하나. 'Q학습'이라는 강화학습 알고리즘을 기초로 함.
정리
이번 5~8장에서는 신경망의 학습 원리 중 핵심적인 부분인 오차역전파법을 알아보고, 그동안 나온 각 계층들과 순전파/역전파 과정을 실제 작성된 코드를 통해 이해하는 시간을 가졌다.
또한 매개변수 갱신이나 가중치 초깃값 설정 등 여러 학습 관련 기술들과, 컴퓨터 비전 분야에서 매우 중요하게 다뤄지는 CNN의 개념도 배울 수 있었다.
프레임워크를 사용하지 않고 낮은 수준의 코드부터 실제 동작하는 간단한 신경망까지를 차근차근 구현해 보면서 딥러닝에 대한 이해를 높일 수 있었던 좋은 책이었다. 다시 한번 내용을 복습하면서 이해가 부족한 부분을 중심으로 더 공부해 봐야겠다.