활성화 함수(Acitvation function)과 Python을 통한 구현

활성화 함수는 비선형이여야(하나의 직선으로 표현이 불가능한) 그 의미가 있다 비선형적이 아니라면 층의 깊이를 깊게 하는 것이 의미가 없어진다. 즉 은닉층의 의미가 없어진다는 뜻이다. 

간단한 예제로 

y= 2x 를 활성화 함수로 사용한다고 하면 3층의 깊이로 만든다고 해도 2*2*2*x가 되버린다. 즉 3층의 깊이를 가지는 것처럼 보이지만 실제로는 8(2^3)*x인 하나의 층으로 표현된다. 따라서 활성화 함수는 비선형으로 되어야 하며 주로 사용되는 비선형 활성화 함수는 다음과 같다. 가장 먼저 계단함수이다(Step function).

계단함수는 매우 간단한 입력과 출력값을 가지며 그래프 또한 간단하다. 

matplotlib라이브러리와 numpy를 기본으로 해서 Step함수를 구현해 보도록 하겠다. 

import numpy as np
import matplotlib.pylab as plt


def step_f(x):
return np.array(x>=0)

x = np.arange(-5.0, 5.0, 1)
y = step_f(x)

plt.plot(x,y)
plt.show()
이와 같이 구현하면 step함수를 구현 할 수 있다. 각각 사용할 라이브러리를 import한 후 
numpy의 arrange를 이용해 -5~5까지 1간격으로 넘파이 배열을 생성한 후 함수로 넘겨줘 각각의 원소에 대해 참or거짓 판단을 해 bool값으로 다시 넘겨주게 된다. 이때 필자는 사용하지 않았지만 astype 메서드를 이용해 bool값을 np.int값으로 변환해 주는 것을 추천한다. 이제 위 코드를 실행하면 

다음과 같이 나온다. 중간의 경사는 넘파이 배열의 간격을 더 좁게 하면 점점 줄어들 것이다.이 그래프에서 왜 '계단'함수라고 불리는지는 어렵지 않게 볼 수 있다. 특정한 값을 배경으로 값이 바뀌는 형태를 띄고 있기 때문이다. 
다음은 시그모이드 함수이다. 시그모이드 함수는 신경망에서도 LSTM에서도 자주 사용되는 활성화 함수이다.  시그모이드 함수의 식은 자연상수(e)를 이용해 표현되는데 
이다. 시그모이드 함수 역시 matplotlib와 numpy를 이용하여 구현해 보겠다.
import numpy as np
import matplotlib.pylab 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.show()
생각보다 간단하다. numpy에는 기본적으로 자연상수가 포함되어있기 때문에 쉽게 구현이 가능하다. 또한 이번에는 곡선의 매끄러움을 위해 위와는 다르게 간격을 0.1로 조정했다. 그리고 표현되는 그래프는 다음과 같다.

마지막으로는 ReLU 함수이다. 
최근에 신경망에서 주로 사용되는 함수인데 이는 기존의 시그모이드 함수가 '기울기 소실'이라는 큰 단점을 안고 있었기 때문에 새로 개발된 함수이다. 이 함수의 식은 간단하다. 
정말 놀랍도록 간단하다. 그냥 0보다 큰값은 본인을 return하고 그 외에는 0을 return한다. 
구현 역시 매우 간단하다.

import numpy as np
import matplotlib.pylab 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.show()
maxium함수를 이용해 구현했으며 그래프는 잘 나온다. 


활성 함수에 대한 이야기는 여기까지 하도록 하겠다.



댓글

이 블로그의 인기 게시물

MongoDB와 VScode 이용한 드라이빙app 개발 일지 (2022.4.10)

다양한 계층 구현을 통한 오차역전파법 구현하기(2)