ANN, DNN, CNN, RNN은 무엇이 다를까

ANN, DNN, CNN, RNN을 같은 분류로 외우지 않고, 깊이와 연결 구조라는 기준으로 나누어 동작 방식과 쓰임을 정리합니다.

신경망을 공부하다 보면 ANN, DNN, CNN, RNN이라는 이름을 한꺼번에 만나게 된다.

처음에는 네 가지가 같은 기준으로 나뉜 모델처럼 보인다. ANN 다음에 DNN이 나오고, 그다음 CNN과 RNN이 등장한 것처럼 외우기도 쉽다. 하지만 이렇게 외우면 CNN이 DNN인지 아닌지부터 헷갈리기 시작한다.

먼저 분류 기준을 나눠보자.

ANN: 인공 신경망이라는 가장 넓은 범주
DNN: 은닉층을 여러 겹 쌓았다는 깊이에 대한 표현
CNN: 가까운 위치의 패턴을 같은 필터로 찾는 연결 구조
RNN: 이전 시점의 상태를 다음 시점으로 넘기는 연결 구조

따라서 여러 층으로 쌓은 CNN은 CNN이면서 DNN이고, 깊게 쌓은 RNN도 RNN이면서 DNN이다. DNN, CNN, RNN을 서로 겹치지 않는 세 상자로 보면 안 되는 이유다.

이름을 나누는 두 가지 기준
ANN · Artificial Neural Network 학습 가능한 가중치로 입력을 출력에 매핑하는 인공 신경망의 넓은 범주
MLP 층과 층을 fully connected 방식으로 연결한다.
CNN 공간적으로 가까운 값에 같은 filter를 적용한다.
RNN 이전 시점의 hidden state를 다음 시점에 전달한다.
위 구조를 여러 층으로 깊게 쌓으면 모두 DNN · Deep Neural Network이라고 부를 수 있다.

ANN: 시작은 가중합과 활성화 함수다

ANN은 Artificial Neural Network, 즉 인공 신경망을 뜻한다. 문맥에 따라 단순한 fully connected network를 ANN이라고 좁게 부르기도 하지만, 보통은 CNN과 RNN까지 포함하는 상위 개념으로 보는 편이 관계를 이해하기 쉽다.

가장 작은 계산 단위부터 보자. 하나의 뉴런은 입력에 가중치를 곱하고 bias를 더한 뒤 activation function을 통과시킨다.

\[z = \mathbf{w}^{\mathsf T}\mathbf{x} + b\] \[a = \sigma(z)\]

x는 입력, w는 입력마다 적용할 가중치, b는 기준점을 옮기는 bias다. sigma에는 ReLU, sigmoid, tanh 같은 비선형 함수가 들어간다.

왜 비선형 함수가 필요할까?

선형 변환을 여러 번 이어 붙여도 결과는 다시 하나의 선형 변환이 된다.

\[W_2(W_1x) = (W_2W_1)x\]

층을 아무리 많이 쌓아도 activation function이 없다면 복잡한 경계를 표현하기 어렵다. 각 층 사이에 비선형성을 넣어야 여러 층을 쌓는 의미가 생긴다.

신경망은 무엇을 학습할까

학습 전에 가중치는 정답을 모른다. 입력을 순방향으로 계산해 예측값을 만들고, 정답과 비교해 loss를 구한 뒤, 그 loss가 줄어드는 방향으로 각 가중치를 조정한다.

입력 x
  -> forward propagation
예측 y_hat
  -> loss(y, y_hat)
오차
  -> backpropagation
각 parameter의 gradient
  -> optimizer
갱신된 W, b

Backpropagation은 학습률이나 optimizer까지 포함한 전체 학습 방법의 이름이 아니다. 계산 그래프의 chain rule을 이용해 각 parameter에 대한 gradient를 효율적으로 구하는 알고리즘이다. 실제 parameter 갱신은 SGD, Adam 같은 optimizer가 맡는다.

가장 단순한 gradient descent는 다음과 같이 쓸 수 있다.

\[\theta \leftarrow \theta - \eta \nabla_{\theta}L\]

theta는 모든 학습 parameter, eta는 learning rate다. 여기까지가 MLP, CNN, RNN이 공유하는 학습의 뼈대다. 달라지는 것은 주로 뉴런을 어떻게 연결하고, 어느 위치에서 같은 parameter를 공유하느냐다.

DNN: 새로운 연결 방식이 아니라 깊이에 대한 말

