9. 활성화 함수

활성화 함수

활성화 함수란?

  • 간단하게 말하면 활성, 비활성을 결정하는 함수.

  • 신경망에서는 노드에 들어오는 값들에 대해 다음 레이어로 바로 전달하지 않고 활성화 함수를 통과시켜 전달.

  • 활성화 함수는 입력 신호의 총합을 출력 신호로 변환하는 함수로, 입력 받은 신호를 얼마나 출력할지 결정 & 네트워크에 층을 쌓아 비선형성을 표현할 수 있도록 해줌.

<비선형성을 사용하는 이유>

  • 인공 신경망의 성능을 높이기 위해서는 은닉층을 계속해서 추가해야함

  • 선형 함수를 사용하면 은닉층을 쌓을 수 없음

  • 다시 말해, 선형 연산은 아무리 층을 깊게 해도 의미가 없음 ex) h(x) = ax → h(h(hx)) → h(x) = bx

  • 따라서 비선형을 사용하여 복잡한 함수를 학습하고, 정확도를 향상시킴

활성화 함수의 종류

  • 계단 함수

  • 시그모이드 함수

  • 하이퍼볼릭탄젠트 함수

  • 렐루 함수

  • 리키 렐루 함수

  • ELU

  • 소프트맥스 함수

인공신경망에서의 학습 과정

  • 순전파는 입력 데이터를 신경망에 공급하고 활성화 함수를 계산하여 예측된 출력값 얻음

  • 역전파에서 네트워크의 매개변수에 대한 결과값과 실제값 비교 후 오차를 통해 손실 함수의 기울기 계산, 이를 이용해 가중치와 편향 업데이트

계단 함수(Step function)

  • 최초로 사용한 활성화 함수

step(x)={1(x>0)0(x<0)step(x) = \lbrace ^ {0\quad(x<0)} _{1\quad(x > 0)}
import numpy as np
import matplotlib.pyplot as plt

def step(x):
    return np.array(x > 0, dtype=np.int64)

x = np.arange(-3.0, 3.0, 0.01)
y = step(x)
plt.plot(x, step(x))
plt.ylim(-0.1, 1.1)
plt.title("step")
plt.show()
  • 데이터의 손실이 일어날 가능성이 있기 때문에 딥러닝에서는 사용되지 않는 활성화 함수

  • 매우 간단한 분류는 가능할지도 모르지만, 딥러닝은 필요한 데이터가 매우 다양하므로, 만약 사용할 경우 매우 낮은 성능을 가질 것

  • 모든 구간에서 미분값이 0 → 현대의 신경망에서는 사용하기 어려움 → 역전파 알고리즘에 적용시, 학습이 진행되지 않기 때문

시그모이드 함수(Sigmoid function) = Logistic

  • x의 값에 따라 0~1의 값을 출력하는 S자형 함수

sigmoid(x)=11+exsigmoid(x) = {1\over 1+ e^{-x}}
ddxsigmoid(x)=11+ex(111+ex)=sigmoid(x)(1sigmoid(x)){d\over{dx}}sigmoid(x) = {1\over {1+e^{-x}}}(1-{1\over {1+e^{-x}}}) = sigmoid(x)(1-sigmoid(x))
import numpy as np
import matplotlib.pyplot as plt

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")
plt.show()

장점

  • 출력값의 범위가 0~1사이 → 확률로 보기 편함

  • 매끄러운 곡성, 기울기가 급격하게 변해서 발생하는 기울기 폭주 문제 발생 안함

  • 어느 분류에 속하는지 쉽게 파악 가능

단점

  • 시그모이드 함수의 출력값이 0 또는 1에 가까워지면, 그래프의 기울기 완만해짐

  • 0과 1에 가까운 부분의 기울기 계산 ⇒ 0에 가까운 작은 값 ⇒ 학습효과 떨어짐

  • 층이 많아질수록 앞단에는 기울기가 잘 전달되지 않음 ⇒ 기울기가 0이 되기 때문 ⇒ 기울기 소실 문제(Vanishing Gradient)

  • 출력값이 작아서 제대로 학습이 안될뿐만 아니라, 중심이 0이 아니라서 시간도 많이 걸림

  • 출력값이 모두 양수이기 때문에 경사하강법을 진행할 때, 기울기가 모두 양수거나 음수

  • 은닉층에서 사용하는 것은 지양!

사용하는 곳

  • 신경망, 로지스틱 회귀, 분류 문제의 가설과 비용함수 등

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

  • 시그모이드 함수의 한계점 보완, 크기 위치 조절

  • 입력값을 -1과 1사이의 값으로 변환

  • σ(x)는 sigmoid함수 식

tanh(x)=2α(2x)1=exexexextanh(x)=2\alpha(2x)-1 = {e^{x}-e^{-x}\over{e^x-e^{-x}}}
ddxtanh(x)=1tanh2(x){d\over{dx}}tanh(x)=1-tanh^2(x)
import numpy as np
import matplotlib.pyplot as plt

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="green", linestyle="--")
plt.title("Tanh")
plt.show()

장점

  • 중앙값이 0 → 경사하강법 사용시 편향 이동 X

  • 출력값 데이터의 평균이 0 → 시그모이드 보다 대부분 학습이 더 잘됨

  • 시그모이드 함수보다 범위가 넓기 때문에 출력값의 변화 폭이 크고, 기울기 소실 문제가 적음

  • 은닉층에서도 시그모이드 보다 효율적

