Deep learning/모델 구현

3. 신경망(2) - 손글씨 숫자 인식

jwjwvison 2021. 4. 19. 20:18

이 포스팅은 밑바닥부터 시작하는 딥러닝 책을 공부하고 정리한것 입니다.


 이번 절에서는 이미 학습된 매개변수를 사용하여 학습 과정은 생략하고 추론 과정만 구현한다. 이 추론 과정을 신경망의 순전파(forward propagation)라고도 한다.

 

 MNIST의 이미지 데이터는 28x28 크기의 회색조 이미지(1채널)이며, 각 픽셀은 0에서 255까지의 값을 취한다.

import sys,os
sys.path.append(os.pardir)
from dataset.mnist import load_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)

 코드를 보면 가장 먼저 부모 디렉터리의 파일을 가져올 수 있도록 설정했다.

 그럼 데이터도 확인할 겸 MNIST 이미지를 화면으로 불러보겠다. 이미지 표시에는 PIL(python image library) 모듈을 사용한다.

import sys,os
sys.path.append(os.pardir)
import numpy as np
from PIL import Image
import pickle
from dataset.mnist import load_mnist
from common.functions import sigmoid, softmax

def img_show(img):
    pil_img=Image.fromarray(np.uint8(img))  # 넘파이로 저장된 이미지 데이터를 PIL용 데이터 객체로 변환
    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)
print(img.shape)
img=img.reshape(28,28)
print(img.shape)

img_show(img)

 

 이 MNIST 데이터셋을 가지고 추론을 수행하는 신경망을 구현할 차례이다. 이 신경망은 입력층 뉴런을 784개, 출력층 뉴런을 10개로 구성한다. 입력층 뉴런이 784개인 이유는 이미지 크기가 28x28=784이기 때문이고, 출력층 뉴런이 10개인 이유는 이 문제가 0에서 9까지의 숫자를 구분하는 문제이기 때문이다. 한편 은닉층은 총 2개로, 첫 번째 은닉층에서는 50개의 뉴런을, 두 뻔째 은닉층에서는 100개의 뉴런을 배치할 것이다.

def get_data():
    (x_train,t_train),(x_test,t_test)=load_mnist(normalize=True,flatten=True,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 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

 init_network() 에서는 pickle 파일인 sample_weight.pkl에 저장된 '학습된 가중치 매개변수'를 읽는다. 이 파일에는 가중치와 편향 매개변수가 딕셔너리 변수로 저장되어 있다.

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

 위 예에서는 normalize를 True로 설정했는데 이는 0~244 범위인 각 픽셀의 값을 0.0~1.0 범위로 변환한다. (단순히 픽셀의 값을 255로 나눈다). 이처럼 데이터를 특정 범위로 변환하는 처리를 정규화(normalization)라 하고, 신경망의 입력 데이터에 특정 변환을 가하는 것을 전처리(pre-processing)라 한다. 여기에서는 입력 이미지 데이터에 대한 전처리 작업으로 정규화를 수행한 셈이다.

 

'Deep learning > 모델 구현' 카테고리의 다른 글

6. 신경망 학습 (3) - 학습 알고리즘 구현하기  (0) 2021.04.20
5. 신경망 학습 (2) - 기울기  (0) 2021.04.20
4. 신경망 학습 (1) - 손실함수  (0) 2021.04.19
2. 신경망 (1)  (0) 2021.04.19
1. 퍼셉트론  (0) 2021.04.17