텐서플로우
tensorflow, keras 를 이용한 Fashion Mnist 모델
Coding J
2021. 10. 4. 10:35
#본 모델은 코랩을 이용하여 제작하였습니다.
## Fashion MNIST 모델
<img src="https://www.tensorflow.org/tutorials/keras/classification_files/output_oZTImqg_CaW1_0.png?hl=ko" width="500">
### 모듈 임포트
import tensorflow as tf
from tensorflow.keras.datasets.fashion_mnist import load_data #케라스 mnist 데이터의 로드데이터사용
from tensorflow.keras.models import Sequential, Model #모델데이터에서 시퀀셜이랑 모델 임폴트
from tensorflow.keras import models #임폴트 모델스
from tensorflow.keras. layers import Dense, Input #레이어는 덴스와 인풋
from tensorflow.keras.optimizers import Adam #옵티마이저는 아담
from tensorflow.keras.utils import plot_model #유틸은 플롯 모델 임폴트
from sklearn.model_selection import train_test_split #모델 셀렉션에 트레인테스트스플릿 사용
import numpy as np #넘파이 사용
import matplotlib.pyplot as plt #매트플롯 파이플롯 as plt 사용
plt.style.use('seaborn-white') #스타일 지정
### 데이터 로드
tf.random.set_seed(111) #랜덤 셋 시드 111로 정의
(x_train_full, y_train_full), (x_test, y_test) = load_data() # 각 트레인 풀 값과 테스트 값 validation 만들기 위해 full로 이름 저장 fload_data에서 가져옴
x_train, x_val, y_train, y_val = train_test_split(x_train_full, y_train_full, # val 나눠주고 test_split 함수를 통해 각 full에서
test_size=0.3, #test_size, 즉 validation 을 30퍼센트를 확보 랜덤스테이트=111
random_state=111)
print("학습데이터 : {}\t레이블: {}".format(x_train_full.shape, y_train_full.shape)) #전체 학습데이터수
print("학습데이터 : {}\t레이블: {}".format(x_train.shape, y_train.shape)) #x트레인을 보여주는것
print("검증데이터 : {}\t레이블: {}".format(x_val.shape, y_val.shape)) #x val보여주는 것
print("테스트 데이터 : {}\t레이블: {}".format(x_test.shape, y_test.shape)) #test 보여주는 것
class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat',
'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankie boot']
class_names[y_train[0]] #y트레인 0번째를 찾는 법 ( y트레인 0의 값은 2)
plt.figure() #직접 이미지로 보여주기 컬러바 띄우고
plt.imshow(x_train[0])
plt.colorbar()
plt.grid(False) #grid는 이미지를 보여줘야 하기 때문에 false로
plt.show()
num_sample=4 #4개를 띄우기 위해 샘플정의
random_idxs = np.random.randint(60000, size=num_sample) # 랜덤인덱스를 60000개를 랜덤으로 잡고 nom_sample크기만큼
plt.figure(figsize=(15,10)) #fig사이즈를 지정하고 enumerate를 랜덤인덱스로 지정
for i, idx in enumerate(random_idxs):
image=x_train_full[idx, :] #첫 인덱스(값)에서 이미지를 가져오기
label=y_train_full[idx] #레이블도 y인덱스에서 가져오기
plt.subplot(1, len(random_idxs), #i+1) 총 4개를 표현하기위해 len정하기
plt.imshow(image) #이미지쇼도 표현
plt.title('index: {}, label: {}' .format(idx, class_names[label])) #인덱스값과 레이블 값 표시
### 데이터 전처리
- Normalization
- Flatten
- loss='sparse_categorical_crossentropy'
x_train = (x_train.reshape(-1, 28*28))/255. #nomallzation을 하기위해 reshape(255로 나눔) 28*28이 flatten
x_val = (x_val.reshape(-1, 28*28))/255.
x_test = (x_test.reshape(-1, 28*28))/255.
### 모델 구성 (함수형 API)
input = Input(shape=(784,), name= 'input') #28*28사용 인풋만들기
hidden1 = Dense(512, activation='relu', name='hidden1')(input) #hidden dense크게만들고 점차 줄여가듯이 하나씩 내려갈떄마다 반씩줄이기
hidden2 = Dense(256, activation='relu', name='hidden2')(hidden1)
hidden3 = Dense(128, activation='relu', name='hidden3')(hidden2)
hidden4 = Dense(64, activation='relu', name='hidden4')(hidden3)
hidden5 = Dense(32, activation='relu', name='hidden5')(hidden4)
output = Dense(10, activation='softmax', name='output')(hidden5) #최종결과는 10개 , 소프트맥스로 엑티베이션 각각 위의 것들을 참조
model = Model(inputs=[input], outputs=output) #모델 만들기 input은 input넣고 out에 outpup
model.summary() #보여주기
plot_model(model) #plot모델로 보여주기(시퀀셜)
### 모델 컴파일 및 학습
model.compile(loss='sparse_categorical_crossentropy', # 로스는 스펄스 카테고리컬 크로스엔트로피 사용
optimizer=Adam(learning_rate=0.01), #옵티마이저는 아담, 러닝레이트는 디폴트 0.01로설정
metrics=['acc']) #매트릭스에 acc
history = model.fit(x_train, y_train, #히스토리로 model.fit 각 트레인과 에폭스 배치사이즈, validation_data 설정
epochs=40,
batch_size=512,
validation_data=(x_val,y_val))
history.history.keys() #히스토리 키
history_dict = history.history #모델 시각화하는 코드
loss = history_dict['loss']
val_loss = history_dict['val_loss']
epochs=range(1, len(loss) + 1)
fig= plt.figure(figsize=(12,5))
ax1 = fig.add_subplot(1,2,1)
ax1.plot(epochs, loss, color = 'blue', label='train_loss')
ax1.plot(epochs, val_loss, color = 'red', label='val_loss')
ax1.set_title('Train and Validation Loss')
ax1.set_xlabel('Epochs')
ax1.set_ylabel('Loss')
ax1.grid()
ax1.legend()
accuracy= history_dict['acc']
val_accuracy=history_dict['val_acc']
ax2 = fig.add_subplot(1,2,2)
ax2.plot(epochs, accuracy, color = 'blue', label='train_accuracy')
ax2.plot(epochs, val_accuracy, color = 'red', label='val_accuracy')
ax2.set_title('Train and Validation Loss')
ax2.set_xlabel('Epochs')
ax2.set_ylabel('Loss')
ax2.grid()
ax2.legend()
plt.show()
### 모델 평가 및 예측
model.evaluate(x_test, y_test) #실제로 평가
pred_ys= model.predict(x_test) #프리딕트
print(pred_ys.shape)
np.set_printoptions(precision=7)
print(pred_ys[0])
arg_pred_y = np.argmax(pred_ys, axis=1) #프레딕트 클래스에 이름이 맞는지 확인
plt.imshow(x_test[0].reshape(-1,28))
plt.title('Predicted class: {}'.format(class_names[arg_pred_y[0]]))
plt.show()
def plot_image(i,pred_ys,y_test, img):
pred_ys, y_test, img=pred_ys[i], y_test[i], img[i]
plt.grid(False) #이미지기 떄문에 false
plt.xticks([]) #xticks와 ytick스 없애기
plt.yticks([])
plt.imshow(img, cmap= plt.cm.binary) #이미지 쇼 컬러맵= 바이너리형태
predicted_label = np.argmax(pred_ys) #argmax(최대값)으로 레이블가져옴
if predicted_label == y_test: #예측값과 테스트값이 같을 경우 블루 다를경우 레드
color = 'blue'
else:
color = 'red'
plt.xlabel("{} {:2.0f}% ({}".format(class_names[predicted_label], #앞두자리 소숫점 첫재까지, 실제 예측숫자를 클래스이름으로,퍼센테이지 값으로환산
100*np.max(pred_ys), #실제 ytest 값을 클래스네임으로, color은color으로
class_names[y_test]),color=color)
def plot_value_array(i,pred_ys, true_label):
pred_ys, true_label = pred_ys[i], true_label[i] #i번쨰 값을 가져오기
plt.grid(False)
plt.xticks([])
plt.yticks([])
thisplot = plt.bar(range(10), pred_ys, color='#777777') #range 10, 색깔지정
plt.ylim([0,1]) #ylim을 0~1까지
predicted_label = np.argmax(pred_ys) #프리딕티드 레이블 값을 argmax 값으로 (pred_ys)
thisplot[predicted_label].set_color('red') #예측값은 레드 진짜값은 블루
thisplot[true_label].set_color('blue')
i=0
plt.figure(figsize=(8,4)) #피규어 8,4
plt.subplot(1,2,1)
plot_image(i,pred_ys, y_test, x_test.reshape(-1, 28, 28)) #reshape해주기(이미지모양으로 만들기)
plt.subplot(1,2,2)
plot_value_array(i,pred_ys, y_test) # 얼만큼 확률로 맞췄는지 바로
plt.show()
i=40 #똑같이 40번째 값
plt.figure(figsize=(8,4))
plt.subplot(1,2,1)
plot_image(i,pred_ys, y_test, x_test.reshape(-1, 28, 28))
plt.subplot(1,2,2)
plot_value_array(i,pred_ys, y_test)
plt.show()
num_rows = 10 #10*3 행렬 갯수만들기
num_cols = 3
num_images = num_rows * num_cols
random_num = np.random.randint(10000, size=num_images)
plt.figure(figsize=(2*2*num_cols,2*num_rows))
for idx, num in enumerate(random_num): #enumerate의 랜덤갯수만큼 반복
plt.subplot(num_rows, 2*num_cols, 2* idx+1)
plot_image(num, pred_ys, y_test, x_test.reshape(-1,28,28)) #plot이미지 넣음 (reshape까지)
plt.subplot(num_rows,2*num_cols,2*idx+2)
plot_value_array(num, pred_ys, y_test) #바형태로 보여주게
plt.show()
- 혼동 행렬 (Confusion Matrix)
from tensorflow.keras.utils import to_categorical #케라스의 유틸에서 카테고리컬 임폴트
y_test_che = to_categorical(y_test) #y_Test값을 카테고리로 바꿈
y_test_che.shape
from sklearn.metrics import classification_report, confusion_matrix #혼동행렬 만들어주기
import seaborn as sns
sns.set(style='white')
plt.figure(figsize=(8,8))
cm = confusion_matrix(np.argmax(y_test_che, axis=-1), np.argmax(pred_ys, axis=-1))
sns.heatmap(cm, annot=True, fmt='d', cmap='Blues')
plt.xlabel('Predicted Label')
plt.ylabel('True Label')
plt.show()
- 분류 보고서
print(classification_report(np.argmax(y_test_che, axis=-1),np.argmax(pred_ys,axis=-1))) #마지막 분류보고서까지.