단점

  • 여전히 기울기 소실 문제가 일어나긴함

  • 은닉층에서의 사용도 여전히 조심해야함

사용하는 곳

  • 시그모이드와 비슷

렐루 함수(ReLU)

  • 가장 많이 사용되는 활성화 함수 중 하나

  • 시그모이드와 탄젠트 함수가 갖는 기울기 소실 문제를 해결하기 위한 함수

relu(x)=max(0,x)relu(x)=max(0,x)
import numpy as np
import matplotlib.pyplot as plt

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")
plt.show()
  • 음수를 입력하면 0을 출력

  • 양수를 입력하면 입력값 그대로 반환

장점

  • 특정 양수값에 수렴하지 않아 깊은 신경망에서 시그모이드 함수보다 훨씬 잘 작동

  • 시그모이드나 탄젠트 함수처럼 다른 연산을 필요로 하지 않고 단순 임계값이므로 속도가 빠름

  • 구현 매우 간단

단점

  • 입력값이 음수면 기울기가 0 ⇒ 가중치 업데이트가 안 될 수 있음 ⇒ 다시 회생하는 것이 어려움 ⇒ 죽은 렐루 문제

  • 출력값은 0 또는 양수, 기울기는 0또는 1인 양수 ⇒ 최적의 가중치를 찾는 지그재그 현상 발생

  • 0에서 미분 불가능

사용하는 곳

  • 은닉층 활성화 함수 사용

리키 렐루(Leaky ReLU)

  • 죽은 렐루 문제 보완하기 위해 등장

leakyrelu(x)=max(ax,x)leakyrelu(x)=max(ax, x)
  • a는 일반적으로 0.01값을 가짐

  • 입력값이 음수일 경우에 0이 아니라 0.001과 같은 매우 작은 수를 반환하도록 함

import numpy as np
import matplotlib.pyplot as plt

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")
plt.show()

장점

  • 음수일 경우 더 이상 기울기가 0이 아니므로, 죽은 렐루 문제 해결

  • 층이 아무리 깊어져도 손실없는 정보 전달가능, 미분값이 항상 0과 1이기 때문에 연산 빠름

  • Relu보다 학습이 잘됨

단점

  • 음수에서 선형성이 생김, 복잡한 분류에서 사용 X

사용하는 곳

  • 음수가 아주 중요한 상황에 사용

ELU(Exponential Linear Unit)

  • ReLU의 모든 장점 포함

  • α는 사용자가 설정 → 일반적으로 1

elu(x)={α(ex1)        (x0)x                          (x>0)elu(x) = \lbrace ^{x\;\;\;\;\;\;\;\;\;\;\;\;\; (x>0)} _{\alpha(e^x-1)\;\;\;\;(x≤0)}
import numpy as np
import matplotlib.pyplot as plt

def elu(x, alp):
    return (x > 0) * x + (x <= 0) * (alp * (np.exp(x) - 1))

x = np.arange(-5.0, 5.0, 0.1)
y = elu(x, 0.5)

plt.plot(x, y)
plt.plot([0, 0], [-1.0, 5.0], ":")
plt.title("ELU")
plt.show()
  • 출력값의 중심이 거의 0에 가까움

장점

  • 죽은 렐루 문제 해결 → 음수 값이 작지만 0이 아닌 출력을 생성하도록 함

  • 음수 부분이 선형적이지 않음

단점

  • ReLU, leaky ReLU와 달리 exp 함수를 계산해야 해서 연산 비용이 큼

소프트맥스 함수(Softmax function)

  • 출력층의 뉴런에서 주로 사용

  • 세 가지 이상으로 분류하는 다중 클래스 분류에서 출력층에 사용되는 활성화 함수

  • 분류될 클래스가 n개라 할 때, n차원의 벡터를 입력받아, 각 클래스에 속할 확률을 추정

softmax(x)=σi(x)=ezij=1jezjsoftmax(x)=\sigma_i(x)={e^{z_{i}}\over\sum^j_{j=1}e^{z_{j}}}
import numpy as np
import matplotlib.pyplot as plt

x = np.arange(-5.0, 5.0, 0.1)
y = np.exp(x) / np.sum(np.exp(x))

plt.plot(x, y)
plt.plot([0, 0], [0.1, 0.0], ":")
plt.title("Softmax")
plt.show()
  • 출력값이 0과 1 사이

  • 출력값의 총합이 1

장점

  • 확률의 총합이 1이므로, 어떤 분류에 속할 확률이 가장 높은지를 쉽게 인지 가능

  • 크로스 엔트로피 로스함수와 함께 사용하면 역전파 계산이 심플함

단점

  • 은닉층에서 소프트맥스 함수가 사용되는 경우, 기울기 소실 문제 등 기울기를 제대로 찾지 못해 학습 효율성이 감소할 수 있음

  • 추론할 때 사용 X → 확률의 합이 무조건 1이 되야 하므로, a와 b에 해당하지 않는 것이 들어있을 때도 a아니면 b중 하나로 인식해버림

사용하는 곳

  • 다중 분류에서 사용

Last updated