티스토리 뷰
손글씨 숫자 분류를 통해 이미 학습된 매개변수를 사용하여 학습 과정은 생략하고, 추론 과정만 구현해 보겠습니다.
1. MNIST 데이터셋
MNIST 데이터셋은 0부터 9까지의 숫자 이미지로 구성됩니다. 훈련 이미지 60,000장 시험 이미지 10,000으로 학습한 모델로 시험 이미지들을 얼마나 정확하게 분류하는지 보겠습니다.
MNIST의 이미지 데이터는 28 * 28 크기의 이미지(1채널)이며, 각 픽셀은 0에서 255까지의 값을 취합니다.
load_mnist 함수는 읽은 MNIST 데이터를 "(훈련 이미지, 훈련 레이블), (시험 이미지, 시험 레이블)" 형식으로 반환합니다.
인수로는 normalize, flatten, one_hot_label 세 가지를 설정할 수 있습니다.
normalize는 입력 이미지의 픽셀 값을 0.0~1.0 사이의 값으로 정규화할지를 정합니다.
False로 설정하면 입력 이미지의 픽셀은 원래 값 그대로 0~255 사이의 값을 유지합니다.
flatten은 입력 이미지를 평탄하게, 즉 1차원 배열로 만들지를 정합니다.
one_hot_label은 레이블링을 원-핫 인코딩 형태로 저장할지를 정합니다.
if __name__ == '__main__':
init_mnist()
(x_train, t_train), (x_test, t_test) = \
load_mnist(flatten=True, normalize=False)
#각 데이터의 형상 출력
print(x_train.shape)
print(t_train.shape)
print(x_test.shape)
print(t_test.shape)
(60000, 784)
(60000,)
(10000, 784)
(10000,)
MNIST 이미지를 화면으로 불러보도록 하겠습니다.
PIL모듈을 사용합니다.
여기서 flatten=True로 설정해 읽어 들인 이미지는 1차원 넘파이 배여로 저장되어 있다는 것입니다.
그래서 reshape() 메서드에 원하는 형상을 인수로 지정하면 넘파이 배열의 형상을 바꿀 수 있습니다.
try:
import urllib.request
except ImportError:
raise ImportError('You should use Python 3.x')
import os.path
import gzip
import pickle
import os
import numpy as np
import sys
from PIL import Image
def img_show(img):
pil_img = Image.fromarray(np.uint8(img))
pil_img.show()
(x_train, t_train), (x_test, t_test) = \
load_mnist(flatten=True, normalize=False)
if __name__ == '__main__':
(x_train, t_train), (x_test, t_test) = \
load_mnist(flatten=True, normalize=False)
img = x_train[0]
label = t_train[0]
print(label)
print(img.shape)
img = img.reshape(28, 28)
print(img.shape)
img_show(img)
2. 신경망의 추론 처리
이 신경망은 입력층 뉴런을 784개, 출력층 뉴런을 10개로 구성합니다.
은닉층은 총 두 개로, 첫번째 은닉층에는 50개의 뉴런을, 두 번째 은닉층에는 100개의 뉴런을 배치할 것입니다.
먼저 MNIST 데이터셋을 얻고 네트워크를 생성합니다.
이어서 for 문을 돌며 x에 저장 된 이미지 데이터를 1장씩 꺼내 predict() 함수로 분류합니다. predict() 함수는 각 레이블의 확률을
넘파이 배열로 반환하게 됩니다. 예를 들어 [0.1, 0.3, 0.2 .... 0.04] 같은 배열이 반환되며, 이는 이미지가
숫자 '0'일 확률이 0.1 '1'일 확률이 0.3 ...
이런식으로 해석합니다.
np.argmax() 함수로 이 배열에서 값이 가장 큰 원소의 인덱스를 구합니다. 이것이 바로 예측 결과!
마지막으로 신경망이 예측한 답변과 정답 레이블을 비교해 맞힌 숫자 accuracy_nct를 세고 전체 이미지 숫자로 나눠 정확도를 계산합니다.
def get_data():
(x_train, t_train), (x_test, t_test) = \
load_mnist(flatten=True, normalize=False, one_hot_label=False)
return x_test, t_test
def init_network():
with open("sample_weight.pkl", 'rb') as f:
network = pickle.load(f)
return network
def sigmoid(x):
return 1 / (1 + np.exp(-x))
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 = sigmoid(a3)
return y
if __name__ == '__main__':
x, t = get_data()
network = init_network()
accuracy_cnt = 0
for i in range(len(x)):
y = predict(network, x[i])
p = np.argmax(y)
if p == t[i]:
accuracy_cnt += 1
print("Accuracy:" + str(float(accuracy_cnt) / len(x)))
결과값
Accuracy:0.9207
3. 배치 처리
이 결과에서 다차원 배열의 대응하는 차원의 원소 수가 일치함을 확인할 수 있습니다. 그리고 최종 결과로는 원소가 10개인 1차원
배열 y가 출력되는 점을 확인해 볼 수 있습니다.
print(x.shape)
print(x[0].shape)
print(W1.shape)
print(W2.shape)
print(W3.shape)
결과값
(10000, 784)
(784,)
(784, 50)
(50, 100)
(100, 10)
x,t = get_data()
network = init_network()
batch_size = 100
accuracy_cnt = 0
for i in range(0, len(x), batch_size):
x_batch = x[i:i+batch_size]
y_batch = predict(network, x_batch)
p = np.argmax(y_batch, axis = 1)
accuracy_cnt += np.sum(p == t[i:i+batch_size])
print("Accuracy:" + str(float(accuracy_cnt) / len(x)))
'딥러닝' 카테고리의 다른 글
딥러닝 - 07. 경사법(경사 하강법) / 신경망 기울기 (0) | 2019.03.21 |
---|---|
딥러닝 - 06. 손실함수 (0) | 2019.03.14 |
딥러닝 - 04. 신경망 (3) 출력층 설계 (0) | 2019.02.21 |
딥러닝 - 04. 신경망 (2) 3층 신경망 구현 (0) | 2019.02.19 |
딥러닝 - 04. 신경망 (1) 활성화, 계단, 시그모이드 함수 (0) | 2019.02.19 |