DNN은 Deep Neural Network다. 말 그대로 hidden layer가 여러 층인 신경망을 뜻한다.

\[h^{(1)} = \sigma(W^{(1)}x + b^{(1)})\] \[h^{(2)} = \sigma(W^{(2)}h^{(1)} + b^{(2)})\] \[\hat{y} = f(W^{(3)}h^{(2)} + b^{(3)})\]

몇 층부터 deep인지에 대한 보편적인 숫자는 없다. 중요한 것은 DNN이 CNN이나 RNN과 같은 종류의 연결 규칙을 말하는 이름이 아니라는 점이다.

층이 깊어지면 앞쪽 층은 비교적 단순한 표현을 만들고, 뒤쪽 층은 그 표현들을 다시 조합할 수 있다. 이미지 모델을 예로 들면 초기 층은 edge나 texture에 반응하고, 깊은 층은 더 넓은 문맥을 이용한다.

다만 깊다고 무조건 좋아지는 것은 아니다.

  • parameter가 많아지면 더 많은 데이터와 계산량이 필요할 수 있다.
  • gradient가 너무 작아지거나 커져 학습이 어려워질 수 있다.
  • train loss는 낮지만 새 데이터에서 성능이 떨어지는 overfitting이 생길 수 있다.

그래서 깊이는 표현력을 늘리는 수단이지, 모델의 품질을 보장하는 숫자는 아니다.

CNN: 이미지 전체를 한 번에 연결하지 않는다

이미지 한 장을 MLP에 넣는다고 생각해보자. 224 x 224 x 3 이미지는 150,528개의 입력값을 가진다. 이것을 1,000개의 뉴런과 fully connected로 연결하면 첫 층에만 bias를 제외하고 약 1억 5천만 개의 가중치가 필요하다.

CNN은 이미지에 있는 두 가지 성질을 이용한다.

  1. 가까이 있는 pixel끼리 지역적인 패턴을 만든다.
  2. 같은 패턴은 이미지의 어느 위치에도 나타날 수 있다.

그래서 작은 kernel을 국소 영역에 적용하고, 그 kernel을 위치마다 공유한다.

\[Y_{i,j,k} = b_k + \sum_{u,v,c} K_{u,v,c,k}X_{i+u,j+v,c}\]

K는 kernel, X는 입력, Y는 feature map이다. 딥러닝 라이브러리에서 convolution이라고 부르는 연산은 kernel을 뒤집지 않는 cross-correlation 형태인 경우가 많다. 학습되는 kernel이라는 관점에서는 이 차이가 모델 사용법을 바꾸지는 않는다.

예를 들어 입력 channel이 3개이고 3 x 3 kernel 64개를 사용한다면 parameter 수는 다음과 같다.

\[(3 \times 3 \times 3 + 1) \times 64 = 1{,}792\]

입력 이미지의 가로와 세로가 커져도 kernel 자체의 parameter 수는 늘지 않는다. 이것이 local connectivity와 weight sharing이 주는 이점이다.

세 구조는 정보를 섞는 방식이 다르다
MLP
입력 벡터 Dense
전체 연결
Dense 출력
CNN
이미지 격자 작은 kernel
위치마다 공유
feature map 분류·검출
RNN
x1
h1
x2 + h1
h2
x3 + h2
h3
출력

Stride, padding, dilation을 어떻게 정하느냐에 따라 feature map의 크기와 receptive field가 달라진다. dilation이 1일 때 한 축의 출력 크기는 다음처럼 계산한다.

\[\left\lfloor\frac{N + 2P - K}{S}\right\rfloor + 1\]

N은 입력 크기, P는 padding, K는 kernel 크기, S는 stride다.

Pooling은 feature map 크기를 줄이는 대표적인 방법이지만 CNN의 필수 조건은 아니다. 현대 CNN에서는 strided convolution이나 global average pooling으로 그 역할을 대신하기도 한다.

RNN: 이전 계산 결과를 다음 시점으로 넘긴다

문장, 음성, 센서 값처럼 순서가 중요한 데이터는 각 입력을 독립적으로 보면 정보가 사라진다. “오늘은 비가 오지” 다음에 “않는다”가 오면 앞의 의미를 뒤집는 것처럼, 현재 입력을 해석하려면 이전 내용이 필요할 수 있다.

RNN은 이전 시점의 hidden state를 현재 입력과 함께 사용한다.

