728x90

활성화 함수




$h(x) = \left\{\begin{matrix}
0 (x\leq 0)\\
1 (x > 0)
\end{matrix}\right.$



[식 1]



h(x)와 같은 활성화 함수는 임계값을 경계로 출력이 바뀌는데, 이런 함수를 계단 함수라 합니다.

그래서 퍼셉트론에서는 활성화 함수로 계단 함수를 이용한다라 할 수 있습니다.

즉, 활성화 함수로 쓸 수 있는 여러 후보 중에서 퍼셉트론은 계단 함수를 채용하고 있습니다.


시그모이드 함수




다음은 신경망에서 자주 이용하는 활성화 함수인 시그모이드 함수를 나타낸 식입니다.



$h(x) = \frac{1}{1 + exp(-x)}$



$exp(-x)$는 $a^{-x}$를 뜻하며, $e$는 자연상수로 2.7182... 의 값을 갖는 실수입니다.

시그모이드 함수도 단순한 함수로, 값을 입력하면 특정 값을 출력합니다.

앞서 배운 퍼셉트론과 앞으로 볼 신경망의 주된 차이는 이 활성화 함수뿐입니다.

뉴런이 여러 층으로 이어진 구조와 신호를 전달하는 방법은 퍼셉트론과 같습니다.


계단 함수 구현하기



def step_function(x):
    if x > 0:
        return 1
    else:
           return 0




이 구현에서, 인수 x는 실수(부동소수점)만 받아들입니다.
즉, step_function(3.0)은 되지만 넘파이 배열을 인수로 넣을 수는 없습니다.



가령 step_function(np.array([1.0, 2.0]))는 안 됩니다. 그러나 우리는 넘파이 배열도 지원하도록 수정하고 싶습니다.
그러기 위해서 다음과 같은 구현을 생각할 수 있겠습니다.


def step_function(x):
    y = x > 0 # y : bool 타입
    return y.astype(np.int) # bool 타입을 int 타입으로 바꿈(True-> 1, False-> 0)




여기서 활용된 넘파이의 특징을 알아봅시다.


>>>import numpy as np
>>>x = np.array([-1.0, 1.0, 2.0])
>>>x
array([-1., 1., 2.])
>>>y = x > 0
>>>y
array([False, True, True], dtype=bool)




넘파이 배열에 부등호 연산을 수행하면 배열의 원소 각각에 부등호 연산을 수행한 bool 배열이 생성됩니다.
배열 x의 원소 각각이 0보다 크면 True로, 0이하면 False로 변환한 새로운 배열 y가 생성됩니다.



이 y는 bool 배열입니다. 그러나 우리가 원하는 계단 함수는 0이나 1의 int 형을 출력하는 함수입니다. 그래서 astype을 통해 배열 y의 원소를 bool에서 int형으로 바꿔줍니다.


>>>y = y.astype(np.int)
>>>y
array([0, 1, 1])




이처럼 넘파이 배열의 자료형변환할 때는 astype()메서드를 이용합니다. 원하는 자료형을 인수로 지정하면 됩니다.
그리고 파이썬에선 bool을 int로 변환하면 True는 1로, False는 0으로 변환됩니다.


계단 함수의 그래프




앞에서 정의한 계단 함수를 그래프로 그려봅시다.


import numpy as np
import matplotlib.pylab as plt

def step_function(x):
    return np.array(x > 0, dtype=np.int)

x = np.arange(-5.0, 5.0, 0.1)
y = step_function(x)
plt.plot(x, y)
plt.ylim(-0.1, 1.1)    # y축의 범위 지정
plt.show()



  • np.arange(-5.0, 5.0, 0.1)은 -5.0에서 5.0 전까지 0.1 간격의 넘파이 배열을 생성
  • 즉, `[-5.0, -4.9, ...4.9]를 생성
  • step_function()은 인수로 받은 넘파이 배열의 원소 각각을 인수로 계단 함수 실행해, 그 결과를 다시 배열로 만들어 돌려줍니다.



    위 코드를 실행하면 아래와 같은 결과나 나옵니다.







    위 결과를 보면 왜 계단 함수인지 아시겠죠?


    시그모이드 함수 구현하기

    def sigmoid(x):
      return 1 / (1 + np.exp(-x))



    실제로 넘파이 배열을 제대로 처리하는지 아래 코드를 통해 실행해보겠습니다.
    >>>x = np.array([-1.0, 1.0, 2.0])
    >>>1.0 + t
    array([2., 3., 4.])
    >>>1.0 / t
    array([1., 0.5, 0.33333333])


    x = np.arange(-5.0, 5.0, 0.1)
    y = sigmoid(x)
    plt.plot(x, y)
    plt.ylim(-0.1, 1.1)
    plt.show()

 

 

 

728x90