본문 바로가기

머신러닝

[파이썬] 딥러닝 활성화 함수(Activation function)

728x90

 

1. 활성화 함수

 

활성화 함수는 입력신호 (x)와 가중치(w) 곱의 합 (weighted sum)을 출력신호(y)로 변환하는 함수입니다.

인공신경망에선 각 노드마다 존재, layer에 따라 다른 활성화 함수 적용이 가능하며,

활성화 함수가 사용되지 않으면 각 노드를 지나도 계속해서 선형이 됩니다.

 

출처: COSS 빅데이터

 

활성화 함수는 비선형 함수이며,

선형 함수가 활성화 함수인 경우 neuron을 multi-layer로 구성해도

linearly separable problem만 해결 가능하므로 비선형 함수를 사용합니다.

 

즉, 활성화 함수는 비선형 모델을 해결하기 위해 사용한다 생각하시면 됩니다.

 

1-1. Step function ( 계단 함수 )

 

 

Neural Networks model 학습 시, 활성화 함수가 미분이 가능해야 합니다.

하지만 Step function은 미분이 불가하며 때문에 역전파 알고리즘을 사용할 수 없습니다.

 

$$h\left( x\right) =\begin{cases}1\quad f\left( x\right) >0\\ 0 \quad    f\left(x\right)\leq 0\end{cases}$$

 

Step function은 다음과 같은 특징을 가집니다.

 

  • Vanishing gradient problem(기울기가 점점 사라짐): activation function의 
      미분 값이 0에 가까울 경우, model을 효과적으로 학습시키지 못함
  • Computational cost: 지수함수가 포함된 경우 상대적으로 Computational cost가 큼
      (expensive, 계산량이 많음)
  • Zero-centered(0이 중심): not zero-centered activation function일 경우,
      model 학습 시, parameter의 update가 비효율적으로 진행됨

 

1-2. Sigmoid

 

 

sigmoid의 식은 다음과 같습니다.

$$h\left( x\right) =\dfrac{1}{1+e^{-x}}$$

 

sigmoid는 출력이 항상 0과 1사이의 값이며 다음과 같은 특징을 가지고 있습니다.

 

  • Computationally expensive
  • Not zero-centered
  • Vanishing gradient problem

 

1-3.  Hyperbolic Tangent ( tanh ) 

 

 

Hyperbolic Tangent는 다음과 같은 식을 가집니다.

 

$$h\left( x\right) =\dfrac{e^{x}-e^{-x}}{e^{x}+e^{-x}}$$

 

특징은 다음과 같습니다.

 

  • 출력이 항상 -1과 1 사이의 값
  • Computationally expensive
  • zero-centered
  • Vanishing gradient problem

이 활성화 함수는 다른 모델에서 잘 사용하지 않는 모델이지만 

RNN (NLP - 자연어 처리)에서 자주 사용합니다.

 

1-4. Rectified Linear Unit ( ReLU )

 

 

ReLU는 다음과 같은 식을 가집니다.

 

$$h\left( x\right) =\begin{cases}x\quad f\left( x\right) >0\\ 0 \quad    f\left(x\right)\leq 0\end{cases}$$

 

ReLU는 사실상 활성화 함수 중 가장 많이 사용하는 함수이며 위에서 서술한 여러 문제가 해결된 함수입니다.

 

  • Computationally inexpensive
  • Not zero-centered
  • Not Vanishing gradient problem

다른 함수는 0보다 너무 커지거나 작아지면 기울기가 소실되어 계속해서 같은 값을 반환하는

Vanishing gradient problem이 발생하지만,

ReLU는 0이 계속 커지더라도 상수를 반환하므로 Vanishing gradient problem이 발생하지 않습니다.

 

728x90

 

2. Neural Networks and Layers

 

출처: COSS 빅데이터

 

위와 같은 딥러닝 모델이 있다 한다면,

왼쪽부터 각각 input layer, hidden layer, output layer입니다.

 

input layer

 

  • 외부로부터 데이터 입력 받는 층
  • ANN model에 적용되는 입력 벡터의 차원과 동일

hidden layer

 

  • 입력층의 노드로부터 전달받은 값을 츨력층까지 전달할 때, 거치는 모든 층

output layer

 

  •  모델이 예측한 결과 값을 나타내는 층

각 노드의 연결마다 가중치 존재하며, 입력 층의 layer의 node index를 i, 도착 layer의 node index를

j라고 할때 각 노드의 연결은 w_ij(n)이 됩니다.

도착 layer에는 각각의 b 값을 가지고 n은 layer의 순서입니다.

 

필요한 가중치와 편향의 수는 입력 층과 도착 층의 곱셈 값 = w, 도착 층의 노드 개수 = b입니다.

