개발아 담하자

[Deep Learning] Neural Network 의 Forward Pass 구현해보기 (2) - MNIST 데이터 학습, 예측, 정답률 구하기 본문

🚀 Deep Learning

[Deep Learning] Neural Network 의 Forward Pass 구현해보기 (2) - MNIST 데이터 학습, 예측, 정답률 구하기

choidam 2020. 4. 22. 02:33

선수 환경 1 : https://silver-g-0114.tistory.com/65

 

[Deep Learning] Neural Network 의 Forward Pass 구현해보기 (1)

1. 단순 신경망 구조 만들기 (네트워크 세팅) def init_network(): network = {} network['W'] = np.array([ [0.2, 0.5, 0.3], [0.8, 0.6, 0.4] ]) return network network = init_network() print(network) {'W'..

silver-g-0114.tistory.com

선수 환경 2 : http://yann.lecun.com/exdb/mnist/

 

MNIST handwritten digit database, Yann LeCun, Corinna Cortes and Chris Burges

 

yann.lecun.com

위 사이트의 gz 압축파일 4개를 원하는 디렉토리에 저장한다.

이 MNIST 데이터들을 활용해 학습하고 예측하고 정답률까지 구할 것이다.


1. 데이터 불러오기

import gzip
import pickle
import os
import numpy as np

files = {
    'train_img':'train-images-idx3-ubyte.gz',
    'train_label':'train-labels-idx1-ubyte.gz',
    'test_img':'t10k-images-idx3-ubyte.gz',
    'test_label':'t10k-labels-idx1-ubyte.gz'
}

# gzip 파일을 읽어서 np.array 로 변환한 후 차원 조정

def _load_img(filename):
    with gzip.open(filename, 'rb') as f:
        data = np.frombuffer(f.read(), np.uint8, offset=16)
    data = data.reshape(-1, 784)
    return data

def _load_label(filename):
    with gzip.open(filename, 'rb') as f:
        data = np.frombuffer(f.read(), np.uint8, offset=8)
    return data

def _change_one_hot_label(X):
    T = np.zeros((X.size, 10)) # 초기화
    for idx, row in enumerate(T) :
        row[X[idx]] = 1
    return T

def load_mnist(normalize=True, flatten=True, one_hot_label=True):
    dataset = {}

    for key in ('train_img', 'test_img') :
        dataset[key] = _load_img(files[key])

    for key in ('train_label', 'test_label'):
        dataset[key] = _load_label(files[key])

    if one_hot_label :
        for key in ('train_label', 'test_label'):
            dataset[key] = _change_one_hot_label(dataset[key])
        
    if not flatten :
        for key in ('train_img', 'test_img') :
            dataset[key] = dataset[key].reshape(-1,1,28,28)

    return ((dataset['train_img'], dataset['train_label']), (dataset['test_img'], dataset['test_label']))

load_mnist 함수로 학습 데이터와 라벨, 테스트 데이터와 라벨을 load한다.

 

 

2. Test load_mnist

import numpy as np 
from mnist_data import load_mnist
from matplotlib.pylab import plt

(x_train, y_train), (x_test, y_test) = load_mnist()

for i in range(10):
    img = x_train[i]
    label = np.argmax(y_train[i])
    print(label, end=", ")
    img = img.reshape(28, 28)
    plt.subplot(1, 10, i + 1)
    plt.imshow(img)

print()
plt.show()
5, 0, 4, 1, 9, 2, 1, 3, 1, 4, 

test 실행 결과

load_mnist() 으로 x_train, y_train 데이터 10개를 가져와서 출력해 보았다.
x_train 은 학습 데이터 중 이미지 데이터를 의미하고, y_train 은 학습 데이터 중 정답 데이터를 의미한다.

제대로 데이터가 로드 됨을 확인했으니 이제 본격적으로 예측을 해보자

 

 

3 layer network

우리가 만들 네트워크 계층 구조이다. 

20, 10 개의 perceptron 을 가진 hidden layer 를 가지며 activation 함수로 softmax 를 사용하는 network를 만들것이다.

 

import numpy as np
from mnist_data import load_mnist
from functions import sigmoid, softmax

layers = [784, 20, 10, 10] # perceptron 개수

# 네트워크 초기화
def init_network() :
    network = {}
    network['W1'] = 0.01 * np.random.randn(layers[0], layers[1]) # 784 * 20
    network['W2'] = 0.01 * np.random.randn(layers[1], layers[2]) # 20 * 10
    network['W3'] = 0.01 * np.random.randn(layers[2], layers[3]) # 10 * 20
    network['b1'] = np.zeros(layers[1])
    network['b2'] = np.zeros(layers[2])
    network['b3'] = np.zeros(layers[3])
    return network

# 예측
def predict(network, x):
    W1, W2, W3 = network['W1'], network['W2'], network['W3']
    b1, b2, b3 = network['b1'], network['b2'], network['b3']
    x1 = sigmoid(np.dot(x, W1) + b1)
    x2 = sigmoid(np.dot(x1, W2) + b2)
    y = softmax(np.dot(x2,W3) + b3)
    return y

# 정확도
def accuracy(network, x, t):
    y = predict(network, x) 
    y = np.argmax(y, axis=1) # 내가 예측한 정답
    t = np.argmax(t, axis=1) # 실제 정답
    accuracy = np.sum(y==t)/ float(y.shape[0]) # 정답 비교하기
    return accuracy

(x_train, y_train), (x_test, y_test) = load_mnist()

network = init_network()
print(accuracy(network, x_train, y_train))
0.09736666666666667

 

정확도는 0.097 정도이다.

초기 weight 를 random하게 setting 해 주어서 실행할 때마다 정확도가 다르게 출력된다.