728x90
반응형

 지난 포스트에서는 시그모이드 함수에서 발전한 소프트맥스 함수에 대해 학습해보았다. 이번 포스트에서는 시그모이드 함수와 꽤 유사하면서, 시그모이드 함수의 단점을 보완한 하이퍼볼릭 탄젠트 함수에 대해 학습해보겠다.

 

 

하이퍼볼릭 탄젠트(Hyperbolic Tangent, tanh)

 우리말로 쌍곡선 탄젠트 함수라고 말하는 하이퍼볼릭 탄젠트는 수학이나 물리학을 전공한 사람이 아니라면, 영 볼 일이 없는 함수다.

 시그모이드, 소프트맥스 함수는 워낙 자주 사용되고, 신경망의 핵심 알고리즘인 로지스틱 회귀 모형에서 유래되었으므로, 공식까지 세세하게 파고 들어갔으나, 하이퍼볼릭 탄젠트 함수는 그 정도까지 설명할 필요는 없다고 생각한다.

 가볍게 하이퍼볼릭 탄젠트가 어떻게 생겼고, 왜 시그모이드 함수의 단점을 보완했다는지만 알아보도록 하자.

 

 

 

1. 하이퍼볼릭 탄젠트란?

  • 하이퍼볼릭 함수는 우리말로 쌍곡선 함수라고도 하며, 삼각함수는 단위원 그래프를 매개변수로 표시할 때, 나오지만, 쌍곡선 함수는 표준 쌍곡선을 매개변수로 표시할 때 나온다는 특징이 있다.
  • 삼각함수에서 $tanx$ = $sinx$/$cosx$로 나왔듯, 쌍곡선 함수에서 쌍곡탄젠트(Hyperbolic tangent)는 $tanhx$ = $sinhx$/$coshx$를 통해서 구한다.
  • 공식은 다음과 같다.

$$ sinhx = sinhx = \frac{e^x - e^{-x}}{2} $$

$$ coshx = \frac{e^x + e^{-x}}{2} $$

$$ tanhx = \frac{sinhx}{coshx} = \frac{e^x - e^{-x}}{e^x + e^{-x}} $$

  • 이들을 명명하는 방식은 다음과 같다.
    • $sinhx$: 신치, 쌍곡 샤인, 하이퍼볼릭 샤인
    • $coshx$: 코시, 쌍곡 코샤인, 하이퍼볼릭 코샤인
    • $tanhx$: 텐치, 쌍곡 탄젠트, 하이퍼볼릭 탄젠트

 

 

 

 

2. 하이퍼볼릭 탄젠트의 구현.

  • 위 공식을 그대로 구현해보면 다음 코드와 같다.
>>> import numpy as np

# 하이퍼볼릭 탄젠트
>>> def tanh(x):
>>>     p_exp_x = np.exp(x)
>>>     m_exp_x = np.exp(-x)
    
>>>     y = (p_exp_x - m_exp_x)/(p_exp_x + m_exp_x)
    
>>>     return y

 

  • 시각화해보자
>>> import matplotlib.pyplot as plt

>>> x = np.arange(-5.0, 5.0, 0.1)
>>> y = tanh(x)

# 캔버스 설정
>>> fig = plt.figure(figsize=(10,7)) # 캔버스 생성
>>> fig.set_facecolor('white')      # 캔버스 색상 설정

>>> plt.plot(x, y)
>>> plt.title("Hyperbolic Tangent", fontsize=30)
>>> plt.xlabel('x', fontsize=20)
>>> plt.ylabel('y', fontsize=20, rotation=0)

>>> plt.yticks([-1.0, 0.0, 1.0]) # 특정 축에서 특정 값만 나오게
>>> plt.axvline(0.0, color='k')
>>> ax = plt.gca()
>>> ax.yaxis.grid(True) # y축에 있는 모든 숫자에 회색 점근선을 그음

