인공지능/RNN

Callback ( check_point와 Earlystopping)

쿠와와 2020. 12. 15. 22:59
# Day_32_02_callback.py
import tensorflow as tf
import pandas as pd
import numpy as np
from sklearn import preprocessing, model_selection


# 자동차 데이터에 대해 80%로 학습하고 20%에 대해 정확도를 구하세요 checkpoint 쓸꺼임
# dense : LabelBinarizer : 피처의 개수가 훨씬 많아짐
# sparse: LableEncoder   : 그냥 변환
def get_cars_sparse():
    names = ['buying', 'maint', 'doors', 'persons', 'lug_boot', 'safety', 'acc']
    cars = pd.read_csv('data/car.data', header=None, names=names)

    # 피처의 개수 6개
    enc = preprocessing.LabelEncoder()

    buying = enc.fit_transform(cars.buying)
    maint = enc.fit_transform(cars.maint)
    doors = enc.fit_transform(cars.doors)
    persons = enc.fit_transform(cars.persons)
    lug_boot = enc.fit_transform(cars.lug_boot)
    safety = enc.fit_transform(cars.safety)
    acc = enc.fit_transform(cars.acc)
    # print(buying.shape, maint.shape)      # (1728,) (1728,)

    data = np.transpose([buying, maint, doors, persons, lug_boot, safety, acc])
    # print(data.shape)                     # (1728, 7)

    # ---------------------------------------------- #

    train_size = int(len(data) * 0.8)

    ds_train = tf.data.Dataset.from_tensor_slices(data[:train_size])
    ds_train = ds_train.map(lambda chunk: (chunk[:-1], chunk[-1]))
    ds_train = ds_train.batch(32, drop_remainder=True)

    ds_test = tf.data.Dataset.from_tensor_slices(data[train_size:])
    ds_test = ds_test.map(lambda chunk: (chunk[:-1], chunk[-1]))
    ds_test = ds_test.batch(32, drop_remainder=True)

    return ds_train, ds_test


# 이전 파일에서 가져온 함수
def build_model(n_classes):
    model = tf.keras.Sequential()
    model.add(tf.keras.layers.Dense(60, activation='relu'))
    model.add(tf.keras.layers.Dense(n_classes, activation='softmax'))

    model.compile(optimizer='adam',
                  loss=tf.keras.losses.sparse_categorical_crossentropy,
                  metrics=['acc'])
    return model


ds_train, ds_test = get_cars_sparse()
model = build_model(4)

# checkpoint 의 의미는 가장 좋은 모델을 선택하는 것에 있음
# checkpoint = tf.keras.callbacks.ModelCheckpoint('model_callback/first.h5')
# 이 밑의 코드 중요함
# checkpoint = tf.keras.callbacks.ModelCheckpoint(
#     'model_callback/keras_{epoch:03d}'      # 0으로 체워지는 숫자 3개 씀
#     '_val_loss{val_loss:.4f}.h5')           # 소수점 4개까지 쓸 것임

# 가장 좋은 모델만 저장함
checkpoint = tf.keras.callbacks.ModelCheckpoint(
    'model_callback/keras_val_acc_{epoch:03d}'      # 0으로 체워지는 숫자 3개 씀
    '_{val_acc:.4f}.h5',           # 소수점 4개까지 쓸 것임
    monitor='val_acc',
    save_best_only=True)

# 오버피팅 나오는 부분을 캐치해서 멈춰줌
early_stoppin = tf.keras.callbacks.EarlyStopping(
    monitor='val_acc',
    patience=10,     # val_acc 안좋아지기 시작하기 3번째 정도에서 멈춤
)

model.fit(ds_train, epochs=30, verbose=2,
          validation_data=ds_test,
          callbacks=[checkpoint, early_stoppin])        # 이런식으로 사용함
print('acc :', model.evaluate(ds_test))