import keras
from keras import layers
def get_mnist_model():
inputs = keras.Input(shape=(28*28,))
features = layers.Dense(512, activation='relu')(inputs)
features = layers.Dropout(0.5)(features)
outputs = layers.Dense(10, activation='softmax')(features)
model = keras.Model(inputs,outputs)
return model
🔸 사용자 지표 함수 생성 코드: RMSE 계산
import tensorflow as tf
class RootMeanSquaredError(keras.metrics.Metric):
def __init__(self, name='rmse',**kwargs):
super().__init__(name=name, **kwargs)
self.mse_sum = self.add_weight(name='mse_sum', initializer='zeros')
self.total_samples = self.add_weight(name='total_sample', initializer='zeros', dtype='int32')
def update_state(self, y_true, y_pred, sample_weight=None):
y_true = tf.one_hot(y_true, depth=tf.shape(y_pred)[1])
mse=tf.reduce_sum(tf.square(y_true - y_pred))
self.mse_sum.assign_add(mse)
num_samples = tf.shape(y_pred)[0]
self.total_samples.assign_add(num_samples)
def result(self):
return tf.sqrt(self.mse_sum / tf.cast(self.total_samples, tf.float32))
def reset_state(self):
self.mse_sum.assign(0.)
self.total_samples.assign(0)
__init__()
: add_weight
: 상태변수정의update_state()
:result()
:tf.cast
: total_samples를 float32타입으로 변형시켜줌reset_state()
:🔸 지표 테스트
from keras.datasets import mnist
(images, labels), (test_images, test_labels) = mnist.load_data()
images = images.reshape((60000, 28 * 28)).astype("float32") / 255
test_images = test_images.reshape((10000, 28 * 28)).astype("float32") / 255
train_images, val_images = images[10000:], images[:10000]
train_labels, val_labels = labels[10000:], labels[:10000]
model = get_mnist_model()
model.compile(optimizer="rmsprop",
loss="sparse_categorical_crossentropy",
metrics=["accuracy", RootMeanSquaredError()])
model.fit(train_images, train_labels,
epochs=3,
validation_data=(val_images, val_labels))
test_metrics = model.evaluate(test_images, test_labels)
🔸 사용가능한 콜백: keras.callbacks.
ModelCheckpoint
BackupAndRestore
TensorBoard
EarlyStopping
LearningRateScheduler
ReduceLROnPlateau
RemoteMonitor
LambdaCallback
TerminateOnNaN
CSVLogger
ProgbarLogger
🔸 콜백리스트 작성
callbacks_list = [keras.callbacks.EarlyStopping(monitor="val_accuracy",
patience=2,),
keras.callbacks.ModelCheckpoint(filepath="checkpoint_path.keras",
monitor="val_loss",
save_best_only=True,)]
monitor="val_accuracy"
: 모델의 검증 정확도를 모니터링patience
: n번의 에포크동안 정확도가 향상되지 않으면 훈련 중지filepath
: 모델 파일의 저장 경로monitor="val_loss"
: 손실값이 좋아지지 않으면 모델파일을 덮어쓰지 않음. save_best_only=True
훈련하는 동안 가장 좋은 모델 저장🔸 fit()에 적용
(images, labels), (test_images, test_labels) = mnist.load_data()
images = images.reshape((60000, 28 * 28)).astype("float32") / 255
test_images = test_images.reshape((10000, 28 * 28)).astype("float32") / 255
train_images, val_images = images[10000:], images[:10000]
train_labels, val_labels = labels[10000:], labels[:10000]
model = get_mnist_model()
model.compile(optimizer="rmsprop",
loss="sparse_categorical_crossentropy",
metrics=["accuracy"])
model.fit(train_images, train_labels,
epochs=10,
callbacks=callbacks_list,
validation_data=(val_images, val_labels))
🔸 저장된 모델 호출
model = keras.models.load_model('checkpoint_path.keras')
훈련도중 내장콜백에서 제공하지 않는 특정행동을 만들 수 있다.
keras.callbacks.Callback클래스를 상속
🔸 사용자 정의 콜백 함수 생성
from matplotlib import pyplot as plt
class LossHistory(keras.callbacks.Callback):
def on_train_begin(self, logs):
self.per_batch_losses = []
def on_batch_end(self, batch, logs):
self.per_batch_losses.append(logs.get("loss"))
def on_epoch_end(self, epoch, logs):
plt.clf()
plt.plot(range(len(self.per_batch_losses)), self.per_batch_losses,
label="Training loss for each batch")
plt.xlabel(f"Batch (epoch {epoch})")
plt.ylabel("Loss")
plt.legend()
plt.savefig(f"plot_at_epoch_{epoch}")
self.per_batch_losses = []
설명:
훈련이 시작되면 손실값 리스트를 만들고,
각 배치처리가 끝날때 손실값을 리스트에 저장하고,
각 에포그가 끝날때 그래프를 그리기
🔸 적용
(images, labels), (test_images, test_labels) = mnist.load_data()
images = images.reshape((60000, 28 * 28)).astype("float32") / 255
test_images = test_images.reshape((10000, 28 * 28)).astype("float32") / 255
train_images, val_images = images[10000:], images[:10000]
train_labels, val_labels = labels[10000:], labels[:10000]
model = get_mnist_model()
model.compile(optimizer="rmsprop",
loss="sparse_categorical_crossentropy",
metrics=["accuracy"])
model.fit(train_images, train_labels,
epochs=10,
callbacks=[LossHistory()],
validation_data=(val_images, val_labels))