>>> plt.show()

  • 위 그림을 보면, 어째서 하이퍼볼릭 탄젠트 함수가 시그모이드 함수를 일부 보완했다고 하였는지, 이해할 수 있겠는가?
  • 시그모이드 함수와 하이퍼볼릭 탄젠트 함수의 가장 큰 차이는 출력값의 범위로, 하이퍼볼릭 탄젠트 함수는 -1에서 1 사이의 값을 출력하며, 중앙값도 0이다!
  • 이를 정리해보면 다음과 같다.
  시그모이드 함수 하이퍼볼릭 탄젠트 함수
범위 0 ~ 1 -1 ~ 1
중앙값 0.5 0
미분 최댓값 0.3 1

 

 

 

 

3. 하이퍼볼릭 탄젠트와 시그모이드 함수

  • 하이퍼볼릭 탄젠트는 중앙값이 0이기 때문에, 경사하강법 사용 시 시그모이드 함수에서 발생하는 편향 이동이 발생하지 않는다.
  • 즉, 기울기가 양수 음수 모두 나올 수 있기 때문에 시그모이드 함수보다 학습 효율성이 뛰어나다.
  • 또한, 시그모이드 함수보다 범위가 넓기 때문에 출력값의 변화폭이 더 크고, 그로 인해 기울기 소실(Gradient Vanishing) 증상이 더 적은 편이다.
    (※ 기울기 소실(Gradient Vanishing): 미분 함수에 대하여, 값이 일정 이상 커지는 경우 미분값이 소실되는 현상)
  • 때문에 은닉층에서 시그모이드 함수와 같은 역할을 하는 레이어를 쌓고자 한다면, 하이퍼볼릭 탄젠트를 사용하는 것이 효과적이다.
  • 그러나, 시그모이드 함수보다 범위가 넓다 뿐이지 하이퍼볼릭 탄젠트 역시 그 구간이 그리 크지는 않은 편이므로, $x$가 -5보다 작고 5보다 큰 경우, 기울기(Gradient)가 0으로 작아져 소실되는 기울기 소실 현상 문제는 여전히 존재한다.
# 시그모이드 함수의 미분
def diff_sigmoid(x):
    
    return 1/(1+np.exp(-x)) * (1 - (1/(1+np.exp(-x))))

# 하이퍼볼릭 탄젠트의 미분
def diff_tanh(x):
    
    return 4 / (np.exp(2*x) + 2 + np.exp(-2*x))
>>> import matplotlib.pyplot as plt

>>> x = np.arange(-10.0, 10.0, 0.1)
>>> y1 = diff_sigmoid(x)
>>> y2 = diff_tanh(x)

>>> fig = plt.figure(figsize=(10,5))

>>> plt.plot(x, y1, c = 'blue', linestyle = "--", label = "diff_sigmoid")
>>> plt.plot(x, y2, c = 'green', label = "diff_tanh")

>>> plt.title("Sigmoid VS tanh", fontsize=30)
>>> plt.xlabel('x', fontsize=20)
>>> plt.ylabel('y', fontsize=20, rotation=0)

>>> plt.ylim(-0.5, 2)
>>> plt.xlim(-7, 7)

>>> plt.legend(loc = "upper right")

>>> plt.axvline(0.0, color='k')
>>> ax = plt.gca()
>>> ax.yaxis.grid(True)
>>> ax.xaxis.grid(True)

>>> plt.show()

 

  • 위 그래프는 시그모이드의 도함수(파랑)와 하이퍼볼릭 탄젠트(녹색)의 미분 함수를 비교한 것으로, 시그모이드 함수의 미분보다 하이퍼볼릭 탄젠트의 미분이 상황이 더 낫긴 하지만, 하이퍼볼릭 탄젠트의 미분 역시 ±5부터 0이 되어버리므로, 기울기 소실 문제에서 안전하지 않다는 것을 알 수 있다.

 

 

 

 지금까지 하이퍼볼릭 탄젠트에 대해 알아보았다. 시그모이드 함수의 단점을 많이 보완한 활성화 함수이긴 하지만, 여전히 기울기 소실 문제가 발생할 가능성이 있으므로, 은닉층에서 쓰고자 하면, 쓰되 조심히 쓰기를 바란다.

 다음 포스트에서는 은닉층에서 가장 많이 사용되는 렐루(ReLU) 함수에 대해 알아보도록 하겠다.

728x90
반응형

+ Recent posts