import sys
import os
sys.path.append(os.pardir) # 부모 directory의 파일 가져오기
from dataset.mnist import load_mnist # mnist dataset load function import
# MNIST dataset load
'''
normalize - 입력 img의 픽셀값을 0.0~1.0사이로 정규화 할것인지, 안하면 0~255 원본값 유지
flatten - 입력 이미지를 평탄하게 784개의 원소의 1차원 배열로 만들것인지, 안하면 1*28*28 3차원 배열로 유지
one-hot-label - label을 원-핫 인코딩 형태로 저장할 것인지
'''
(x_train, t_train), (x_test, t_test) = load_mnist(flatten=True, normalize=False)
# print data shape
print(x_train.shape)
print(t_train.shape)
print(x_test.shape)
print(t_test.shape)
(60000, 784) (60000,) (10000, 784) (10000,)
# show image
import numpy as np
from PIL import Image
def img_show(img):
pil_img = Image.fromarray(np.uint8(img)) # numpy로 저장된 img를 PIL용 data객체로 변환
pil_img.show()
img = x_train[0]
label = t_train[0]
print('img label : ', label)
print('before img shape : ', img.shape)
img = img.reshape(28, 28) # 1차원 numpy array로 저장된 img를 다시 28*28 크기로 변형
print('after img shape : ', img.shape)
img_show(img)
img label : 5 before img shape : (784,) after img shape : (28, 28)
import pickle
def get_data():
(x_train, t_train), (x_test, t_test) = load_mnist(flatten=True, normalize=False)
return x_test, t_test
# pickle file(sample_weight.pkl)에 저장된 '학습된 가중치 매개변수' load
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))
# temp_x = x.tolist()
# for i in range(len(temp_x)):
# x1 = temp_x[i]
# # 원소 값이 작을 경우 -x하는 과정에서 overflow가 발생할 수 있으므로
# # if문을 통해 조건을 걸어서 리턴
# if x1 < 0:
# temp_x[i] = np.exp(x1) / (1 + np.exp(x1))
# else:
# temp_x[i] = 1 / (1 + np.exp(-x1))
# return np.array(temp_x)
def softmax(a):
exp_a = np.exp(a)
sum_exp_a = np.sum(exp_a)
c = np.max(a) # overflow방지
a -= c
y = np.exp(a) / np.sum(np.exp(a))
return y
# 각 label의 확률을 numpy array로 return
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
d1 = sigmoid(a1)
a2 = np.dot(d1, W2) + b2
d2 = sigmoid(a2)
a3 = np.dot(d2, W3) + b3
y = softmax(a3)
return y
# main
x, t = get_data() # get dataset
network = init_network() # create network
accuracy_cnt = 0 # 분류가 얼마나 올바른지 판단
for i in range(len(x)):
y = predict(network, x[i])
p = np.argmax(y) # 확률이 가장 높은 원소의 index 얻기
if p == t[i]:
accuracy_cnt += 1
print("Accuracy: ", str(float(accuracy_cnt) / len(x)))
Accuracy: 0.9207
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] # batch의 크기만큼 한번에 묶기
y_batch = predict(network, x_batch) # 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)))
Accuracy: 0.9207
C:\Users\hyosun\AppData\Local\Temp\ipykernel_11128\2019075988.py:14: RuntimeWarning: overflow encountered in exp return 1 / (1 + np.exp(-x))
퍼셉트론에서는 급격히 변화하는 step function을 사용했다는 차이
numpy의 다차원 배열을 활용하면 효율적 처리 OK