Ch.3 신경망/ 3.5 출력층 설계하기
신경망은 분류와 회귀 모두에 이용할 수 있는데, 어떤 문제냐에 따라서 출력층에서 사용되는 활성화 함수가 다르다.
일반적으로 회귀에서는 항등 함수, 분류에서는 소프트맥스 함수를 사용한다.
## 기계학습 문제는 분류와 회귀로 나뉜다. 분류는 데이터가 어느 클래스에 속하느냐의 문제, 즉 사진 속 인물의 성별을 분류하는 것들이다. 회귀는 입력 데이터에서 연속적인 수치를 예측하는 문제이다. 이를테면 사진 속의 인물의 몸무게를 예측하는 문제로 예시를 들고 있다. ##
3.5.1 항등 함수와 소프트맥스 함수 구현하기
이를 식으로 옮긴다면 다음과 같은 형태라고 볼 수 있다.
import numpy as np
a = np.array([0.3,2.9,4.0])
exp_a=np.exp(a)
sum_exp_a=np.sum(exp_a) #행렬값을 모두 더해주는 메소드
y=exp_a/sum_exp_a
print(y)
def softmax(a):
exp_a=np.exp(a)
sum_exp_a=np.sum(exp_a)
y=exp_a/sum_exp_a
return y
numpy에는 참 많은 메소드들이 있다. 하나 둘 익혀보자
3.5.2 소프트맥스 함수 구현 시 주의점
약간 딴 얘기로 넘어가는 것인데, exponential 특성 상 값이 굉장히 급격하게 증가한다. 그리고 이는 당연하게도 overflow의 주범이 되고 만다.... 그렇다면 큰 값에 대한 해결방법이 없냐하면 그건 또 아니다. 다음 수식을 보자
C'에 충분한 음수를 넣어준다면 굉장히 큰 a에 대해서 대비할 수 있다.
이를 코드로 옮긴다면
def safe_softmax(a):
c=np.max(a)
exp_a=np.exp(a-c)
sum_exp_a=np.sum(exp_a-c)
y=exp_a/sum_exp_a
return y
당연하게도 결과 역시 그냥 softmax와 동일하게 나온다.
3.5.3 소프트맥스 함수의 특징
소프트맥스 함수의 수식을 잘 기억해보자. 분명 분모가 시그마꼴로 되어있었다. 즉 소프트맥스 함수의 출력의 총합은 1.0이 된다는 것을 알 수 있다.
우리는 고등학교 시절 배운 확률을 조금 기억해볼 필요가 있다. 35%를 과연 무엇이라 표현했던가? 0.35로 표기했었다. 즉 우리는 소프트맥스의 최댓값이 1.0이라는 것을 이용해, 이를 '확률'로 생각해볼 수 있다고 한다.
[0.01821127 0.24519181 0.73659691]
위 예시에서의 값인데, 이를 확률로 해석한다면 y[0]의 확률이 약 18%, y[1]의 확률이 약 24%, y[2]는 73%이다.
이 결과를 통해서 "2번째 원소의 확률이 가장 높으므로, 답은 2번째 클래스다"라고 할 수 있다.
즉 소프트맥스 함수를 통해서 문제를 확률적으로 대응할 수 있게 되는 것이다.
그런데 책에 나와있기를... 신경망을 이용한 분류에서는 일반적으로 가장 큰 출력을 내는 뉴런에 해당하는 클래스로만 인식하고, 소프트맥스 함수를 적용해도 출력이 가장 큰 뉴런의 위치는 달라지지 않는다고 한다. 그래서 신경망을 분류할때는 출력층의 소프트맥스 함수를 생략한다고 한다. 현업에서도 지수함수 계산에 드는 자원 낭비를 줄이고자 생략한다고 하는데... (신경망을 학습시킬 때는 사용한다고 한다.) 추후 책을 더 읽어보고 다시 읽어봐야할 부분인 것 같다.