간단 정리
ㅤ | 이진분류 | 다중분류 | 회귀 |
학습(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)