e 는 자연로그의 밑으로, 무리수이며 값은 대략적으로 2.718281828459045 입니다.
>>> np.exp(1)
2.718281828459045
So following code means
>>> a = np.array([0.3, 2.9, 4.0])
>>> exp_a = np.exp(a)
def softmax(a):
exp_a = np.exp(a)
sum_exp_a = np.sum(exp_a)
y = exp_a/sum_exp_a
return y
The code is implemented well, but vulnerable on stack overflow as exp() calculates exponentially.
So this code can be reinforced subtracting max value from each elements.
def softmax(a):
c = np.max(a)
exp_a = np.exp(a-c)
sum_exp_a = np.sum(exp_a)
y = exp_a/sum_exp_a
return y
Sum of y is always 1
>>> a = np.array([0.3, 2.9, 4.0])
>>> y = softmax(a)
>>> y
array([0.01821127, 0.24519181, 0.73659691])
>>> np.sum(y)
1.0
>>>
This leads us to the concept of 'rate'
가령 앞의 예에서 y[0]의 확률은 0.018, y[1]의 확률은 0.245, y[2]의 확률은 0.737로 해석할 수 있습니다. 그리고 이 결과 확률들로부트 "2번째 원소의 확률이 가장 높으니 답은 2번째 클래스다"라고 할 수 있습니다. 혹은 "74%의 확률로 2번째 클래스, 25%확률로 1번째 클래스, 1% 확률로 0번째 클래스다"와 같이 확률적인 결론도 낼 수 있죠. 즉, 소프트맥스 함수를 이용함으로써 문제를 확률적(통계적)으로 대응할 수 있게 되는 것이죠.
여기서 주의할 점으로, 소프트맥스 함수를 적용해도 각 원소의 대소 관계는 변하지 않습니다. 이는 지수 함수 y = exp(x)가 단조 증가 함수이기 때문이죠. 실제로 앞의 예에서는 a의 원소들 사이의 대소 관계가 y의 원소들 사이의 대소 관계로 그대로 이어집니다. 예를 들어 a에서 가장 큰 원소는 2번째 원소이고, y에서 가장 큰 원소도 2번째 원소입니다.
신경망을 이용한 분류에서는 일반적으로 가장 큰 출력을 내는 뉴런에 해당하는 클래스로만 인식합니다. 그리고 소프트맥스 함수를 적용해도 출력이 가장 큰 뉴런의 위치는 달라지지 않습니다. 결과적으로 신경망으로 분류할 떄는 출력층의 소프트맥스 함수를 생략해도 됩니다. 현업에서도 지수 함수 계산에 드는 자원 낭비를 줄이고자 출력층의 소프트맥스 함수는 생략하는 것이 일반적입니다.
-> This is why we DON'T USE SIGMOID on output level.(sigmoid values cannot be interpreted as a ratio.)
In the matter of classification:
(x_train, t_train), (x_test, t_test) = load_mnist(flatten=True, normalize=False)
Flatten here means flattening multidimensional vector into simplified natural number.
파이썬에는 pickle이라는 편리한 기능이 있습니다. 이는 프로그램 실행 중에 특정 객체를 파일로 저장하는 기능입니다. 저장해둔 pickle 파일을 로드하면 실행 당시의 객체를 즉시 복원할 수 있습니다. MNIST 데이터셋을 읽는 load_mnist()함수에서도 (2번째 이후 읽기 시) pickle을 이용합니다. pickle 덕분에 MNIST 데이터를 순식간에 준비할 수 있습니다.
-> So "pickling" means saving the data set on the memory into the disk, than load it directly after then.
드디어 이 MNIST 데이터셋을 가지고 추론을 수행하는 신경망을 구현할 차례입니다. 이 신경망은 입력층 뉴런을 784ㅐ, 출력층 뉴런을 10개로 구성합니다. 입력층 뉴ㅠ런이 784개인 이유는 이미지 크기가 28x28=784이기 때문이고, 출력층 뉴런이 10개인 이유는 이 문제가 0부터 9까지의 숫자를 구분하는 문제이기 때문입니다. 한 편, 은닉층은 총 두개로, 첫 번째 은닉충에는 50개의 뉴런을, 두 번째 은닉층에는 100개의 뉴런을 배치할 것입니다. 여기서 50과 100은 임의로 정한 값입니다.