\[h_t = \phi(W_{xh}x_t + W_{hh}h_{t-1} + b_h)\] \[y_t = W_{hy}h_t + b_y\]

여기서 중요한 것은 모든 시점에 같은 W_xh, W_hh를 사용한다는 점이다. CNN이 공간 위치마다 kernel을 공유한다면, RNN은 시간 위치마다 recurrent weight를 공유한다.

RNN을 시간축으로 펼치면 같은 cell이 반복된 깊은 계산 그래프처럼 보인다.

x1 -> h1 -> h2 -> h3
             ^     ^
             x2    x3

학습할 때는 이 펼쳐진 그래프를 따라 backpropagation을 수행한다. 이를 BPTT, Backpropagation Through Time이라고 한다.

문제는 긴 sequence다. gradient에는 여러 시점의 recurrent Jacobian이 반복해서 곱해진다. 그 크기가 계속 1보다 작으면 gradient가 사라지고, 크면 폭발할 수 있다.

\[\frac{\partial h_t}{\partial h_k} = \prod_{i=k+1}^{t}\frac{\partial h_i}{\partial h_{i-1}}\]

LSTM과 GRU는 gate를 이용해 정보를 얼마나 유지하고 버릴지 조절한다. 이 구조는 장기 의존성 학습을 크게 개선하지만, 모든 긴 문맥 문제를 자동으로 해결한다는 뜻은 아니다. Exploding gradient에는 gradient clipping도 자주 함께 사용한다.

또한 RNN은 h_t를 계산하려면 이전 상태인 h_{t-1}이 먼저 필요하다. 시간축 계산을 완전히 병렬화하기 어렵다는 점은 긴 sequence에서 큰 비용이 된다. Transformer가 sequence 모델링의 중심으로 자리 잡은 이유 중 하나이지만, 작은 streaming 모델이나 제한된 메모리로 순차 처리해야 하는 문제에서는 RNN 계열이 여전히 쓸모가 있다.

같은 데이터라도 어떤 구조를 넣을지 선택하는 문제다

구분 주로 이용하는 구조 parameter 공유 잘 맞는 데이터 주의할 점
MLP 입력 feature 사이의 전체 연결 기본적으로 위치별 공유 없음 고정 길이 vector, tabular feature 공간·시간 구조를 스스로 배워야 한다.
CNN 지역성, grid topology 공간 위치마다 kernel 공유 이미지, 영상, 1D 신호 먼 위치의 관계에는 많은 층이나 별도 구조가 필요할 수 있다.
RNN 시간 순서, 누적 상태 시간 위치마다 recurrent weight 공유 문장, 음성, time series, streaming 긴 의존성과 순차 계산 비용을 확인해야 한다.

CNN은 이미지만, RNN은 텍스트만 처리한다고 외울 필요도 없다. 1D CNN은 음성이나 시계열에 쓸 수 있고, RNN은 이미지 row나 video frame의 순서를 처리할 수 있다. CNN encoder로 이미지 feature를 뽑고 RNN decoder로 문장을 생성하는 것처럼 두 구조를 함께 사용할 수도 있다.

모델을 고를 때는 다루려는 데이터부터 살펴보자.

입력에 공간적인 이웃 관계가 있는가?
시간 순서와 이전 상태가 중요한가?
입력 길이는 고정인가, 계속 들어오는 stream인가?
정확도뿐 아니라 latency와 memory 제약은 어떤가?

데이터가 가진 구조를 모델의 연결 방식에 반영하면, 모델이 처음부터 배워야 할 범위를 줄일 수 있다. 이를 inductive bias라고 한다. CNN의 locality와 translation equivariance, RNN의 temporal recurrence가 각각 대표적인 예다.

정리

처음의 네 이름으로 돌아가보자.

ANN은 전체 범주다.
DNN은 얼마나 깊게 쌓았는지를 말한다.
CNN은 공간의 가까운 패턴과 가중치 공유를 이용한다.
RNN은 이전 상태를 다음 시점으로 전달한다.

처음에 헷갈리기 쉬운 이유는 DNN을 CNN, RNN과 같은 기준의 분류로 보기 때문이다. DNN은 깊이를 가리키므로, 깊게 쌓은 CNN과 RNN도 DNN에 포함된다.

새 모델을 볼 때도 어떤 연결을 사용하고 어디서 가중치를 공유하는지 확인해보면, 이름만으로는 알기 어려웠던 차이를 파악하기 쉽다.

참고 자료


© 2024. All rights reserved.