from keras.datasets import mnist
from keras.utils import np_utils
import numpy
import sys
import tensorflow as tf
seed = 0
numpy.random.seed(seed)
tf.random.set_seed(3)
(X_train, Y_train),(X_test, Y_test) = mnist.load_data()
print(X_train.shape[0]) #60000
print(X_test.shape[0] #10000
import matplotlib.pyplot as plt
plt.imshow(X_train[0], cmap='gray')
plt.show()
X_train = X_train.reshape(X_train.shape[0], 784)
X_train = X_train.astype('float64')
X_train = X_train/255
X_test = X_test.reshape(X_test.shape[0], 784).astype('float64')/255
print("class : %d " % (Y_train[0])) #Y 클래스(레이블값) 확인
#class : 5
Y_train = np_utils.to_categorical(Y_train, 10)
Y_test = np_utils.to_categorical(Y_test, 10)
print(Y_train[0])
# [0. 0. 0. 0. 0. 1. 0. 0. 0. 0.]
- mnist 데이터 : 케라스를 이용해서 부를 수 있음
- 미국 국립표준기술원(NIST)이 고등학생과 인구조사국 직원 등이 쓴 손글씨를 이용해 만든 데이터로 구성
- 70,000개의 글자 이미지에 각각 0부터 9까지 이름표를 붙인 데이터셋
- 총 70,000개의 이미지 중 60,000개를 학습용으로, 10,000개를 테스트용으로 미리 구분해 놓음
plt.imshow(X_train[0], cmap='gray')
: 이미지 출력
- 데이터
- 이미지 인식 방법
for x in X_train[0]:
for i in x:
sys.stdout.write('%d\t' % i)
sys.stdout.write('\n')
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 numpy
import sys
import tensorflow as tf
import os
# 모델 프레임 설정
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 = './model/'
if not os.path.exists(MODEL_DIR):
os.mkdir(MODEL_DIR)
modelpath = "./model/{epoch:02d}-{val_loss:.4f}.hdf5"
checkpoint = 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, checkpoint])
model.evaluate(X_test, Y_test)[1]
# 테스트셋의 오차
y_vloss = history.history['val_loss']
# 학습셋의 오차
y_loss = history.history['loss']
x_len = numpy.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()
model.add(Dense(512, input_dim=784, activation='relu'))
: 은닉층 512개, 입력값 784개, history = model.fit(X_train, Y_train, validation_data=(X_test, Y_test), epochs=30, batch_size=200, verbose=0, callbacks=[early_stopping_callback, checkpoint])
: 샘플 200개를 모두 30번 실행하게 설정.은닉층이 하나인 딥러닝 모델 도식
- 입력된 이미지에서 다시 한번 특징을 추출하기 위해 마스크(커널, 필터, 윈도)를 도입함
- 예시
⬆️ 입력된 이미지
⬆️ 마스크 : 각 칸에 가중치있음
⬆️ 마스크를 옮겨가면서 적용 : 적용된 부분은 원래 있던 값에 가중치를 곱하고 그 결과를 합산해서 새로운 값 도출⬇️
➡️ 컨볼루션(합성곱) : 새롭게 만들어진 층. 입력 데이터로부터 더욱 정교한 특징을 추출할 수 있음
여러개의 마스크 대입 시 여러개의 컨볼루션 만들 수 있음.
model.add(Conv2D(32, kernel_size=(3,3), input_shape=(28,28,1), activation='relu')
model.add(Conv2D(64, (3, 3), activation='relu')) #마스크 64개를 적용한 컨볼루션 층 추가
- 풀링(pooling)(=서브 샘플링(sub sampling)) : 컨볼루션 층으로부터 얻은 특징 결괏값이 여전히 크고 복잡하여 축소함
- 맥스 풀링(max pooling) : 정해진 구역안에서 최댓값을 뽑아냄
- 평균 풀링(average pooling) : 정해진 구역안에서 평균값을 뽑아냄
ex) 맥스 풀링 예시
- 이미지
- 맥스 풀링을 적용하여 구역을 나눔
- 각 구역에서 가장 큰 값 추출 : 불필요한 정보 간추림
model.add(MaxPooling2D(pool_size=2))
- 드롭아웃(dropout) : 은닉층에 배치된 노드 중 일부를 임의로 꺼줌 ➡️ 랜덤하게 노드를 끔으로써 학습 데이터에 지나치게 치우쳐서 학습되는 과적합 방지 가능
model.add(Dropout(0.25)) #25%의 노드 끔
- 플래튼(flatten) : 2차원 배열을 1차원 배열로 바꿔줌
- 컨볼루션 층, 맥스풀링 층 : 2차원 배열
- 입력층 : 1차원배열 필요(활성화 함수 적용 시 필요)
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
import os
import tensorflow as tf
# seed 값 설정
seed = 0
numpy.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, kernel_size=(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'])
# 모델 최적화 설정
MODEL_DIR = './model/'
if not os.path.exists(MODEL_DIR):
os.mkdir(MODEL_DIR)
modelpath="./model/{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]))
# 테스트셋의 오차
y_vloss = history.history['val_loss']
# 학습셋의 오차
y_loss = history.history['loss']
# 그래프로 표현
x_len = numpy.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()