자연어처리(NLP) 10일차 (인공신경망 훑어보기)

정민수
13 min readJun 13, 2019

--

2019.06.13

출처 : https://wikidocs.net/book/2155

핵심키워드

  • 인공신경망(Artificial Neural Network)
  • 피드 포워드 신경망(Feed-Forward Neural Network, FFNN)
  • 전결합층(Fully-connected layer, FC, Dense layer)
  • 활성화 함수(Activation Function)
  • 계단 함수(Step function)
  • 시그모이드 함수(Sigmoid function)
  • 렐루 함수(Relu function)
  • 하이퍼볼릭탄젠트 함수(Tanh function)
  • 소프트맥스 함수(Softmax function)

인공신경망(Aritificial Neural Network)

인공 신경망(Artificial Neural Network)이 발전함에 따라, 앞서 배운 퍼셉트론의 정형화된 틀을 벗어나서 계단 함수(Step function)가 아닌 다른 함수를 도입해보기도 하고, 뉴런 내 연산을 복잡하게도 해보는 등 다양한 시도를 통해 새로운 인공 신경망들이 등장하기 시작했다. 이번 챕터에서는 계단 함수 대신 선택할 수 있는 활성화 함수들과 인공 신경망의 행렬 연산을 이용한 순전파에 대해서 이해해보자.

1. 피드 포워드 신경망(Feed-Forward Neural Network, FFNN)

앞서 배운 단층 퍼셉트론이나 다층 퍼셉트론과 같이 입력층에서 출력층 방향으로 연산이 전개되는 신경망을 피드 포워드 신경망이라고 한다. 줄여서 FFNN이라고도 한다. 이렇게 별도로 정의되는 이유는 FFNN이 아닌 신경망이 존재하기 때문이다.

위 그림은 대표적으로 FFNN이 아닌 RNN이라는 신경망을 보여준다. 이 신경망은 은닉층의 출력값을 출력층으로도 값을 보내지만, 동시에 은닉층의 출력값이 다시 은닉층의 입력으로 사용되는데 이는 FFNN의 정의에 벗어난다.

2. 전결합층(Fully-connected layer, FC, Dense layer)

앞서 본 다층 퍼셉트론은 은닉층과 출력층에 있는 모든 뉴런은 바로 이전 층의 모든 뉴런과 연결돼 있었다. 그와 같이 어떤 층의 모든 뉴런이 이전 층의 모든 뉴런과 연결돼 있는 층을 전결합층이라고 한다. 줄여서 FC라고 부르기도 한다.

즉, 앞서 본 다층 퍼셉트론의 모든 은닉층과 출력층은 전결합층이다. 이와 동일한 의미로 밀집층(Dense Layer)라고 부르기도 하는데, 케라스에서는 밀집층을 구현할 때 Dense()를 사용한다. 자세한 구현 방법은 뒤에서 배운다.

3. 활성화 함수(Activation Fucntion)

앞서 배운 퍼셉트론에서는 계단 함수(Step function)를 통해 출력값이 0이 될지, 1이 될지를 결정했다. 이러한 매커니즘은 실제 뇌를 구성하는 신경 세포 뉴런이 전위가 일정치 이상이 되면 시냅스가 서로 화학적으로 연결되는 모습을 모방한 것이다. 이렇게 은닉층과 출력층의 뉴런에서 출력값을 결정하는 함수를 활성화 함수(Activation function)이라고 하는데, 계단 함수는 이러한 활성화 함수의 하나의 예제에 불과하다.

앞으로 다양한 활성화 함수에 대해서 알아볼텐데, 사실 일부는 7챕터인 머신러닝에서 본 함수들이다.

(1) 활성화 함수의 특징 — 비선형 함수(Nonlinear function)

활성화 함수의 특징은 선형 함수가 아닌 비선형 함수여야 한다는 점이다. 선형 함수란 출력이 입력의 상수배만큼 변하는 함수를 선형함수라고 한다. 예를 들어 f(x)=Wx+b 라는 함수가 있을 때, W와 b는 상수이다. 이 식은 그래프를 그리면 직선이 그려진다. 반대로 비선형 함수는 직선 1개로는 그릴 수 없는 함수를 말한다.

