# 문제 100.(점심시간 문제) 문제 99번의 코드의 dropout 비율을 20%가 아니라 10%만 뉴런을 삭제할 수 있게 하시오!
# 1. 필요한 패키지 가져오는 코드
import tensorflow as tf
# 텐써 플로우 2.0
from tensorflow.keras.datasets.mnist import load_data
# 텐써플로우에 내장되어있는 mnist 데이터를 가져온다.
from tensorflow.keras.models import Sequential
# 모델을 구성하기 위한 모듈
from tensorflow.keras.layers import Dense,Flatten,BatchNormalization,Dropout
# 완전 연결계층을 구성하기 위한 모듈
from tensorflow.keras.utils import to_categorical
# one encoding 하는 모듈
tf.random.set_seed(777)
(x_train, y_train), (x_test, y_test) = load_data(path='mnist.npz')
# mnist 데이터 로드
# 2. 정규화 진행
x_train = (x_train.reshape((60000, 28 * 28))) / 255
x_test = (x_test.reshape((10000, 28 * 28))) / 255
# 3. 정답 데이터를 준비한다.
# 하나의 숫자를 one hot encoding 한다. (예: 4 ---> 0 0 0 0 1 0 0 0 0 0 )
y_train = to_categorical(y_train) #훈련 데이터의 라벨(정답)을 원핫 인코딩
y_test = to_categorical(y_test) # 테스트 데이터의 라벨(정답)을 원핫 인코딩
# 4. 모델을 구성합니다.
model = Sequential()
model.add(Flatten(input_shape=(784, ) ) ) # 입력층(0층)
model.add(BatchNormalization() )
model.add(Dropout(0.1))
model.add(Dense( 100, activation='sigmoid')) # 은닉층(1층)
model.add(BatchNormalization() )
model.add(Dropout(0.1))
model.add(Dense( 50, activation='sigmoid')) # 은닉층(2층)
model.add(Dense( 10, activation='softmax') ) # 출력층(3층)
# 5. 모델을 설정합니다. ( 경사하강법, 오차함수를 정의해줍니다. )
model.compile(optimizer='RMSprop',
loss = 'categorical_crossentropy',
metrics=['acc']), # 학습과정에서 정확도를 보려고
#6. 모델을 훈련시킵니다.
history = model.fit(x_train, y_train,
epochs = 30, # 30에폭
batch_size = 100,
validation_data = (x_test,y_test))
# 7.모델을 평가합니다. (오차, 정확도가 출력됩니다.)
model.evaluate(x_test, y_test)
# 위의 코드들 밑에 바로 구현
train_acc_list = history.history['acc'] # 훈련 데이터의 정확도 30개
test_acc_list = history.history['val_acc'] # 테스트 데이터의 정확도 30개
print( train_acc_list )
print( test_acc_list )
# 시각화 까지 하세요 ~
import numpy as np
import matplotlib.pyplot as plt
x = np.arange( len(train_acc_list) ) # x축의 데이터를 구성(0~29)
plt.plot( x, train_acc_list, label='train acc') # 훈련데이터의 라인 그래프를 그립니다.
plt.plot( x, test_acc_list, label='test acc', linestyle='--') # 테스트 데이터의 라인 그래프를 그리는데 점선으로 그립니다.
plt.legend(loc='lower right')
plt.xlabel('epochs')
plt.ylabel('accuracy')
plt.show()