티스토리 뷰

손글씨 숫자 분류를 통해 이미 학습된 매개변수를 사용하여 학습 과정은 생략하고, 추론 과정만 구현해 보겠습니다.


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가 출력되는 점을 확인해 볼 수 있습니다.


X                   W1             W2               W3            ->             Y

784           784 * 50        50 * 100       100 * 10                         10

784개로 구성된 1차원 배열이 입력되어 마지막에는 원소가 10개인 1차원 배열이 출력되는 흐름입니다.


 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)



range() 함수가 반환하는 리스트를 바탕으로 x[i:i_batch_size]에서 입력 데이터를 묶습니다. batch_size가 100이므로 
x[0:100], x[100:200], ...와 같이 앞에서부터 100장씩 묶어 꺼내게 됩니다.

argmax()로 최댓값의 인덱스를 가져옵니다. 여기서 axis=1이라는 인수는 100 * 10의 배열 중 1번째 차원을 구성하는 원소에서 최댓값의 
인덱스를 찾도록 한 것입니다.

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)))


댓글
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31