인공 신경망에서 활성화 함수는 반드시 비선형 함수여야 한다. 앞서 퍼셉트론에서도 계단 함수라는 활성화 함수를 사용했다. 즉, 계단 함수 또한 비선형 함수에 속한다.

인공 신경망의 능력을 키우기 위해서는 은닉층을 계속해서 추가해야 한다. 그런데 만약 활성화 함수로 선형 함수를 사용하게 되면 은닉층을 쌓을 수 없다. 예를 들어 활성화 함수로 선형 함수를 선택하고, 층을 계속 쌓는다고 가정해보면, f(x)=Wx 함수에다 은닉층 두 개를 추가한다고 해보자. 그렇다면 출력층을 포함해서 y(x) = f(f(f(x)))가 된다. 이를 식으로 표현하면 W × W × W × x이다. 그런데 이는 잘 생각해보면 W의 세 제곱값을 k라고 정의해버리면 y(x) = kx와 같이 다시 표현이 가능하다. 즉, 선형 함수로는 은닉층을 쌓는 것이 의미가 없다.

파이썬을 통해 주로 사용되는 활성화 함수를 직접 그려보고, 이해해보도록 하자.

(2) 계단 함수(Step function)

def step(x):
return np.array(x > 0, dtype=np.int)
x = np.arange(-5.0, 5.0, 0.1)
y = step(x)
plt.title('Step Function')
plt.plot(x, y)
plt.show()

계단 함수는 이제 거의 사용하지 않지만, 퍼셉트론을 통해 처음으로 인공 신경망을 배울 때 가장 처음 접하게 되는 활성화 함수이다.

(3) 시그모이드 함수(Sigmoid function)

def sigmoid(x):
return 1/(1+np.exp(-x))
x = np.arange(-5.0, 5.0, 0.1)
y = sigmoid(x)
plt.plot(x, y)
plt.plot([0, 0], [1.0,0.0], ':') # 가운데 점선
plt.title('Sigmoid Function')
plt.show()

시그모이드 함수는 가중치 곱의 함을 0과 1사이의 값으로 조정하여 반환하는 활성화 함수이다. 이미 로지스틱 회귀를 통해 접한 바있는 함수이지만 다시 설명하겠다. 시그모이드 함수는 마치 S자의 모양을 연상시키며, 로지스틱 함수(logistic function)라고도 부른다. 시그모이드 함수는 특정 목적으로 출력층의 뉴런에서 주로 사용되는데, 두 가지 선택지 중 하나를 고르는 이진 분류 문제(Bianry Classification)에 사용한다. 시그모이드 함수는 0과 1사이의 값을 반환한다.

이러한 이진 분류 문제의 예로 입력한 메일에 대해서 정상 메일인지, 스팸 메일인지를 판별하는 예제가 있다. 실제로 뒤에서 텍스트 분류 챕터에서도 스팸 메일 분류기를 구현할 때, 출력층의 뉴런에 시그모이드 함수를 사용할 것이다.

시그모이드 함수와 계단 함수는 두 함수 모두 입력이 작을 때 출력이 0에 가까워지고, 입력이 커질 때 출력이 1에 가까워진다는 점에서는 언뜻 보기에 비슷해보인다. 즉, 굳이 활성화 함수로 계단 함수 대신 시그모이드 함수를 사용해야하는 이유에 대해서 의문이 생길 수 있다. 계단 함수와 시그모이드 함수의 차이는 계단 함수는 0을 경계로 출력이 급격하게 변하는 것에 비해, 시그모이드 함수는 입력에 따라 출력이 연속적으로 변하는 곡선의 모양을 가진다는 것이다.

