3.1.2 퍼셉트론 복습



인공 신경망은 퍼셉트론과 비슷하면서 다르다. 여러개의 층으로 이루어져 있고, 은닉층(hidden layer)가 존재한다.
3.1.3 활성화 함수(activation function)


활성화 함수는 입력신호의 총합에 적용되어 활성화를 일으키는지 결정하는 역할을 한다.
원래 a라는 결과를 가진 노드를 노드를 y라는 노드로 변환 시켜주는 역할을 하는 함수인 것이다.
- 활성화 함수는 비선형 함수여야 한다.
선형함수를 사용하면, 얼마나 많은 레이어가 네트워크에 있는지에 관계없이
결국 single-layer perceptron로 구현할 수 있는, 똑같이 행동하는 네트워크가 된다.
3.2.1 시그모이드 함수(sigmoid function)


- 시그모이드 함수의 중요한 특징 중 하나는,
입력값이 클수록 출력을 1에 가깝게 내고 작을수록 출력을 0에 가깝게 낸다는 점이다.
- 해석이 용이하다는 이유로 과거에 많이 사용하였다.
- Saturation, vanishing gradient 문제가 존재한다.
gradient가 0이 되어 back propagation시 weight의 업데이트가 중지되는 현상을 의미한다.
- zero-centered가 아니라는 문제가 존재한다.
3.2.7 ReLU 함수 (Rectified Linear Unit)


- 최근에 주로 이용하는 함수로, 시그모이드 함수의 saturation 문제가 존재하지 않는다.
- 계산이 더욱 간편하고, 시그모이드나 tanh에 비하여 더욱 빠르게 수렴하는 장점이 있다.
3.4 3층 신경망 구현하기
np.ndim(A) # A의 dimension을 리턴
A.shape() # A의 shape에 맞는 튜플을 리턴
np.dot(A, B) # 행렬 곱


import numpy as np
import matplotlib.pylab as plt
def sigmoid(x):
return 1/ (1+ np.exp(-x))
#출력층의 활성화 함수
def activation_out(x):
return x
# (1,2)
x = np.array([[1.0, 0.5]])
# (2,3) -- 2개 인풋, 3개 다음 뉴런 생성
w1 = np.array([[0.1,0.3,0.5], [0.2, 0.4, 0.6]])
b1 = np.array([0.1,0.2,0.3])
# A = XW + B (1번째 hidden layer)
A1 = np.dot(x, w1) + b1
Z1= sigmoid(A1)
print("first layer: ")
print(Z1)
#(3,2) -- 3개의 인풋, 2개의 다음 뉴런 생성
w2 = np.array([[0.1, 0.4], [0.2, 0.5], [0.3, 0.6]])
b2 = np.array([0.1, 0.2])
A2 = np.dot(Z1, w2) + b2
Z2 = sigmoid(A2)
print("second layer: ")
print(Z2)
#(2,2) -- 2개의 인풋, 2개의 출력층 뉴런 생성
w3 = np.array([[0.1, 0.3],[0.2, 0.4]])
b3 = np.array([0.1, 0.2])
A3 = np.dot(Z2, w3) + b3
Y = activation_out(A3)
print("out: ")
print(Y)
3.5 출력층 설계
일반적으로 classification에는 softmax, regression에는 항등함수를 사용한다.
3.5.1 Softmax 함수

다만, 위 식을 그대로 코드로 구현하면 오버플로우 문제가 생길 수 있다.

