학습된 매개변수를 사용하여 학습 과정은 생략하고, 추론과정만 구현 (추론과정=신경망의 순전파)
MNIST 데이터셋
MNIST 데이터셋을 이용하여 모델을 학습하고, 학습한 모델로 시험 이미지들을 얼마나 정확하게 분류하는지 평가한다. 이를 준비하는 코드는 다음과 같다.
# coding: utf-8
import sys, os
sys.path.append(os.pardir) # 부모 디렉터리의 파일을 가져올 수 있도록 설정
import numpy as np
from mnist import load_mnist # MNIST데이터를 (훈련이미지,훈련레이블), (시험이미지, 시험레이블)로 반환
from PIL import Image
def img_show(img): #MNIST이미지 화면으로 불러옴
pil_img = Image.fromarray(np.uint8(img))
pil_img.show()
(x_train, t_train), (x_test, t_test) = load_mnist(flatten=True, normalize=False)
img = x_train[0]
label = t_train[0]
print(label) # 5
print(img.shape) # (784,)
img = img.reshape(28, 28) # 형상을 원래 이미지의 크기로 변형
print(img.shape) # (28, 28)
img_show(img)
load_mnist 함수는 읽은 데이터를 (훈련이미지,훈련레이블), (시험이미지,시험레이블) 형식으로 반환한다. 인수로는 normalize, flatten, one_hot_label 세 가지를 설정할 수 있다.
1) nomalize는 입력 이미지의 픽셀값을 0.0~1.0 사이의 값으로 정규화할지를 정한다.
- false일 경우 입력 이미지 픽셀은 원래 값 그대로 0~244 사이의 값 유지
2) flattern은 입력 이미지를 평탄하게 1차원 배열로 만들지를 정한다.
- false일 경우 입력 이미지를 3차원 배열로, true일 경우 1차원 배열로
3) 원-핫 레이블은 레이블을 원-핫 인코딩 형태로 저장할지 정한다. 정답을 뜻하는 원소만 1, 나머지는 0인 배열
- false면 숫자형태의 레이블을 그대로 저장 / true일때는 인코딩하여 저장
0 > 0001
1 > 0010
2 > 0100
3 > 1000
추론을 수행하는 신경망을 구현해본다.
이 신경망은 입력층 뉴런이 이미지의 크기가 28*28이므로 784이고 출력층은 0~9까지의 숫자를 구분하기 때문에 10이 된다. 은닉층은 2개로 첫 번째 은닉층에서 50개의 뉴런을, 두 번째 은닉층에서 100개의 뉴런을 배치하고자 한다.
# coding: utf-8
import sys, os
sys.path.append(os.pardir) # 부모 디렉터리의 파일을 가져올 수 있도록 설정
import numpy as np
import pickle # 파이썬에서 리스트나 클래스 이외의 자료형을 파일로 저장하고자 할때 사용
from mnist import load_mnist # dataset폴더에 있는 mnist라는 파일에서 load_mnist라는 함수를 import 해라
from common.functions import sigmoid, softmax
def get_data():
(x_train, t_train), (x_test, t_test) = load_mnist(normalize=True, flatten=True, one_hot_label=False)
# flattern = True로 설정해 읽어 들인 이미지는 1차원 넘파이 배열로 저장
return x_test, t_test
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
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)))
# len(x)는 전체 이미지 숫자이고 신경망이 맞춘 숫자를 전체 이미지 숫자로 나눠서 정확도를 구한다.
배치처리
하나로 묶은 입력 데이터를 배치라고한다.
배치처리는 이미지 1장당 처리 시간을 대폭 줄여준다.
배치처리를 구현해본다.
'''
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 # 그 횟수를 증가시킨다.
'''
x, t = get_data()
network = init_network()
batch_size = 100
accuracy_cnt = 0
for i in range(0,len(x), batch_size): # 0부터 batch_size 만큼 묶어나간다.
x_batch = x[i:i+batch_size]
y_batch = predict(network, x_batch)
p = np.argmax(y_batch,axis = 1)
# 100x10의 배열 중 1차원을 구성하는 각 원소에서(1번째 차원을 축으로) 최대값의 인덱스를 찾도록 한 것
accuracy_cnt += np.sum(p == t[i:i+batch_size])
print('Accuracy:' + str(float(accuracy_cnt)/len(x)))
# len(x)는 전체 이미지 숫자이고 신경망이 맞춘 숫자를 전체 이미지 숫자로 나눠서 정확도를 구한다.