-
2. 신경망(5)AI 모델(딥러닝 기초)/2. 신경망 2023. 1. 5. 13:29728x90
※ MNIST 데이터셋
- 손글씨 숫자 이미 집합
- 0~9까지의 숫자 이미지로 구성되고 훈련 이미지와 시험 이미지로 구성됨
- 훈련 이미지로 학습 후 시험 이미지로 테스트 하여 정확성을 판별
<기본 MNIST 데이터셋>
# coding: utf-8 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 url_base = 'http://yann.lecun.com/exdb/mnist/' key_file = { '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' } dataset_dir = os.path.dirname(os.path.abspath(__file__)) save_file = dataset_dir + "/mnist.pkl" train_num = 60000 test_num = 10000 img_dim = (1, 28, 28) img_size = 784 def _download(file_name): file_path = dataset_dir + "/" + file_name if os.path.exists(file_path): return print("Downloading " + file_name + " ... ") urllib.request.urlretrieve(url_base + file_name, file_path) print("Done") def download_mnist(): for v in key_file.values(): _download(v) def _load_label(file_name): file_path = dataset_dir + "/" + file_name print("Converting " + file_name + " to NumPy Array ...") with gzip.open(file_path, 'rb') as f: labels = np.frombuffer(f.read(), np.uint8, offset=8) print("Done") return labels def _load_img(file_name): file_path = dataset_dir + "/" + file_name print("Converting " + file_name + " to NumPy Array ...") with gzip.open(file_path, 'rb') as f: data = np.frombuffer(f.read(), np.uint8, offset=16) data = data.reshape(-1, img_size) print("Done") return data def _convert_numpy(): dataset = {} dataset['train_img'] = _load_img(key_file['train_img']) dataset['train_label'] = _load_label(key_file['train_label']) dataset['test_img'] = _load_img(key_file['test_img']) dataset['test_label'] = _load_label(key_file['test_label']) return dataset def init_mnist(): download_mnist() dataset = _convert_numpy() print("Creating pickle file ...") with open(save_file, 'wb') as f: pickle.dump(dataset, f, -1) print("Done!") 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=False): """MNIST 데이터셋 읽기 Parameters ---------- normalize : 이미지의 픽셀 값을 0.0~1.0 사이의 값으로 정규화할지 정한다. one_hot_label : one_hot_label이 True면、레이블을 원-핫(one-hot) 배열로 돌려준다. one-hot 배열은 예를 들어 [0,0,1,0,0,0,0,0,0,0]처럼 한 원소만 1인 배열이다. flatten : 입력 이미지를 1차원 배열로 만들지를 정한다. Returns ------- (훈련 이미지, 훈련 레이블), (시험 이미지, 시험 레이블) """ 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']) if __name__ == '__main__': init_mnist()
<MNIST 데이터셋 불러오기>
# coding: utf-8 import sys, os sys.path.append(os.pardir) # 부모 디렉터리의 파일을 가져올 수 있도록 설정 import numpy as np from dataset.mnist import load_mnist 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) img = x_train[0] label = t_train[0] print(label) # 5 print(img.shape) # (784,) img = img.reshape(28, 28) # 형상을 원래 이미지의 크기로 변형 print(img.shape) # (28, 28) img_show(img)
<MNIST 데이터셋을 활용한 신경망의 accuracy 출력시키기>
# coding: utf-8 import sys, os sys.path.append(os.pardir) # 부모 디렉터리의 파일을 가져올 수 있도록 설정 import numpy as np import pickle from dataset.mnist import load_mnist def sigmoid(x): return 1 / (1+np.exp(-x)) def softmax(a): c = np.max(a) exp_a = np.exp(a-c) sum_exp_a = np.sum(exp_a) y = exp_a / sum_exp_a return y 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 # normalize=True를 통해서 0~255 범위인 각 픽셀의 값을 0.0~1.0 범위로 변환함(픽셀 값을 255로 나눔) # 정규화 : 데이터를 특정 범위로 변환하는 처리(전처리) 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 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)))
MNIST 데이터셋을 활용해서 데이터를 특정 범위로 변환하는 처리를 하는 정규화와 전처리 과정을 살펴보았고, mnist 데이터셋을 load하여 train 시키고 predict함수를 통해 구축해 둔 간단한 신경망 안에서 예측값 출력, 그리고 최종accuracy까지 뽑아내 보았다.
이 과정을 거치면서 이전 데이터 공모전에 출전하여 아무것도 모르는 상태에서 영상 classification 작업을 진행해 본 것이 떠올랐다. 데이터 전처리, 모델 학습, 학습된 모델을 새로운 테스트 데이터셋에 예측 적용, accuracy 뽑아내기 등을 살펴볼 수 있었다. 이 과정에서 epoch만 적절히 조정해 준다면 영상 딥러닝의 기본적인 과정을 모두 살펴볼 수 있는 시간이라고 생각한다.
728x90