그런데 이 차이가 신경망 학습에서는 아주 큰 차이를 불러온다. 인공 신경망은 역전파(Back Propagation)라는 과정을 통해 인공 신경망에 경사 하강법을 수행하는데, 이때 인공신경망의 전체 식의 일부에 해당하는 활성화 함수도 미분의 대상이 된다. 앞서 배웠듯이 경사 하강법은 접선의 기울기를 이용한다. 그런데 계단 함수는 거의 모든 구간에서 기울기가 0이므로 학습이 제대로 되지 않는다.

(4) 렐루 함수 (ReLU function)

def relu(x):
return np.maximum(0, x)
y = relu(x)
plt.plot(x, y)
plt.plot([0, 0], [5.0, 0.0], ':')
plt.title('Relu Function')
plt.show()

은닉층에서 활성화 함수로 가장 많이 사용되는 활성화 함수이다. 하지만 입력값이 0보다 작을 경우, 미분값이 0이 되는 단점이 존재하는데 이를 보완한 Leaky ReLU와 같은 ReLU의 변형 함수들이 등장하기 시작했다. 하지만 그럼에도 여전히 은닉층에서 가장 많이 사용되는 활성화 함수이다.

(5) 하이퍼볼릭탄젠트 함수(Tanh function)

x = np.arange(-5.0, 5.0, 0.1)
y = np.tanh(x)
plt.plot(x, y)
plt.plot([0,0],[1.0,-1.0], ':')
plt.axhline(y=0, color='orange', linestyle='--')
plt.title('Tanh Function')
plt.show()

은닉층에서 활성화 함수로 종종 사용되는 tanh함수이다. 이미지 인식 분야에서 자주 사용되는 인공 신경망인 CNN에서는 ReLU함수가 주로 사용되고, 자연어 처리 분야에서 자주 사용되는 인공 신경망인 LSTM에서는 tanh 함수와 시그모이드 함수가 주로 사용된다.

(6) 소프트맥스 함수(Softmax function)

y = np.exp(x) / np.sum(np.exp(x))plt.plot(x, y)
plt.title('Softmax Function')
plt.show()

시그모이드 함수처럼 출력층의 뉴런에서 주로 사용되는데, 시그모이드 함수가 두 가지 선택지 중 하나를 고르는 이진 분류(Binary Classification) 문제에 사용된다면 세 가지 이상의 선택지 중 하나를 고르는 다중 클래스 분류(MultiClass Classification) 문제에 주로 사용된다.

4. 행렬의 곱셈을 이용한 순전파(Forward Propagation)

이와 같은 인공 신경망이 있다고 하자. 주어진 인공 신경망을 케라스로 구현해본다면 아래와 같이 짧은 코드로 구현할 수 있다.

from keras.models import Sequential
from keras.layers import Dense
model = Sequential() # 층을 추가할 준비
model.add(Dense(8, input_dim=4, init='uniform', activation='relu'))
# 입력층(4)과 다음 은닉층(8) 그리고 은닉층의 활성화 함수는 relu
model.add(Dense(8, activation='relu'))
# 은닉층(8)의 활성화 함수는 relu
model.add(Dense(3, activation='softmax'))
# 출력층(3)의 활성화 함수는 softmax

아직 케라스로 인공 신경망 모델을 만드는 방법을 자세히 배우지 않았지만, 사실 위의 코드가 어떤 의미인지 파악하는 것은 어렵지 않다. 위의 코드의 주석에서 () 괄호 안의 값은 각 층에서의 뉴런의 수를 의미하며 입력층부터 출력층까지 순차적으로 인공 신경망의 층을 한 층씩 추가하였다. 케라스를 사용하면 이렇게 간단하게 딥 러닝 모델을 구현할 수 있다.

인공 신경망에서 입력층에서 출력층 방향으로 연산을 진행하는 과정을 순전파(Forward Propagation)라고 한다. 다르게 말하면 주어진 입력으로부터 예측값을 계산하는 과정을 순전파라고 한다. 앞서 머신 러닝 챕터에서 배웠던 벡터와 행렬 연산을 인공 신경망에 적용하려고 하면, 벡터와 행렬 연산이 순전파 과정에서 층(layer)마다 적용된다.

