Skip to content

활성화함수

import numpy as np
import matplotlib.pyplot as plt

1. 계단 함수(Step function)

def step(x):
return np.array(x > 0, dtype=np.int)
x = np.arange(-5.0, 5.0, 0.1) # -5.0부터 5.0까지 0.1 간격 생성
y = step(x)
plt.title('Step Function')
plt.plot(x,y)
plt.show()

image

음수면 0, 양수면 1을 반환하는 간단한 함수이다. 실제로는 거의 사용되지 않는다.

2. 시그모이드 함수(Sigmoid function)

시그모이드 함수를 사용한 인공 신경망이 있다고 가정해보자.

위 인공 신경망의 학습 과정은 다음과 같다.

  1. 우선 인공 신경망은 입력에 대해서 순전파(forward propagation) 연산을 한다.
  2. 그리고 순전파 연산을 통해 나온 예측값과 실제값의 오차를 손실 함수(loss function)을 통해 계산한다.
  3. 이 손실(오차라고도 부릅니다. loss)을 미분을 통해서 기울기(gradient)를 구한다.
  4. 이를 통해 출력층에서 입력층 방향으로 가중치와 편향을 업데이트 하는 과정인 역전파(back propagation)를 수행한다.

이 시그모이드 함수의 문제점은 미분을 해서 기울기(gradient)를 구할 때 발생한다.

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()

image

위 그래프는 시그모이드 함수의 그래프이다. 시그모이드 함수의 출력값이 0 또는 1에 가까워지면, 그래프의 기울기가 완만해지는 모습을 볼 수 있다.

image

주황색 구간에서는 미분값이 0에 가까운 아주 작은 값이다. 초록색 구간에서의 미분값은 최대값이 0.25이다. 다시 말해 시그모이드 함수를 미분한 값은 적어도 0.25 이하의 값이다. 시그모이드 함수를 활성화 함수로하는 인공 신경망의 층을 쌓는다면, 가중치와 편향을 업데이트 하는 과정인 역전파 과정에서 0에 가까운 값이 누적해서 곱해지게 되면서, 앞단에는 기울기(미분값)가 잘 전달되지 않게 된다. 이러한 현상을 기울기 소실(Vanishing Gradient) 문제라고 한다.

시그모이드 함수를 사용하는 은닉층의 개수가 다수가 될 경우에는 0에 가까운 기울기가 계속 곱해지면 앞단에서는 거의 기울기를 전파받을 수 없게 된다. 다시 말해 매개변수가 업데이트 되지 않아 학습이 되지 않는다.

image

위의 그림은 은닉층이 깊은 신경망에서 기울기 소실 문제로 인해 출력층과 가까운 은닉층에서는 기울기가 잘 전파되지만, 앞단으로 갈수록 기울기가 제대로 전파되지 않는 모습을 보여준다. 결론적으로 시그모이드 함수의 은닉층에서의 사용은 지양된다. 시그모이드 함수는 주로 이진 분류를 위해 출력층에서 사용한다.

3. 하이퍼볼릭탄젠트 함수(Hyperbolic tangent function)

하이퍼볼릭탄젠트 함수(tanh)는 입력값을 -1과 1사이의 값으로 변환한다.

x = np.arange(-5.0, 5.0, 0.1) # -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()

image

하이퍼볼릭탄젠트 함수도 -1과 1에 가까운 출력값을 출력할 때, 시그모이드 함수와 같은 문제가 발생한다. 그러나 하이퍼볼릭탄젠트 함수의 경우에는 시그모이드 함수와는 달리 0을 중심으로 하고있으며 하이퍼볼릭탄젠트 함수를 미분했을 때의 최대값은 1로 시그모이드 함수의 최대값인 0.25보다는 크다.

다시 말해 미분했을 때 시그모이드 함수보다는 전반적으로 큰 값이 나오게 되므로 시그모이드 함수보다는 기울기 소실 증상이 적은 편이며 은닉층에서 시그모이드 함수보다는 선호되는 함수다.

4. 렐루 함수(ReLU)

인공 신경망의 은닉층에서 가장 인기있는 함수이다.

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

렐루 함수는 음수를 입력하면 0을 출력하고, 양수를 입력하면 입력값을 그대로 반환하는 것이 특징인 함수로(f(x) = max(0,x)) 출력값이 특정 양수값에 수렴하지 않고 입력값이 0 이상이면 미분값이 항상 1이다. 깊은 신경망의 은닉층에서 시그모이드 함수보다 훨씬 더 잘 작동한다. 뿐만 아니라, 렐루 함수는 시그모이드 함수와 하이퍼볼릭탄젠트 함수와 같이 어떤 연산이 필요한 것이 아니라 단순 임계값이므로 연산 속도도 빠르다.

하지만 여전히 문제점이 존재하는데, 입력값이 음수면 기울기. 즉, 미분값도 0이 된다. 그리고 이 뉴런은 다시 회생하는 것이 매우 어렵다. 이 문제를 죽은 렐루(dying ReLU)라고 한다.

image

5. 리키 렐루(Leaky ReLU)

죽은 렐루를 보완하기 위해 ReLU의 변형 함수들이 등장하기 시작했다. Leaky ReLU는 입력값이 음수일 경우에 0이 아니라 0.001과 같은 매우 작은 수를 반환하도록 되어있다. (f(x) = max(ax,x)) a는 하이퍼파라미터로 Leaky(‘새는’) 정도를 결정하며 일반적으로는 0.01의 값을 가진다.

a = 0.1
def leaky_relu(x):
return np.maximum(a*x, x)
x = np.arange(-5.0, 5.0, 0.1)
y = leaky_relu(x)
plt.plot(x, y)
plt.plot([0,0],[5.0,0.0], ':')
plt.title('Leaky ReLU Function')
plt.show()

기울기가 0이 되지 않으면 ReLU는 죽지 않는다.

image

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

은닉층에서는 ReLU(또는 ReLU 변형) 함수들을 사용하는 것이 일반적이다. 반면, 소프트맥스 함수는 시그모이드 함수처럼 출력층에서 주로 사용된다. 시그모이드 함수가 두 가지 선택지 중 하나를 고르는 이진 분류 (Binary Classification) 문제에 사용된다면 소프트맥스 함수는 세 가지 이상의 (상호 배타적인) 선택지 중 하나를 고르는 다중 클래스 분류(MultiClass Classification) 문제에 주로 사용된다. 다시 말해서 딥 러닝으로 이진 분류를 할 때는 출력층에 앞서 배운 로지스틱 회귀를 사용하고, 딥 러닝으로 다중 클래스 분류 문제를 풀 때는 출력층에 소프트맥스 회귀를 사용한다고 생각할 수 있다.

x = np.arange(-5.0, 5.0, 0.1) # -5.0부터 5.0까지 0.1 간격 생성
y = np.exp(x) / np.sum(np.exp(x))
plt.plot(x, y)
plt.title('Softmax Function')
plt.show()

image


참고