아직 여러 데이터를 접해보지 못했을 때에는 궁금했습니다.
비정형 데이터들이 어떤 식의 데이터로 넣어 머신러닝이 학습하는지 도무지 감이 오지 않았죠. 이 책을 통해서 접하면서 신세계인 느낌? 정형 데이터보다 더 더욱 재밌었습니다. 오늘은 비정형 데이터 중 MNIST 이미지 데이터를 다룹니다.
CNN은 제가 이 책으로만은 이해도나 궁금증이 해결되지 않아서 구글링을 하면서 공부한 것을 따로 포스팅 했습니다.
이 포스팅에서는 실습을 위주로 다루겠습니다.
https://inhovation97.tistory.com/15
<이미지 데이터 전처리/시각화>
from keras.datasets import mnist
from keras.utils import np_utils
import numpy as np
import pandas as pd
import sys
import tensorflow as tf
# seed값 설정
seed=0
np.random.seed(seed)
tf.random.set_seed(3)
# MNIST 데이터셋 불러오기
(X_train, Y_class_train),(X_test, Y_class_test) = mnist.load_data()
print('학습셋 이미지 수 : %d 개' % (X_train.shape[0]))
print('테스트셋 이미지 수 : %d 개' % (X_test.shape[0]))
# 그래프로 확인
import matplotlib.pyplot as plt
plt.imshow(X_train[0], cmap='Greys')
plt.show()
## 코드로 확인
for x in X_train[0]:
for i in x:
sys.stdout.write('%d\t' % i) # 1행에 28개 그 다음은 \n으로 다음행으로 넘어감
sys.stdout.write('\n')
# 차원 변환 과정
X_train = X_train.reshape(X_train.shape[0], 784) # 60000행, 28*28열로 재배치
X_train = X_train.astype('float64')
X_train = X_train / 255
# 클래스 값 확인
print('class : %d' % (Y_class_train[0]))
# 바이너리화 과정
Y_train = np_utils.to_categorical(Y_class_train, 10)
Y_test = np_utils.to_categorical(Y_class_test, 10)
print(Y_train[0])
이미지 데이터는 이렇게 픽셀들을 명암의 숫자로 전처리하여 입력 데이터로 만들어 줍니다.
<다층 퍼셉트론으로 학습한 딥러닝 기본 프레임>
from keras.datasets import mnist
from keras.utils import np_utils
from keras.models import Sequential
from keras.layers import Dense
from keras.callbacks import ModelCheckpoint, EarlyStopping
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import os
import tensorflow as tf
# seed 값 설정
seed=0
np.random.seed(seed)
tf.random.set_seed(3) # 버전 달라서 random.set_seed로 코딩해야함
# mnist 데이터 불러오기
(X_train, Y_train),(X_test,Y_test) = mnist.load_data()
X_train = X_train.reshape(X_train.shape[0],784).astype('float32')/255 #float64보다 숫자의 범위는 작지만 메모리가 적게듦
X_test = X_test.reshape(X_test.shape[0],784).astype('float32')/255
Y_train = np_utils.to_categorical(Y_train, 10)
Y_test = np_utils.to_categorical(Y_test, 10)
# 모델 프레임 설정
model = Sequential()
model.add(Dense(512, input_dim=784, activation='relu'))
model.add(Dense(10, activation='softmax'))
# 모델 실행 환결 설정
model.compile(loss='categorical_crossentropy',
optimizer='adam',
metrics=['accuracy'])
# 모델 최적화 설정
MODEL_DIR = './model2/'
if not os.path.exists(MODEL_DIR):
os.mkdir(MODEL_DIR)
modelpath = './model2/{epoch:02d}-{val_loss:.4f}.hdf5'
checkpointer = ModelCheckpoint(filepath=modelpath, monitor='val_loss', verbose=1, save_best_only=True)
early_stopping_callback = EarlyStopping(monitor='val_loss',patience=10)
# 모델의 실행
history = model.fit(X_train, Y_train, validation_data = (X_test, Y_test), epochs=30, batch_size=200, verbose=0, callbacks=[early_stopping_callback, checkpointer])
# 테스트 정확도 출력
print('\n Test Accuracy: %.4f' % (model.evaluate(X_test,Y_test)[1]))
학습이 23번째에서 멈추고 최종적인 정확도는 0.9833이 나왔습니다.
이제 train과 test 데이터의 오차를 그래프로 비교해보겠습니다.
# 테스트셋의 오차
y_vloss=history.history['val_loss']
# 학습셋의 오차
y_loss = history.history['loss']
# 그래프로 표현
x_len = np.arange(len(y_loss))
plt.figure(figsize=(15, 10)) # 크기 지정
plt.plot(x_len, y_vloss, marker='.',c='red', label='Testset_loss')
plt.plot(x_len, y_loss, marker='.',c='blue', label='Trainset_loss' )
# 그래프에 그리드를 주고 레이블을 표시
plt.legend(loc='upper right')
# plt.axis([0,20,0,0.35])
plt.grid()
plt.xlabel('epoch')
plt.ylabel('loss')
plt.figure(figsize=(15, 10)) # 크기 지정
plt.show()
test셋의 오차가 10번의 반복에도 오차가 개선되지 않아서 학습을 그만두는 것을 알 수 있습니다.
<CNN(Convolution Neural Network)으로 학습시키기>
# CNN 설계하기
from keras.datasets import mnist
from keras.utils import np_utils
from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten, Conv2D, MaxPooling2D
from keras.callbacks import ModelCheckpoint, EarlyStopping
import matplotlib.pyplot as plt
import numpy as np
import os
import tensorflow as tf
# seed값 설정
seed=0
np.random.seed(seed)
tf.random.set_seed(3)
# 데이터 불러오기
(X_train, Y_train),(X_test, Y_test) = mnist.load_data()
X_train = X_train.reshape(X_train.shape[0], 28, 28,1).astype('float32') / 255
X_test = X_test.reshape(X_test.shape[0], 28, 28,1).astype('float32') / 255
Y_train = np_utils.to_categorical(Y_train)
Y_test = np_utils.to_categorical(Y_test)
# 컨볼루션 신경망 설정
model = Sequential()
model.add(Conv2D(32, (3,3), input_shape=(28,28,1), activation='relu'))
model.add(Conv2D(64, (3,3),activation='relu'))
model.add(MaxPooling2D(pool_size=2))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(10, activation='softmax'))
model.compile(loss = 'categorical_crossentropy',
optimizer='adam',
metrics=['accuracy'])
# 모델 최적화 설정
CNNMODEL_DIR = './CNNmodel/'
if not os.path.exists(CNNMODEL_DIR):
os.mkdir(CNNMODEL_DIR)
modelpath='./CNNmodel/{epoch:02d}-{val_loss:.4f}.hdf5'
checkpointer = ModelCheckpoint(filepath=modelpath, monitor='val_loss', verbose=1, save_best_only=True)
early_stopping_callback = EarlyStopping(monitor='val_loss',patience=10)
# 모델의 실행
history= model.fit(X_train,Y_train, validation_data=(X_test,Y_test),epochs=30, verbose=0, batch_size=200, callbacks=[early_stopping_callback, checkpointer])
# 테스트 정확도 출력
print('\n Test Accuray: %.4f' % (model.evaluate(X_test,Y_test)[1]))
# 테스트셋의 오차
y_vloss = history.history['val_loss']
#학습셋의 오차
y_loss = history.history['loss']
# 그래프로 표현
x_len = np.arange(len(y_loss))
plt.plot(x_len, y_vloss, marker='.', c='red', label='Testset_loss')
plt.plot(x_len, y_loss, marker='.', c='blue', label='Trainset_loss')
# 그래프에 그리드를 주고 레이블을 표시
plt.legend(loc = 'upper right')
plt.grid()
plt.xlabel('epoch')
plt.ylabel('loss')
plt.show()
모델을 설계하는 부분을 봅시다. 원래의 입력층 앞에 컨볼루션층과 맥스풀링층을 추가하고 드롭아웃으로 과적합을 방지해주는 것을 알 수 있습니다.
컨볼루션 층1(32개의 필터) -> 컨볼루션 층2(64개의 필터) -> 맥스풀링 -> 드롭아웃(25%) -> 플래튼(데이터 1차원화) -> FC층(중간에 드롭아웃25%) -> 레이블 출력(소프트 맥스)
CNN모델은 정확도가 0.9937으로 엄청나게 향상함을 알 수 있습니다. 책에서는 이미지 데이터 중에서도 숫자가 아닌 이상한 이미지들 때문에 100%를 기록하지 못했다고 합니다. 학습 시간은 CPU를 이용했는데 데이터가 가벼워서 그런지 엄청 오래걸리지는 않았습니다.
'데이터 과학 관련 스터디 > 모두의 딥러닝' 카테고리의 다른 글
[모두의 딥러닝] 15장 선형 회귀 적용하기 (0) | 2020.07.24 |
---|---|
[모두의 딥러닝] 14장 베스트 모델 만들기 (0) | 2020.07.23 |
[모두의 딥러닝] 13장 과적합 피하기 (0) | 2020.07.14 |
[모두의 딥러닝] 12장 다중 분류 문제 해결하기 (0) | 2020.07.12 |
[모두의 딥러닝] 11장 데이터 다루기 (0) | 2020.07.11 |
댓글