간단 정리
이진분류 | 다중분류 | 회귀 | |
---|---|---|---|
학습(loss) | binary_crossentropy | categorical_crossentropy | mse |
성능(metrics) | accuracy, recall | accuracy, recall | mae, r_square |
출력층 개수 | 1개 | n개 | 1개 |
출력층 활성화함수 | sigmoid | softmax | 사용하지 않음 |
라이브러리 불러오기
import tensorflow as tf
from tensorflow.keras.datasets import mnist
from tensorflow.keras.utils import to_categorical
from sklearn.model_selection import train_test_split
from tensorflow.keras import models, layers, regularizers
유틸 함수 추가하기
import pandas as pd
import numpy as np
def get_dataframe(model, history, loss, metrics, batch_size):
layer_info = []
layer_info.append({"key": "params", "value": np.sum([np.prod(v.shape) for v in model.trainable_variables])})
layer_info.append({"key": "loss", "value": model.loss.__name__ if callable(model.loss) else model.loss})
layer_info.append({"key": "metrics", "value": model.metrics_names[1]})
layer_info.append({"key": "optimizer", "value": model.optimizer.get_config()["name"]})
for i in range(len(model.layers)):
layer = model.layers[i]
config = layer.get_config()
units = config["units"] if "units" in config else None
activation = config["activation"] if "activation" in config else None
regularizers = ("%.5f" % config["kernel_regularizer"]["config"]["l2"] if config["kernel_regularizer"] != None else None) if "kernel_regularizer" in config else None
rate = config["rate"] if "rate" in config else None
pool_size = config["pool_size"] if "pool_size" in config else None
filters = config["filters"] if "filters" in config else None
kernel_size = config["kernel_size"] if "kernel_size" in config else None
layer_info.append({
"key": "layer%d" % i,
"value": type(layer).__name__,
"units": units or rate or filters,
"activation": activation,
"l2": regularizers or kernel_size or pool_size,
})
metric_name = model.metrics_names[1]
layer_info.append({"key": "epochs", "value": history.params['epochs']})
layer_info.append({"key": "batch_size", "value": batch_size})
layer_info.append({"key": "r_loss", "value": round(loss, 4)})
layer_info.append({"key": "r_%s" % metric_name, "value": round(metrics, 4)})
df_layer = pd.DataFrame(layer_info).fillna("")
return df_layer
import matplotlib.pyplot as plt
from datetime import datetime
import os
def save_result(model, history, loss, metrics, batch_size=None):
epochs = range(1, len(history.history['loss']) + 1)
plt.figure(figsize=(25, 6))
plt.subplot(1, 3, 1)
df_layer = get_dataframe(model, history, loss, metrics, batch_size)
bbox=[0, 0, 1, 1]
mpl_table = plt.table(cellText = df_layer.values, bbox=bbox, colLabels=df_layer.keys(), colWidths=[0.3, 0.6, 0.2, 0.2, 0.2])
mpl_table.auto_set_font_size(False)
mpl_table.set_fontsize(12)
table_cells = mpl_table.get_children()
for index in range(len(table_cells)):
cell = table_cells[index]
cell.set_linewidth(0.2)
cell.set_edgecolor('darkgray')
if index == 1:
cell_text = cell.get_text()
cell_text.set_weight('bold')
if (index == len(table_cells) - 14) | (index == len(table_cells) - 9):
cell_text = cell.get_text()
cell_text.set_weight('bold')
cell_text.set_color('red')
elif (index >= 20) & (index < len(table_cells) - 25):
cell.set_facecolor('whitesmoke')
elif index >= len(table_cells) -5:
cell.set_facecolor("steelblue")
cell.get_text().set_color('white')
plt.axis('off')
ax = plt.subplot(1, 3, 2)
plt.plot(epochs, history.history['loss'], 'b--')
plt.plot(epochs, history.history['val_loss'], 'r--')
plt.title('Trainig & Validation Loss')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend(['Training Loss', 'Validation Loss'])
plt.grid()
ax = plt.subplot(1, 3, 3)
metric_name = model.metrics_names[1]
plt.plot(epochs, history.history[metric_name], 'b--')
plt.plot(epochs, history.history['val_%s' % metric_name], 'r--')
plt.title('Training & Validation %s' % metric_name)
plt.xlabel('Epochs')
plt.ylabel(metric_name)
plt.legend(['Trainig %s' % metric_name, 'Validation %s' % metric_name])
plt.grid()
folder_name = "plots"
if os.path.exists(folder_name) == False:
os.mkdir(folder_name)
plt.savefig(folder_name + '/%s_%.4f.png' % (datetime.now().strftime("%Y%m%d_%H%M%S"), metrics), bbox_inches='tight', pad_inches=0.2)
plt.show()
데이터 불러오기
(X_train, y_train), (X_test, y_test) = mnist.load_data()
X_train = X_train.astype(float) / 255
X_test = X_test.astype(float) / 255
X_train = X_train.reshape(60000, 28 * 28)
X_test = X_test.reshape(10000, 28 * 28)
y_train = to_categorical(y_train)
y_test = to_categorical(y_test)
print("Train Shape:", X_train.shape, y_train.shape)
print("Test Shape:", X_test.shape, y_test.shape)
Train, Validation 분리하기
X_train, X_valid, y_train, y_valid = train_test_split(X_train, y_train, test_size=0.2, random_state=2045)
모델링 작업하기
tf.keras.backend.clear_session()
tf.config.experimental.enable_op_determinism()
tf.keras.utils.set_random_seed(2045)
model = models.Sequential()
l2 = regularizers.l2(0.0001)
model.add(layers.Dense(512, kernel_regularizer=l2, input_shape=(28 * 28, )))
model.add(layers.BatchNormalization())
model.add(layers.Activation('relu'))
model.add(layers.Dropout(0.5))
model.add(layers.Dense(256, kernel_regularizer=l2))
model.add(layers.BatchNormalization())
model.add(layers.Activation('relu'))
model.add(layers.Dropout(0.3))
model.add(layers.Dense(10, activation='softmax'))
model.summary()
학습 진행하기
model.compile(loss='categorical_crossentropy', optimizer='rmsprop', metrics=['accuracy'])
%%time
batch_size = 128
history = model.fit(X_train, y_train, epochs=10, batch_size=batch_size, validation_data=(X_valid, y_valid))
학습 결과 평가하기
loss, accuracy = model.evaluate(X_test, y_test)
print("loss: %.5f" % loss)
print("accuracy: %.5f" % accuracy)
그래프로 시각화하기
save_result(model, history, loss, accuracy, batch_size)