만약 1번째 레이어에 노드가 3개, 2번째는 4개라면 w = 12, b = 4가 됩니다.

 

이를 Matrix로 표현하면

a(n) = xW(n) + b(n)
x = [x1 x2]
W(1) = [ w11(1)  w12(1) w13(1) 
              w21(1)  w22(1)  w23(1) ]

가 됩니다.

 

출발 layer의 노드 수는 행의 개수 도착 layer의 노드 수는 열의 개수가 되며,

x와 w는 행렬곱이 가능합니다.

 

input layer에서 hidden layer에 전달된 값이 활성화 함수를 거치며

그 값이 output layer에 전달됩니다.

 

x1 -> (a1(1)->z1(1)) -> (a1(2) -> y1)

위와 같은 과정일 때 여기서 a는 다음과 같은 식입니다.

$$a=\sum x_{w}\left( 1\right) +b\left( 1\right)$$

 

a의 행의 개수는 샘플의 개수, 열의 개수는 도착 layer의 node수,

b의 열의 개수는 도착 layer의 node 수입니다.

 

3. Simple MLP model in python

 

이번에 만들 모델은 input layer node: 2개, hidden layer node: 4개, output layer node: 3개의

Simple MLP model입니다.

 

먼저 필요 라이브러리를 불러옵니다.

import numpy as np

 

 

다음 샘플과 layer입니다.

 

# X가 5개의 sample일 경우 x.shape = (5,2)
x = np.array([[0,1],
    [1,1],
    [-1,0],
    [2,-1],
    [-1,1]])

#-------------input layer -> hidden layer-----------------

# W1.shape = (2,4) (input layer(출발), 첫번째 hidden layer node(도착))
w1 = np.array([[0.5,0.2,-0.3,0.1],
     [-0.2,0.7,-0.4,0.8]])

# b1.shape(4,) (hidden layer node(도착))
b1 = np.array([0.3,-0.1,0.5,-0.4])

#-------------hidden layer -> output layer----------------
    
# w2.shape(4,3) (hidden layer node(출발), output layer node(도착))
w2 = np.array([[0.2,0.7,-0.3],
              [0.8,-0.5,-0.1],
              [0.1,0.5,0.3],
              [-0.6,0.4,0.7],])

# b2.shape(3,) (output layer node(도착))
b2 = np.array([-0.5,0.9,-0.2])

 

input layer가 2개이므로 x의 특징은 2개입니다.

각 가중치와 바이어스 값은 임의의 값입니다.

 

다음 활성화 함수인 sigmoid를 사용하겠습니다.

 

def sigmoid(a):
    return 1/(1+np.exp(-a))
# 입력 a와 동일한 shape의 ndarray를 반환함
# 위 식이 입력 a의 각 원소에 적용됨

 

이제 input layer -> hidden layer를 구현하면 다음과 같습니다.

 

# input layer -> hidden layer(a1, z1)
# a1과 z1의 shape = (5,4) (sample의 수, hidden layer node의 수)
# x.dot(w1): x.shape[1]과 w1.shape[0]은 반드시 동일해야 함
print(x.shape, w1.shape)
a1 = x.dot(w1) + b1
print(a1.shape)
# a1의 각 행은 x의 각 행에 대한 hidden layer node에 대응되는 값
# 그러므로, x의 행과 a1의 행은 동일해야 함

 

x의 shape은 5,2이며, w1은 2,4이므로

a1은 5,4의 행렬이 됩니다.

 

다음 a1을 활성화 함수를 거쳐서 output layer로 전달되도록 구현합니다.

 

# z1은 a1이 activation function(sigmoid)를 통과한 결과
z1 = sigmoid(a1)
# z1은 a1과 동일한 shape

# hidden layer -> output layer
# 입력 z1
# z1.shape = (5,4) (sample의 수, hidden layer node의 수)
# w2.shape = (4,3) (hidden layer node 수, output layer node의 수)
# b2.shape = (3,) (output layer node의 수)
a2 = z1.dot(w2)+b2
# a2의 각 행은 입력값 z1의 각 행에 대한 output layer node에 대응되는 값 
print(a2.shape)

 

결과값에도 sigmoid를 적용합니다.

 

y = sigmoid(a2)
print(y.shape)
# y의 각 행은 입력 X의 각 행에 대한 output layer node의 최종 값
# 그러므로, y.shape = (sample의 수, output layer node의 수)
print(y)
# y는 a2에 대한 sigmoid 값이므로 0~1 사이의 값을 가짐
# -> 가장 큰 값을 갖는 node에 해당하는 class로 판단

 

결과값이 잘 뜨는 모습을 볼 수 있습니다.

0~1사이의 값을 가지며 가장 큰 값을 가진 node에 해당하는 class로 판단하게 되는

MLP model입니다.

728x90
반응형