softmax 함수는 0 - 1 사이의 실수를 반환하고, 출력의 총합을 1로 만든다.
즉, 소프트맥스 함수는 출력이 확률의 특성을 갖도록 만든다.
def softmax(a):
max_a = np.max(a)
exp_a = np.exp(a - max_a)
sum_exp_a = np.sum(exp_a)
y = exp_a / sum_exp_a
return y
3.6 MNIST 데이터셋 / Forward propagation
import sys, os
import numpy as np
import pickle
sys.path.append(os.pardir)
from dataset.mnist import load_mnist
from PIL import Image
(x_train, t_train) , (x_test, t_test) = \
load_mnist(flatten= True, normalize=True, one_hot_label = False)
# normalize - 픽셀 값을 0~1로 정규화 (0~255)
# flatten - false인 경우 3차원 배열(1x28x28) 아닐경우 784개 원소 1차원 배열
# one_hot_label - 원핫인코딩 여부
print(x_train.shape) # 60000, 784 - 훈련 이미지
print(t_train.shape) # 60000, 훈련 레이블
print(x_test.shape) # 10000, 784
print(t_test.shape) # 10000,
def sigmoid(x):
return 1 / (1+ np.exp(-x))
def softmax(x):
max_x = np.max(x)
exp_x = np.exp(x - max_x)
y = exp_x / np.sum(exp_x)
return y
def img_show(img):
pil_img = Image.fromarray(np.uint8(img)) #넘파이 배열을 PIL용 객체로 변환
pil_img.show()
"""img = x_train[0]
label = t_train[0]
print(label)
img = img.reshape(28, 28) # 원래 모양으로 변형
img_show(img)"""
# 1층 50개 , 2층 100개 뉴런 , 출력은 10(0~9)
# pickle 파일에 저장된 학습된 매개변수를 읽어옴.
# 이 파일에는 weight와 bias가 딕셔너리로 저장되어 있다.
# w1 = 784, 50
# w2 = 50, 100
# w3 = 100, 10
def init_network():
#바이트 형식으로 여네용
with open("sample_weight.pkl", 'rb') as f:
network = pickle.load(f)
return network
def predict(network, x):
W1, W2, W3 = network['W1'], network['W2'], network['W3']
b1, b2, b3 = network['b1'], network['b2'], network['b3']
a1 = np.dot(x,W1) + b1
z1 = sigmoid(a1)
a2 = np.dot(z1, W2) + b2
z2 = sigmoid(a2)
a3 = np.dot(z2, W3) + b3
y= softmax(a3)
return y
network = init_network()
accuracy = 0
for i in range(len(x_test)):
y = predict(network, x_test[i])
prediction = np.argmax(y) #확률이 제일 높은 인덱스
if (prediction == t_test[i]):
accuracy += 1
print(str(float(accuracy)/ len(x_test))) # 0.9352
이 때, 입력값 x중 n개를 1개의 배치로 묶어 학습시킬 수 있다. 이 경우 입력 행렬 X는 (n, 784)의 형태가 된다.
배치 처리를 하는 경우 다음 두 가지의 장점이 존재한다.
1. 큰 배열을 효율적으로 처리하는 라이브러리의 최적화를 이용할 수 있다.
2. I/O 처리 횟수가 줄어 버스 부하를 줄이고, CPU 계산에 쓰이는 비율을 늘릴 수 있다.
아래 코드는 배치 처리를 사용하여 prediction하는 코드이다.
batch_size = 100
accuracy_batch = 0
for i in range(0, len(x_test), batch_size):
x_batch = x_test[i:i+batch_size]
y_batch = predict(network, x_batch)
pred = np.argmax(y_batch, axis =1) # 각 행의 최댓값 인덱스를 리턴함
accuracy_batch += np.sum(pred == t_test[i:i+batch_size])
print(str(float(accuracy_batch)/ len(x_test))) # 0.9352
'Deep Learning' 카테고리의 다른 글
| CH7 - CNN(Convolutional Neural Network) (0) | 2022.08.12 |
|---|---|
| CH6 - 학습 관련 기술들 (2) | 2022.07.20 |
| CH5 - Back Propagation (0) | 2022.07.13 |
| CH4 - 신경망 학습(Training Neural Network) (0) | 2022.07.06 |
| CH2 - 퍼셉트론(Perceptron) (0) | 2022.06.30 |