0415 CNN_tensorflow2.x

wldnjswldnjs·2022년 5월 12일
0

딥러닝

목록 보기
5/10
post-custom-banner
import numpy as np
import pandas as pd
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Flatten, Dense
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Dropout
from tensorflow.keras.optimizers import Adam
from sklearn.preprocessing import MinMaxScaler
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt

# class 10개인 multinomial

# Raw Data Loading
df = pd.read_csv('/content/drive/MyDrive/colab/mnist/train.csv')
display(df.head())

1. 데이터 전처리

# 결측치, 이상치, 정규화, feature engineering

# 결측치, 이상치 X
# 정규화 필요

# train data와 test data 분리
# train data를 학습을 하기 위한 train data와 학습 검증을 위한 validation data로 분리
# 마지막 평가를 하기 위해 딱 1번 사용되는 test data
train_x_data, test_x_data, train_t_data, test_t_data = \
train_test_split(df.drop('label', axis=1, inplace=False),
                 df['label'],
                 test_size=0.3,
                 random_state=1,
                 stratify=df['label'])

scaler = MinMaxScaler()
scaler.fit(train_x_data)

norm_train_x_data = scaler.transform(train_x_data)
norm_test_x_data = scaler.transform(test_x_data)

2. model 구현

# keras 구현

model = Sequential()

# 입력 데이터의 channel의 개수와 같아서 channel 설정 X
# input layer가 있는데 생략해서 conv가 바로 받는 것처럼 표현
# input_shape() : 이미지 개수는 나중에 정해지는 값(None)이므로 정해주지 않는다.
model.add(Conv2D(filters=32,            # 1장에 32개의 feature map 생성
                 kernel_size=(3,3),
                 activation='relu',
                 input_shape=(28,28,1),
                 padding='valid',
                 strides=(1,1)))

# 일반적으로 stride는 pool_size와 동일하므로 설정 X
model.add(MaxPooling2D(pool_size=(2,2)))

# print(model.summary())

model.add(Conv2D(filters=64,            # 1장에 32x64 feature map 생성
                 kernel_size=(3,3),
                 activation='relu',
               # input_shape=(28,28,1), # conv2d와 pooling을 거쳐 들어오는 값이 있음
                 padding='valid',
                 strides=(1,1)))

model.add(MaxPooling2D(pool_size=(2,2)))

# print(model.summary())

model.add(Conv2D(filters=64,
                 kernel_size=(3,3),
                 activation='relu',
                 padding='valid',
                 strides=(1,1)))

# print(model.summary())

# 이미지 개수를 제외한 3차원을 1차원으로 변경 => 3 x 3 x 64 = 576
model.add(Flatten())                    # 이미지 개수 포함 4차원 => 2차원

# deep learning 으로 classification
# 형태는 유지하지만 연산에서 절반 제거
model.add(Dropout(rate=0.5))
model.add(Dense(units=256,              # 설정해주는 값
                activation='relu'))

model.add(Dense(units=10,
                activation='softmax'))  # 10개의 class당 확률값이 나옴

print(model.summary())

3. model 실행 옵션

# 어떤 optimizer를 사용하는가에 따라 learning_rate가 달라짐
# sparse : one-hot encoding 자동으로 진행
model.compile(optimizer=Adam(learning_rate=1e-3),
              loss='sparse_categorical_crossentropy', 
              metrics=['accuracy'])

4. model 학습

# norm_train_x_data이 학습 데이터의 일부를 validation data로 활용해서
# 학습이 진행될 때 (epoch마다) 평가 진행
# train data에 대한 loss, accuracy / valid data에 대한 loss, accuracy를
# (epoch마다) 출력하면서 평가 진행
history = model.fit(norm_train_x_data.reshape(-1,28,28,1), # 2차원 => 4차원 변경
                    train_t_data,
                    epochs=200,                            # 200번 돈다
                    batch_size=100,                        # 100씩 잘라서 계산
                    verbose=1,
                    validation_split=0.3)

5. History 객체

epoch마다 loss, accuracy, val_loss, val_accuracy가 저장되어 있다.

=> 그래프를 그릴 수 있다.

print(type(history)) # History 객체
# <class 'keras.callbacks.History'>

print(history.history.keys())    # print(변수이름, history객체.keys())
# dict_keys(['loss', 'accuracy', 'val_loss', 'val_accuracy'])

plt.plot(history.history['accuracy'], color='r')
plt.plot(history.history['val_accuracy'], color='b')
plt.show()

4.1 model 저장

# 이렇게 학습된 model 자체를 저장 가능
# 모델 구조 + 계산된 모든 weight, bias를 하나의 파일에 저장
# 확장자는 .h5 (HDF5) 형식

model.save('/content/drive/MyDrive/colab/mnist_model_save/my_mnist_model.h5')

model evaluation (평가)

model.evaluate(norm_test_x_data.reshape(-1,28,28,1), test_t_data)

# [0.11118786782026291, 0.9902380704879761]

저장된 model load 성능평가 진행

from tensorflow.keras.models import load_model

new_model = load_model('/content/drive/MyDrive/colab/mnist_model_save/my_mnist_model.h5')

# model 평가
new_model.evaluate(norm_test_x_data.reshape(-1,28,28,1), test_t_data)

# [0.11118786782026291, 0.9902380704879761]

4.2 checkpoint 저장 및 평가

# epoch이 돌 때마다 계산된 weight, bias 값을 저장
# model 학습 (ckpt, earlyStopping callback 포함)

from tensorflow.keras.callbacks import ModelCheckpoint, EarlyStopping

# checkpoint 설정
# epoch:04d : epoch수 => 4자리 숫자로 구성
checkpoint_path = '/content/drive/MyDrive/colab/mnist_model_save/cp-{epoch:04d}.ckpt'
cp_callback = ModelCheckpoint(checkpoint_path,
                              save_weights_only=True,
                              period=5,              # 5번 epoch이 돌 때마다 저장
                              verbose=1)

# earlyStopping
es = EarlyStopping(monitor='val_loss',
                   min_delta=0.001,     # 이만큼은 떨어져야 개선된 것으로 인식
                                        # 생략하면 값이 떨어지면 개선된 것으로 인식
                   patience=5,          # 5번동안 개선되지 않으면 문제있다.
                   verbose=1,
                   mode='auto',
                   restore_best_weights=True) # 자동으로 끝났을 때 최적의 값 복원

# norm_train_x_data이 학습 데이터의 일부를 validation data로 활용해서
# 학습이 진행될 때 (epoch마다) 평가를 같이 진행
# train data에 대한 loss, accuracy / valid data에 대한 loss, accuracy를 평가
history = model.fit(norm_train_x_data.reshape(-1,28,28,1), # 2차원 => 4차원 변경
                    train_t_data,
                    epochs=50,
                    batch_size=100,
                    verbose=1,
                    validation_split=0.3,
                    callbacks=[cp_callback, es])

문제가 있어서 멈춘 것인지 학습이 다 되어서 멈춘 것인지 확인해야 함

post-custom-banner

0개의 댓글