순방향 신경망의 구조와 설계 항목
현대에 들어와서 다층 퍼셉트론은 `순방향 신경망`, 퍼셉트론은 `인공 뉴런(Artificial Neuron)`이라 불린다. 순방향 신경망의 데이터는 서로 독립되어 있다고 가정하며, 데이터가 한 방향으로 전달되는 `순뱡향(Feedforward)` 연결만을 갖는 구조로 되어 있으며, 퍼셉트론의 연산과 같은 기본 뉴런 연산으로 실행된다. 추가적으로, CNN은 공간 데이터를 가정하며, RNN은 순환 데이터를 가정한다.
순방향 신경망의 구조
순방향 신경망은 다음과 같이 뉴런들이 모여 `계층(Layer)`를 이루고 계층이 쌓여 전체 신경망을 이루는 구조로 되어 있다.
순방향 신경망의 계층 구조
순방향 신경망의 계층 구조는 입력 계층, 은닉 계층, 출력 계층으로 구분된다. 대부분의 모델에는 입력 계층과 출력 계층이 각각 하나씩 있지만 은닉 계층은 문제의 복잡도에 따라 가변적으로 구성된다. 또한 신경망의 계층을 표현할 때는 보통 입력 계층을 제외하고 표현한다. 위의 그림에선 3개의 은닉 계층과 1개의 출력 계층으로 구성되어 '4계층 신경망'으로 표기한다. 입력 계층은 데이터를 전달하는 역할만 수행하기 때문에 가중치나 편향과 같은 모델 파라미터가 없어 학습이 필요 없으며 계층으로서의 의미도 약하기 때문이다.
- 입력 계층 : 외부에서 데이터를 전달받음
- 은닉 계층 : 데이터의 특징을 추출
- 출력 계층 : 추출된 특징을 기반으로 추론한 결과를 외부에 출력
신경망 모델에서 계층이 많아질수록 '신경망이 깊어진다'라고 표현한다. 보통 계층이 2~3개 정도이면 `얕은 신경망(Shallow Neural Network)`이라고 하고, 그 이상이 되는 경우 `깊은 신경망(Deep Neural Network, DNN)`이라고 한다.
완전 연결 계층과 뉴런의 역할
순방향 신경망은 모든 계층이 `완전 연결 계층(Fully Connected Layer)`로 구성된다. 완전 연결 계층은 계층에 속한 각 뉴런이 이전 계층의 모든 뉴런과 모두 연결된 구조를 말하며, 이로 인해 같은 입력 데이터에서 뉴런마다 서로 다른 특징을 추출한다. 따라서 데이터에 특징이 많을수록 뉴런 수가 충분해야 데이터에 내재한 특징을 모두 추출할 수 있다. 각 뉴런에서 추출된 특징은 계층 단위로 출력되어 다음 계층에 한꺼번에 전달된다. 신경망에 입력된 데이터는 은닉 계층을 거치면서 추론에 필요한 특징으로 변환되며, 출력 계층은 가장 추상화된 특징을 이용하여 예측한다.
특징을 추출하는 뉴런 구조
뉴런은 데이터에 내재한 특징을 추출하기 위해 `가중 합산`과 `활성 함수`를 순차적으로 실행한다. 가중 합산은 추출할 특징에 중요한 영향을 미치는 데이터를 선택하는 과정이며, 활성 함수는 원하는 형태로 특징을 추루하기 위해 데이터를 비선형적으로 변환하는 과정이다. 신경망의 계층이 쌓이면서 뉴런의 활성 함수는 여러 단계로 합성되고 신경망이 표현하고자 하는 매우 복잡한 연속 함수나 결정 경계를 이루는 특징을 표현한다. 따라서 뉴런의 활성 함수는 신경망의 `기저 함수(Basis Function)`이라고 할 수 있다.
중요한 데이터를 선택하는 가중 합산 연산
가중치는 특징을 추출할 때 영향이 큰 데이터를 선택하는 역할을 한다. 즉, 특징 추출에 영향이 큰 데이터는 큰 가중치를 갖고 영향이 작은 데이터는 작은 가중치를 갖는다. 이때 가중 합산 연산식에 편향 b를 더하는 이유는 특징을 공간의 어느 위치에든지 존재할 수 있게 하려는 의도이다. 편향이 없다면 특징은 무조건 원점을 지나는 연속 함수로 결정된다.
범용 함수 근사기로서의 신경망
뉴런은 가중 함수와 활성 함수를 순차적으로 실행하는 합성 함수이며, 뉴런의 그룹으로 정의되는 계층도 합성 함수이다. 또한 계층을 순차적으로 쌓은 형태인 신경망 역시 합성 함수이다. 각각 뉴런은 실함수로, 계층과 신경망은 벡터 함수로 정의된다.
실함수인 뉴런
뉴런은 실함수로 입력과 가중치의 가중 합산 결과를 비선형 활성 함수로 매핑해서 실수를 출력하는 합성 함수이다. 실함수는 입력은 크기가 n인 벡터이며 출력은 실수의 형태이다.
벡터 함수인 계층
계층은 입력도 벡터이고 출력도 벡터인 벡터 함수이다. 계층을 이루는 각 뉴런은 이전 계층의 출력을 벡터 형태로 입력받으며, 각 뉴런의 출력을 모아 벡터 형태로 출력한다. 이때 입력 벡터의 크기는 이전 계층의 뉴런의 수와 같고 출력 벡터의 크기는 현재 계층의 뉴런 수와 같다. 즉 이전 계층의 뉴런이 n개이고 현재 계층의 뉴런이 m개라면, 입력은 크기가 n인 벡터이고 출력은 크기가 m인 벡터가 된다. 이때 계층의 가중치는 크기는 (n x m)인 행렬 W로 정의되며 가중치 행렬의 각 열은 각 뉴런의 가중치를 나타낸다. 가중 합산 결과에 활성 함수를 실행하면 벡터의 요소별로 활성 함수가 실행되어 크기가 m인 벡터가 출력된다.
벡터 함수들의 합성 함수인 신경망
신경망은 입력과 출력이 벡터인 벡터 함수이며 동시에 각 계층이 정의하는 벡터 함수를 순차적으로 실행하는 합성 함수이다. 또한 신경망은 학습할 때 미분을 사용하기 때문에 신경망이 표현하는 함수는 `미분 가능한 함수(differentiable function)`이어야 한다. 합성 함수로 정의되는 신경망은 다음 그림과 같이 표현된다.
순방향 신경망의 설계 항목
순방향 신경망 모델을 설계하려면 기본적으로 모델의 입력과 출력 형태, 활성 함수의 종류, 네트워크 크기 등을 고려해야 한다. 일반적으로 문제가 정의되고 데이터와 신경망 모델의 종류가 선정되면 입력, 출력의 형태는 결정된다. 하지만 모델의 크기와 활성 함수의 종류는 모델 검증 단게에서 하이퍼파라미터 탐색을 하거나 자동 모델 탐색을 통해 최적의 모델을 찾아야 한다.
분류와 회귀 문제
분류 문제
`분류(classification)` 문제는 데이터의 `클래스(class)` 또는 `카테고리(category)`를 예측하는 문제이다. 분류 문제는 두 개 클래스로 분류하는지 여러 클래스로 분류하는지에 따라 `이진 분류(binary classification)`와 `다중 분류(multiclass classification)` 문제로 다시 나뉜다. 여기서 분류 모델을 대상을 판별하는 `판별 함수(discriminative function)`로 정의하면 모델은 입력 데이터가 속한 클래스를 예측한다. 반면 분류 모델을 확률을 예측하는 `확률 함수(stochastic model)`로 정의하면 입력 데이터가 각 클래스에 속할 확률을 예측한다.
회귀 문제
`회귀(regression)` 문제는 여러 독립 변수와 종속 변수의 관계를 연속 함수 형태로 분석하는 문제이다. 예측값이 숫자 형태이면 회귀 문제이다. 회귀 모델은 입력 데이터에 대한 함숫값을 예측한다. 회귀 모델을 확률 모델로 정의하면 타겟값의 확률분포를 예측한다.
입력 계층
순방향 신경망의 입력 계층은 입력 데이터를 벡터 형태로 받아서 다음 계층에 전달하는 역할을 한다. 만약 입력 데이터가 크기가 n개인 벡터라면 입력 계층은 n개의 뉴런으로 정의된다. 예를 들어 피쳐가 9개인 데이터라고 하면 입력 계층은 총 9개의 뉴런으로 구성되며, MNIST 이미지 데이터의 경우 입력 데이터의 크기가 (28 x 28 x 1)이기 때문에 이를 1차원으로 변환한 크기인 784개의 뉴런으로 입력 계층이 구성된다.
활성 함수
은닉 계층을 설계할 때 선택할 수 있는 활성 함수는 매우 다양하다. 활성 함수는 크게 S자형 곡선 형태의 시그모이드(sigmoid) 계열과 구간 선형 함수로 정의되는 ReLU(Rectified Linear Unit) 계열로 구분할 수 있다. 역사적으로는 역전파 알고리즘이 등장하면서 시그모이드 계열의 활성 함수가 먼저 등장했고, 이후 딥러닝 시대가 열린 이후 ReLU 계열의 활성 함수가 나타나기 시작했다.
- 시그모이드 계열 : `Sigmoid`, `Tanh`
- ReLU 계열 : `ReLU`, `Leaky ReLU`, `Maxout`, `ELU`
ReLU 계열의 활성 함수들은 선형성을 갖고 있어서 연산 속도가 빠르며 학습 과정을 안정적으로 만들어준다. 따라서 은닉 계층에서는 ReLU 계열의 활성 함수를 사용하는 것이 좋다. 시그모이드 계열은 연산 속도도 느리고 그레이디언트 소실의 원인이 되어 신경망 학습에는 좋지 않지만, 값을 고정 범위로 만들어주는 `스쿼싱(squashing)` 기능이 필요한 다음과 같은 구조에서 다양하게 활용된다.
- 출력 계층에서 실숫값을 확률로 변환 → Sigmoid, Softmax
- 변수값을 조절해야 할 때 게이트 연산을 하며, 게이트 값을 [0,1] 범위로 만들기 위해 Sigmoid 함수 사용
- 게이트 구조는 순환 신경망의 LSTM과 GRU 셀에서 사용하며, 다중 작업 학습(Multi-Task Learning) 모델에서 각자 다른 역할을 담당하는 브랜치들을 두고 작업에 필요한 브랜치를 선택하는 구조에서도 사용
- 값의 범위가 존재하는 데이터를 출력할 때 Sigmoid나 Tanh를 사용해서 값의 범위를 맞춤
- 생성 모델에서 이미지의 픽셀값을 [-1,1] 범위로 만들 때와 로봇이나 기계 제어를 위한 모터의 각도나 이동 거리, 속도 등을 제어할 때도 Tanh을 사용해서 값의 범위를 제한
계단 함수(Step Function)
`계단 함수(Step Function)`는 메켈러-피츠 모델과 퍼셉트론에서 사용된 활성 함수이다. 이는 뉴런의 활성과 비활성 상태를 숫자 1과 0으로 표현한다. 그래서 입력값이 0보다 크면 1을 출력하고 0보다 작으면 0을 출력한다. 그러나 계단 함수는 현대의 신경망에서는 사용할 수 없다. 계단 함수는 모든 구간에서 미분값이 0이기 때문에 미분을 이용해서 학습하는 역전파 알고리즘에 적용할 경우 학습이 진행되지 않는다.
시그모이드 함수(Sigmoid Function)
역전파 알고리즘을 만들 당시 계단 함수를 대체할 미분 가능한 함수가 필요했고, 그 결과 부드러운 계단 함수 모양인 시그모이드 함수를 찾았다. 시그모이드는 S자 형태의 함수이다. 계단 함수와 같이 함숫값의 범위도 [0,1] 사이이다. 또한 모든 구간에서 미분할 수 있고, 증가 함수이므로 미분값이 항상 양수이다.
그러나 이런 시그모이드는 몇 가지 문제점이 있다.
- 함수 정의에 지수 함수가 사용되기 때문에 연산 비용이 많이 발생
- 그레이디언트 포화가 발생해서 학습이 중단될 수 있음
- 양수만 출력하므로 학습 경로가 진동하면서 학습 속도가 느려짐
`그레이디언트 포화(Gradient Saturation)`란 시그모이드 함수 끝부분에서 미분값이 0으로 포화되는 상태를 말한다. 함수에서의 `포화(Saturation)`란 입력값이 변화해도 함숫값이 변화하지 않는 상태를 말한다. 다음 그림을 보면, 시그모이드 함수(파란색)는 양쪽 끝에서 함숫값이 0과 1로 포화하기 때문에 도함수에서(빨간색) 미분값도 0으로 포화한다. 그레이디언트가 0으로 포화하면 `그레이디언트 소실(Gradient Vanishing)`로 학습이 진행되지 않는다.
하이퍼볼릭 탄젠트 함수(Hyperbolic Tangent, tanh)
`하이퍼볼릭 탄젠트 함수(Hyperbolic Tangent, tanh)`는 함숫값이 [-1, 1] 범위에 있는 S형 함수이다. 시그모이드가 항상 양수만을 출력하기 때문에 최적화가 비효율적으로 진행되는 문제를 해결하고자 사용되었다.
그러나 하이퍼볼릭 탄젠트 함수는 시그모이드 함수의 선형 변환식이기 때문에 동일한 문제점이 남아있다.
- 함수 정의에 지수 함수가 포함되어 있어 연산 비용이 많이 발생
- 그레이디언트 포화가 발생해서 학습이 중단될 수 있음
ReLU(Rectified Linear Unit) 함수
`ReLU(Rectified Linear Unit)`는 0보다 큰 입력이 들어오면 그대로 통과시키고 0보다 작은 입력이 들어오면 0을 출력하는 함수이다. 따라서 입력값이 양수인 경우에만 활성 상태가 된다. ReLU를 사용하면 시그모이드 계열보다 추론과 학습 속도가 빨라지고 안정적으로 학습할 수 있다. 이는 양수 구간은 값을 그대로 통과시키고 음수 구간도 0을 출력하므로 연산이 발생하지 않기 때문이다. 또한 음수 구간의 데이터가 0이 되면서 데이터가 `희소(sparse)`해져서 추가 연산량이 줄어든다. (여기서 데이터가 희소하다는 표현은 값이 대부분 0인 경우를 말한다.) 여기에 ReLU는 양수 구간에서 미분값이 1이고, 음수 구간에서 미분값이 0이기 때문에 미분을 계산할 필요가 없다. 따라서 시그모이드 계열보다 약 6배 정도 학습이 빨라진다. 또한 ReLU는 양수 구간이 선형 함수이기 때문에 그레이디언트 소실이 생기지 않아 안정적으로 학습할 수 있다.
ReLU는 빠르고 안정적으로 학습할 수 있지만 다음과 같은 단점이 존재한다.
- 양수만 출력하므로 학습 경로가 진동하면서 학습 속도가 느려짐
- 죽은 ReLU가 발생하면 학습이 진행되지 않을 수 있음
`죽은 ReLU(dead ReLU)`는 뉴런이 계속 0을 출력하는 상태를 말한다. 뉴런이 0을 출력하면 그레이디언트도 0이 되어 뉴런이 더 학습되지 않고 같은 값을 출력한다. 이는 가중치 초기화를 잘못했거나, 학습률이 매우 클 때 발생한다. 뉴런의 10~20%가 죽은 ReLU가 되면 학습에 문제가 생길 수 있다.
LeakyReLU, PReLU, ELU 함수
죽은 ReLU 문제를 해결하려면 음수 구간이 0이 되지 않도록 약간의 기울기를 주면 된다. `Leaky ReLU`가 이러한 방식을 취한다. 음수 구간에 기울기를 주면 작은 그레이디언트가 생겨 학습 속도가 빨라진다. 그러나 Leaky ReLU는 기울기가 고정되어 있기 때문에 최적의 성능을 내지 못할 가능성이 있어, 기울기를 학습하도록 만든 방식이 `PReLU(Parametric ReLU)`이다. PReLU를 사용하면 뉴런별로 기울기를 학습하므로 성능이 개선된다.
Leaky ReLU나 PReLU는 음수 구간이 직선이므로 기울기가 작더라도 큰 음숫값이 들어오면 출력값이 -∞로 발산할 수 있다. 이에 반해 `ELU(Exponential Linear Units)`는 음수 구간이 지수 함수 형태로 정의되어 x값이 음수 방향으로 커지더라도 함숫값이 0에 가까운 일정한 음숫값으로 포화된다. 따라서 아주 큰 음숫값이 입력되더라도 함숫값이 커지지 않으므로 노이즈에 민감하지 않다.
맥스아웃 함수
`맥스아웃(Maxout)`은 활성 함수를 `구간 선형 함수(piecewise linear function)`로 가정하고, 각 뉴런에 최적화된 활성 함수를 학습을 통해 찾아낸다. 다음 그림과 같이 뉴런별로 선형 함수를 여러 개 학습한 뒤에 최댓값을 취한다. 맥스아웃은 ReLU의 일반화된 형태라고 할 수 있으며 성능이 뛰어나다.
맥스아웃 활성 함수를 학습하기 위한 뉴런을 확장한 구조를 `맥스아웃 유닛(Maxout unit)`이라고 한다. 맥스아웃 유닛은 선형 함수를 학습하는 `선형 노드(linear node)`와 최댓값을 출력하는 노드로 구성된다. 선형 노드는 뉴런의 가중 합산과 같은 형태로 선형 함수를 학습하며, 최댓값 출력 노드는 구간별로 최댓값을 갖는 선형 함수를 선택한다.
맥스아웃은 선형 노드의 개수에 따라 다른 형태의 `볼록 함수(convex function)`를 근사할 수 있다. 선형 노드가 2개이면 ReLU와 절댓값 함수를 근사할 수 있고, 선형 노드가 5개이면 2차 함수를 근사할 수 있다. 맥스아웃을 적용하면 유닛별로 사용되는 파라미터 수는 증가하지만, 신경망의 깊이를 줄일 수 있기 때문에 전체적인 파라미터 수는 소폭 증가한다.
Swish 함수
`Swish`는 구글의 딥러닝 연구팀의 AutoML로 찾은 최적의 활성 함수로 `SiLU(Sigmoid Linear Unit)`이라고도 부른다. Swish 함수는 선형 함수 x와 시그모이드 함수의 곱으로 정의된다. 이는 ReLU와 ELU와 비슷한 모양이지만 원점 근처의 음수 구간에서 잠시 볼록 튀어나왔다가 다시 0으로 포화하는 곡선 모양을 하고 있다.
신경망 모델의 크기
신경망의 모델의 크기는 `너비(width)`와 `깊이(depth)`로 정해진다. 너비는 '계층별 뉴런 수'를 말하며 깊이는 '계층 수'를 말한다. 데이터가 특징이 많고 데이터 간의 관계가 복잡할수록 특징을 학습하는 뉴런의 수를 늘려줘야 하고(너비), 특징의 추상화 수준이 높을수록 추상화를 수행하는 계층의 수를 늘려줘야 한다(깊이). 그러나 관계의 복잡도나 추상화 수준을 가늠하기 어렵기 때문에 경험적으로 크기의 범위를 정하고 성능 분석을 통해 최적의 크기를 탐색해 나가야 한다.
모델 크기 탐색
신경망모델의 크기를 탐색할 때는 `그리드 서치(grid search)`나 `랜덤 서치 (random search)`와 같은 탐색 방법을 사용한다. 그리드 서치는 파라미터별로 구간을 정해서 등간격으로 값을 샘플링하는 방법이고, 랜덤 서치는 여러 파라미터를 조합해서 랜덤하게 값을 샘플링하는 방법이다. 이 두 가지 방법 중에는 랜덤 서치가 더 골고루 테스트할 수 있기 때문에 그리드 서치보다 성능이 좋다. 최근에는 네트워크 구조 탐색 방법인 `NAS(Network Architecture Search)`와 같은 자동 모델 탐색 방법을 활용하기도 한다. 이는 최적의 모델을 생성하는 방법을 학습하는 방식으로 강화 학습이나 유전 알고리즘, 베이지안 기법 등으로 구현된다.
모델 크기 조정
신경망 모델을 구성할 때 많이 사용하는 방법 중 하나는 성능이 검증된 기본 모델을 선택해서 새로운 문제에 맞게 모델의 크기를 조정하는 것이다. 2019년에 제안된 `EfficientNet`에서는 다음의 4가지 방법 중 마지막 모델이 최고의 성능을 갖는다는 것을 보였다.
- 너비를 늘린 모델
- 깊이를 늘린 모델
- 입력 이미지의 해상도를 높인 모델
- 너비, 깊이와 입력 이미지의 해상도를 동시에 늘린 컴파운드 스케일링 모델
신경망 학습 관련 내용
시그모이드 함수와 크로스 엔트로피 손실
시그모이드 함수는 분모에 지수 항이 있기 때문에 함수의 양 끝부분에서 그레이디언트 포화가 발생하고 그로 인해 학습이 중단될 수 있다. 여기서 시그모이드 함수를 출력 계층에 사용할 때 크로스 엔트로피 손실을 사용하면 일부 구간에서 그레이디언트 포화가 생기지 않게 만들 수 있다. 시그모이드 함수의 그레이디언트 포화 상쇄 과정은 다음과 같다.
`소프트플러스(softplus)` 함수는 부드러운 곡선 형태의 ReLU 함수이다. 따라서 양수 구간에서 그레이디언트 포화가 발생하지 않는다. 이와 같이 분류 모델의 출력 계층에서 소프트맥스와 시그모이드 계열의 활성 함수를 사용할 때 크로스 엔트로피 손실 함수를 같이 사용하면 소프트플러스 함수 형태로 변환되어 학습이 개선될 수 있다.
양수만 출력하는 활성 함수의 최적화 문제
시그모이드나 ReLU와 같이 활성 함수의 출력이 항상 양수이면 학습 경로의 이동 방향이 크게 진동하면서 학습이 느려진다. 양수만 출력하는 활성 함수를 모든 은닉 계층에서 사용한다고 가정해보면, 입력 계층을 제외한 모든 계층의 출력은 모두 양수이다. 즉, 첫 번째 은닉 계층을 제외한 모든 계층의 입력은 양수이다. 먼저 가중치의 최적화 경로를 확인하기 위해 그레이디언트를 계산하면 다음과 같다.
이처럼 가중치를 업데이트할 때 모든 차원이 양수이거나 음수의 방향으로만 이동하게 되어 최적해 방향으로 곧바로 가지 못한다. 가중치가 2개인 경우의 이 과정을 그림으로 표현하면 다음과 같다.
그레이디언트의 모든 차원이 양수이거나 음수이므로 가중치 업데이트의 허용 방향은 제한되어있다. 여기서 만약 손실 함수의 최소 지점이 빨간 점이라고 하면, 파란색 경로처럼 직선으로 가지 못하고 노란색 경로처럼 진동하면서 느리게 도달하여 학습이 느려진다.
죽은 ReLU가 발생하는 이유
죽은 ReLU는 뉴런이 계속 0을 출력하는 상태를 말하며, 이는 가중치 초기화를 잘못했거나 학습률이 매우 클 때 발생할 수 있다. 가중치 초기화를 잘못해서 뉴런의 입력값 x가 아주 커졌다고 가정해보겠다.
여기서 뉴런의 입력 x가 아주 큰 값이기 때문에 그레이디언트도 매우 커지고 가중치를 업데이트하면 가중치가 큰 음수로 변한다. 가중치가 한번 음수가 되면 다음 입력이 들어왔을 때 가중 합산이 음수가 되므로 ReLU는 0을 출력하고, ReLU의 그레이디언트가 0이 되어 학습이 더 진행되지 않고 계속해서 0을 출력하는 상태가 된다.
미분 불가능한 활성 함수
신경망에서 학습하기 위해선 미분 가능한 활성 함수를 사용해야 한다. 그러나 미분이 되지 않는 활성 함수를 사용해도 괜찮다. 신경망은 근사 방식으로 함수를 표현하기 때문에 약간의 미분 오차를 허용해도 결과에 미치는 영향은 크지 않다고 본다. 활성 함수가 구간별로 미분 가능한 형태라면 구간 내에서는 정상적으로 미분을 해서 학습하고, 구간이 변경되는 지점에서는 우미분과 좌미분 중에 하나를 선택해서 학습하면 된다. 예를 들어, ReLU의 경우 x=0에서우미분 1과 좌미분 0 중 어느 것을 사용해도 상관없다.
본 포스팅은 'Do it! 딥러닝 교과서' 교재를 공부하고 작성한 글입니다.