huskycat1202
03. 신경망 (손글씨 숫자 인식) 본문
이 글은 '밑바닥부터 시작하는 딥러닝' 이란 책으로 공부하며 작성했다.
저번에 github 저장소를 못 찾아 진행하지 못한 손글씨 숫자 인식 실습을 진행하려고 한다.
1. MNIST 데이터셋 준비
MNIST 데이터셋을 다운받아 이미지를 numpy 배열로 변환하는 python 스크립트를 사용한다.
ch03의 부모 디렉터리에 저장한 아래 코드를 python3로 실행한다.
github.com/WegraLee/deep-learning-from-scratch/blob/master/dataset/mnist.py
WegraLee/deep-learning-from-scratch
『밑바닥부터 시작하는 딥러닝』(한빛미디어, 2017). Contribute to WegraLee/deep-learning-from-scratch development by creating an account on GitHub.
github.com
load_mnist함수를 보면, 아래 3가지 인수가 있다.
normalize : 이미지의 픽셀 값을 0.0~1.0 사이의 값 / 0~255 사이의 값
flatten : 입력 이미지를 784개 원소 1차원 배열 / 1x28x28 3차원 배열
one_hot_label : 레이블을 원-핫(one-hot) 배열(정답인 한 원소만 1인 배열) / 일반 숫자 형태
load_mnist 함수는 (훈련 이미지, 훈련 레이블), (시험 이미지, 시험 레이블) 의 형식으로 반환한다.
def load_mnist(normalize=True, flatten=True, one_hot_label=False):
if not os.path.exists(save_file):
init_mnist()
with open(save_file, 'rb') as f:
dataset = pickle.load(f)
if normalize:
for key in ('train_img', 'test_img'):
dataset[key] = dataset[key].astype(np.float32)
dataset[key] /= 255.0
if one_hot_label:
dataset['train_label'] = _change_one_hot_label(dataset['train_label'])
dataset['test_label'] = _change_one_hot_label(dataset['test_label'])
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'])
ch03의 mnist_show.py를 실행한다.
여기서 dataset.mnist로 인해 엄청나게 많은 에러를 만났는데, 거의다 실패하고 아래 하나만 성공했다.
파이썬 버전과 경로, 현재 위치에 주의해야한다,
(base) ➜ dataset python3 ../ch03/mnist_show.py
Traceback (most recent call last):
File "/Users/annie/Downloads/deep-learning-from-scratch-master/dataset/../ch03/mnist_show.py", line 6, in <module>
from PIL import Image
ModuleNotFoundError: No module named 'PIL'
pip3 install pillow를 통해 해결한다.
(base) ➜ dataset python3 ../ch03/mnist_show.py
5
(784,)
(28, 28)
2. MNIST 데이터셋으로 추론하는 신경망 구현
입력층: 이미지 크기=28*28=784
은닉층1: 50
은닉층2: 100
출력층: 0~9 구분=10
neuralnet_mnist.py
# coding: utf-8
import sys, os
sys.path.append(os.pardir) # 부모 디렉터리의 파일을 가져올 수 있도록 설정
import numpy as np
import pickle
from dataset.mnist import load_mnist
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)
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): # 레이블 확률 -> numpy 배열
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]) # 이미지 1장씩 분류
p= np.argmax(y) # 확률이 가장 높은 원소의 인덱스를 얻는다.
if p == t[i]: #분류 맞췄나
accuracy_cnt += 1
print("Accuracy:" + str(float(accuracy_cnt) / len(x)))
옳게 분류한 비율이 93.52%이다.
(base) ➜ ch03 python3 neuralnet_mnist.py
Accuracy:0.9352
실제 신경망(딥러닝)에 전처리를 사용하는데, 이를 통해 식별 능력 개선, 학습 속도 증가 등이 이뤄진다.
'Deep Learning' 카테고리의 다른 글
04. 신경망 학습 (0) | 2021.01.30 |
---|---|
03. 신경망 (1) | 2021.01.24 |
02. 퍼셉트론 (0) | 2021.01.24 |
01. 헬로 파이썬 (0) | 2021.01.23 |