사실 케라스로 인공 신경망을 만들면 이러한 연산 과정을 자세히 이해하지 않아도 모델을 만들 수 있지만, Numpy 등을 통해 인공 신경망을 로우 레벨로 개발하고 있다면 인공 신경망 내부 연산에 사용하는 행렬 크기를 고려해야 인공 신경망을 구현할 수 있다. 그렇기 때문에 비록 이 책은 케라스를 사용하지만, 적어도 로우 레벨 단계에서는 행렬의 크기가 어떻게 결정되는지 이해해보고자 한다.

1) layer 1의 행렬 크기 추정하기

우선 각 층을 기준으로 입력과 출력의 개수를 정리하면 다음과 같다.

입력층 : 4개의 입력과 8개의 출력

은닉층1 : 8개의 입력과 8개의 출력

은닉층2 : 8개의 입력과 3개의 출력

출력층 : 3개의 입력과 3개의 출력

여기서는 편의상 입력층을 layer 0, 은닉층 1을 layer1, 은닉층 2를 layer2, 출력층을 layer3 라고 해보자. 이제 위의 정보를 가지고 층마다 생기는 가중치와 편향 행렬의 크기를 추정해보자. 벡터와 행렬 연산 챕터에서 언급하였듯이 가중치 행렬에 입력 행렬을 곱하는 경우와 입력 행렬에 가중치 행렬을 곱하는 경우가 있겠으나, 여기서는 후자를 가정한다. 또한 배치 크기는 1로 한다. 이 경우 layer1에서 처음 입력으로 들어오는 입력 행렬 X의 크기는 1×4로 행벡터에 해당된다. (만약 미니 배치 학습을 가정할 경우, X의 크기는 배치의 크기 ×4가 된다.)

앞서 벡터와 행렬 연산 챕터에서 배운 바에 따르면, 입력 행렬, 가중치 행렬, 편향 행렬, 출력 행렬은 다음과 같은 크기 관계를 가진다.

layer1의 입력 행렬 X의 크기는 1×4 이다. layer1의 출력은 8개이므로, 그에 따라 출력 행렬 Y의 크기는 1×8이 된다.

그런데 가중치 행렬 W의 행은 입력 행렬 X의 열고 같아야 하므로 아래와 같다. (n=4)

편향 행렬 B는 출력 행렬 Y의 크기에 영향을 주지 않으므로 편향 행렬 B의 크기는 출력 행렬 Y의 크기와 같다.

가중치 행렬 W의 열은 출력 행렬 Y의 열과 동일해야 한다.

layer1의 가중치 행려로가 편향 행렬의 크기를 구했다. 이제 layer1의 출력 행렬 Y는 layer2에서는 입력 행렬 X가 된다.

2) layer2와 layer3의 행렬 크기 추정하기

이를 반복하면 layer2와 layer3에서의 가중치 행렬과 편향 행렬의 크기를 구할 수 있다. 비록 은닉층과 출력층에 활성화 함수가 존재하지만 활성화 함수는 행렬의 크기에 영향을 주지 않는다.

인공 신경망이 입력층에서 은닉층을 지나 출력층에서 예측값을 계산하기까지의 과정을 행렬 연산으로 가정하고 행렬의 크기를 추정해보았다. 이와 같이 순전파를 진행하고 예측값을 구하고나서 이 다음에 인공 신경망이 해야할 일은 예측값과 실제값으로부터 오차를 계산하고, 오차로부터 가중치와 편향을 업데이트하는 일이다. 즉, 인공 신경망의 학습 단계에 해당된다. 이때 인공 신경망은 순전파와는 반대 방향으로 연산을 진행하며 가중치를 업데이트하는데, 이 과정을 역전파(BackPropagation)라고 한다. 인공 신경망의 이러한 학습 방법에 대해서는 다음 챕터에서 배운다.

--

--

정민수
정민수

No responses yet