◆ 활성화 함수
전 포스트에서 h(x)라는 함수가 등장했는데, 이처럼 입력 신호의 총합을 출력 신호로 변환하는 함수를 일반적으로 활성화 함수(activation function)라고 한다. 활성화 함수는 입력 신호의 총합이 활겅화를 일으키는지를 정하는 역할을 한다.
[식 3.3]과 같이 활성화 함수는 임계값을 경계로 출력이 바뀌는데, 이런 함수를 계단 함수(step function)이라고 한다. 그래서 "퍼셉트론에서는 활성화 함수로 계단함수를 이용한다."라 할 수 있다. 즉, 활성화 함수로 쓸 수 있는 여러 후보 중에서 퍼셉트론은 계단 함수를 채용하고 있다.
그럼 [식 3.2]를 다시 써보자. [식 3.2]는 가중치가 곱해진 입력신호의 총합을 계산하고, 그 합을 활성화 함수에 입력해 결과를 내는 2단계로 처리된다. 그래서 이 식은 다음과 같은 2개의 시긍로 나눌 수 있다.
$ a=h(b+w1x1+w2x2) $
[식 3.4]
$y = h(a) $
[식 3.5]
[식 3.4]는 가중치가 달린 입력신호와 편향의 총합을 계산하고, 이를 a라 한다. 그리고 [식 3.5]는 a를 함수 h()에 넣어 y를 출력하는 흐름이다.
◆ 시그모이드 함수
다음은 신경망에서 자주 이용하는 활성화 함수인 시그모이드 함수(sigmoid function)을 나타낸 식이다.
$ h(x) = \frac{1}{1 + exp(-x)} $
[식 3.6]
[식 3.6]에서 exp(-x)는 $e^{-x}$를 뜻하며, e는 자연상수 2.7182...이다.
신경망에서는 활성화 함수로 시그모이드 함수를 이용하여 신호를 변환하고, 변환된 신호를 다음 뉴런에 전달한다. 우리가 앞에서 본 퍼셉트론과 앞으로 볼 신경망의 주된 차이는 활성화 함수뿐이다.
◆ 계단함수와 시그모이드함수 비교
- 계단함수 구현
이 구현은 단순하고 쉽지만, 인수 x는 실수(부동소수점)만 받아들이다. 즉 step_function(3.0)은 되지만 넘파이 배열을 인수로 넣는 수는 없다. 가령 step_function(np.array([1.0, 2.0]))는 안 된다.
이런식으로 넘파이의 편리한 트릭을 사용하면 해결 가능하다.
x = np.array([-1.0, 1.0, 2.0]) 을 수행하면 넘파이 배열이 생성되고
y = x > 0를 수행하고 y를 출력하면 array([False, True, True], dtype=bool)이 출력된다.
이 y는 bool배열이다. 그런데 우리가 원하는 계단 함수는 0이나 1의 'int형'을 출력하는 함수이다. 그래서 배열 y의 원소를 bool에서 int형으로 바꿔준다.
y = y.astype(np.int) -> Numpy버전에서 더이상 사용되지 않으며 대신 int 또는 np.int32, np.int64를 사용해야 한다.
이처럼 넘파이 배열의 자료형을 변환할 때는 astype() 메서드를 이용한다.
- 계단함수의 그래프
[그림 3-6]에서 보듯 계단 함수는 0을 경계로 출력이 0에서 1(또는 1에서 0)로 바뀐다. 계단처럼 생겨서 계단함수이다.
- 시그모이드함수 구현하기
이런식으로 sigmoid함수를 구현할 수 있다. 이 함수가 넘파이 배열도 훌륭히 처리해줄 수 있는 비밀은 넘파이의 브로드캐스트에 있다. 그럼, 시그모이드 함수를 그려보자.
- 시그모이드 함수와 계단 함수 비교
이 둘의 차이점은 '매끄러움'이다. 시그모이드 함수는 부드러운 곡선이며 입력에 따라 출력이 연속적으로 변화한다. 한편, 계단 함수는 0을 경계로 출력이 갑자기 바뀌어버린다. 시그모이드 함수의 이 매끈함이 신경망 학습에서 아주 중요한 역할을 하게 된다.
또한 계단 함수가 0과 1 중 하나의 값만 돌려주는 반면 시그모이드 함수는 실수를 돌려준다는 점도 다르다. 다시 말해 퍼셉트론에서는 뉴런 사이에 0과 1이 흘렀다면, 신경망에서는 연속적인 실수가 흐른다.
둘의 공통점은 큰 관점에서 보면 같은 모양을 하고 있다. 즉, 입력이 중요하면 큰 값을 출력하고 입력이 중요하지 않다면 작은 값을 출력한다. 그리고 입력이 아무리 작거나 커도 출력은 0에서 1 사이라는 것도 둘의 공통점이다.
또한 둘 모두 비선형 함수이다.계단 함수처럼 구부러진 직선으로 나타나는 것도 비선형 함수라고 한다.
신경망에서는 활성화 함수로 비선형 함수를 사용해야 한다. 선형 함수를 이용하면 신경망의 층을 깊게 하는 의미가 없어지기 때문이다.
선형 함수의 문제는 층을 아무리 깊게 해도 은닉측이 없는 '네트워크'로도 똑같은 기능을 할 수 있다는 데 있다. 예를 들어 선형 함수인 h(x) = cx를 활성화 함수로 사용한 3층 네트워크를 떠올려 보자. 이를 식으로 나타내면 y(x) = h(h(h(x)))가 된다. 이 계산은
y(x) = c * c * c * x 처럼 곱셈을 세번 수행하지만 실은 y(x) = ax와 똑같다. 즉, 은닉츠잉 없는 네트워크로 표현이 가능하다. 선형 함수를 이용해서는 여러 층으로 구성하는 이점을 살릴 수 없다. 그래서 층을 쌓는 혜택을 얻고 싶다면 활성화 함수로는 반드시 비선형 함수를 사용해야 한다.
'딥러닝 > 밑바닥부터 시작하는 딥러닝1' 카테고리의 다른 글
[6장] 배치 정규화, 오버피팅, 가중치 감소, 드롭아웃 (0) | 2025.04.02 |
---|---|
[6장] 가중치의 초깃값 (0) | 2025.04.02 |
[6장] 매개변수 갱신방법 (0) | 2025.04.02 |
퍼셉트론 (0) | 2024.10.01 |
파이썬 지식 (0) | 2024.10.01 |