from tensorflow import keras
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt
import numpy as np

(train_input, train_target), (test_input, test_target) =\
    keras.datasets.fashion_mnist.load_data()
print(train_input.shape, train_target.shape)
print(test_input.shape, test_target.shape)

train_scaled = train_input / 255.0

train_scaled, val_scaled, train_target, val_target =\
    train_test_split(train_scaled, train_target, test_size=0.2, random_state=42)

def model_fn(a_layer=None):
    model = keras.Sequential()
    model.add(keras.layers.Flatten(input_shape=(28, 28)))
    model.add(keras.layers.Dense(100, activation='relu'))
    if a_layer:
        model.add(a_layer)
    model.add(keras.layers.Dense(10, activation='softmax'))
    return model

model = model_fn()
print(model.summary())

model.compile(loss='sparse_categorical_crossentropy', metrics='accuracy')
history = model.fit(train_scaled, train_target, epochs=20, verbose=0)
print(history.history.keys())

plt.plot(history.history['loss'])
plt.xlabel('epoch')
plt.ylabel('loss')
plt.show()

plt.plot(history.history['accuracy'])
plt.xlabel('epoch')
plt.ylabel('loss')
plt.show()

model = model_fn()
model.compile(loss='sparse_categorical_crossentropy', metrics='accuracy')
history = model.fit(train_scaled, train_target, epochs=20, verbose=0, validation_data=(val_scaled, val_target))
print(history.history.keys())

plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.xlabel('epoch')
plt.ylabel('loss')
plt.legend(['train', 'val'])
plt.show()

model = model_fn()
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics='accuracy')
history = model.fit(train_scaled, train_target, epochs=20, verbose=0, validation_data=(val_scaled, val_target))
print(history.history.keys())

plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.xlabel('epoch')
plt.ylabel('loss')
plt.legend(['train', 'val'])
plt.show()

model = model_fn(keras.layers.Dropout(0.3))
print(model.summary())

model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics='accuracy')
history = model.fit(train_scaled, train_target, epochs=20, verbose=0, validation_data=(val_scaled, val_target))

plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.xlabel('epoch')
plt.ylabel('loss')
plt.legend(['train', 'val'])
plt.show()

# 모델 저장과 복원
model = model_fn(keras.layers.Dropout(0.3))
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics='accuracy')
history = model.fit(train_scaled, train_target, epochs=10, verbose=0, validation_data=(val_scaled, val_target))

model.save_weights('model-weights.h5')

model.save('model-whole.h5')

model = model_fn(keras.layers.Dropout(0.3))
model.load_weights('model-weights.h5')

val_labels = np.argmax(model.predict(val_scaled), axis=-1)
print(np.mean(val_labels == val_target))

model = keras.models.load_model('model-whole.h5')
model.evaluate(val_scaled, val_target)

# 콜백
model = model_fn(keras.layers.Dropout(0.3))
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics='accuracy')
checkpoint_cb = keras.callbacks.ModelCheckpoint('best-model.h5', save_best_only=True)
model.fit(train_scaled, train_target, epochs=20, verbose=0, validation_data=(val_scaled, val_target), 
          callbacks=[checkpoint_cb])

model = keras.models.load_model('best-model.h5')
model.evaluate(val_scaled, val_target)

model = model_fn(keras.layers.Dropout(0.3))
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics='accuracy')
checkpoint_cb = keras.callbacks.ModelCheckpoint('best-model.h5', save_best_only=True)
model.fit(train_scaled, train_target, epochs=20, verbose=0, validation_data=(val_scaled, val_target), 
          callbacks=[checkpoint_cb])

model = keras.models.load_model('best-model.h5')
model.evaluate(val_scaled, val_target)

model = model_fn(keras.layers.Dropout(0.3))
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics='accuracy')
checkpoint_cb = keras.callbacks.ModelCheckpoint('best-model.h5', save_best_only=True)
early_stopping_cb = keras.callbacks.EarlyStopping(patience=2, restore_best_weights=True)
history = model.fit(train_scaled, train_target, epochs=20, verbose=0, validation_data=(val_scaled, val_target),
                    callbacks=[checkpoint_cb, early_stopping_cb])
print(early_stopping_cb.stopped_epoch)

plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.xlabel('epoch')
plt.ylabel('loss')
plt.legend(['train', 'val'])
plt.show()

model.evaluate(val_scaled, val_target)



matplotlib.pyplot.legend tensorflow.keras.datasets.fashion_mnist.load_data tensorflow.keras.models.load_model tensorflow.keras.callbacks.ModelCheckpoint tensorflow.keras.layers.Dropout tensorflow.keras.layers.Dense tensorflow.keras.Sequential sklearn.model_selection.train_test_split tensorflow.keras.callbacks.EarlyStopping matplotlib.pyplot.plot numpy.mean matplotlib.pyplot.xlabel matplotlib.pyplot.show tensorflow.keras.layers.Flatten matplotlib.pyplot.ylabel
[(7, 'tensorflow.keras.datasets.fashion_mnist.load_data', 'keras.datasets.fashion_mnist.load_data', ([], {}), False, 'from tensorflow import keras\n'), (14, 'sklearn.model_selection.train_test_split', 'train_test_split', (['train_scaled', 'train_target'], {'test_size': '(0.2)', 'random_state': '(42)'}), False, 'from sklearn.model_selection import train_test_split\n'), (32, 'matplotlib.pyplot.plot', 'plt.plot', (["history.history['loss']"], {}), True, 'import matplotlib.pyplot as plt\n'), (33, 'matplotlib.pyplot.xlabel', 'plt.xlabel', (['"""epoch"""'], {}), True, 'import matplotlib.pyplot as plt\n'), (34, 'matplotlib.pyplot.ylabel', 'plt.ylabel', (['"""loss"""'], {}), True, 'import matplotlib.pyplot as plt\n'), (35, 'matplotlib.pyplot.show', 'plt.show', ([], {}), True, 'import matplotlib.pyplot as plt\n'), (37, 'matplotlib.pyplot.plot', 'plt.plot', (["history.history['accuracy']"], {}), True, 'import matplotlib.pyplot as plt\n'), (38, 'matplotlib.pyplot.xlabel', 'plt.xlabel', (['"""epoch"""'], {}), True, 'import matplotlib.pyplot as plt\n'), (39, 'matplotlib.pyplot.ylabel', 'plt.ylabel', (['"""loss"""'], {}), True, 'import matplotlib.pyplot as plt\n'), (40, 'matplotlib.pyplot.show', 'plt.show', ([], {}), True, 'import matplotlib.pyplot as plt\n'), (47, 'matplotlib.pyplot.plot', 'plt.plot', (["history.history['loss']"], {}), True, 'import matplotlib.pyplot as plt\n'), (48, 'matplotlib.pyplot.plot', 'plt.plot', (["history.history['val_loss']"], {}), True, 'import matplotlib.pyplot as plt\n'), (49, 'matplotlib.pyplot.xlabel', 'plt.xlabel', (['"""epoch"""'], {}), True, 'import matplotlib.pyplot as plt\n'), (50, 'matplotlib.pyplot.ylabel', 'plt.ylabel', (['"""loss"""'], {}), True, 'import matplotlib.pyplot as plt\n'), (51, 'matplotlib.pyplot.legend', 'plt.legend', (["['train', 'val']"], {}), True, 'import matplotlib.pyplot as plt\n'), (52, 'matplotlib.pyplot.show', 'plt.show', ([], {}), True, 'import matplotlib.pyplot as plt\n'), (59, 'matplotlib.pyplot.plot', 'plt.plot', (["history.history['loss']"], {}), True, 'import matplotlib.pyplot as plt\n'), (60, 'matplotlib.pyplot.plot', 'plt.plot', (["history.history['val_loss']"], {}), True, 'import matplotlib.pyplot as plt\n'), (61, 'matplotlib.pyplot.xlabel', 'plt.xlabel', (['"""epoch"""'], {}), True, 'import matplotlib.pyplot as plt\n'), (62, 'matplotlib.pyplot.ylabel', 'plt.ylabel', (['"""loss"""'], {}), True, 'import matplotlib.pyplot as plt\n'), (63, 'matplotlib.pyplot.legend', 'plt.legend', (["['train', 'val']"], {}), True, 'import matplotlib.pyplot as plt\n'), (64, 'matplotlib.pyplot.show', 'plt.show', ([], {}), True, 'import matplotlib.pyplot as plt\n'), (72, 'matplotlib.pyplot.plot', 'plt.plot', (["history.history['loss']"], {}), True, 'import matplotlib.pyplot as plt\n'), (73, 'matplotlib.pyplot.plot', 'plt.plot', (["history.history['val_loss']"], {}), True, 'import matplotlib.pyplot as plt\n'), (74, 'matplotlib.pyplot.xlabel', 'plt.xlabel', (['"""epoch"""'], {}), True, 'import matplotlib.pyplot as plt\n'), (75, 'matplotlib.pyplot.ylabel', 'plt.ylabel', (['"""loss"""'], {}), True, 'import matplotlib.pyplot as plt\n'), (76, 'matplotlib.pyplot.legend', 'plt.legend', (["['train', 'val']"], {}), True, 'import matplotlib.pyplot as plt\n'), (77, 'matplotlib.pyplot.show', 'plt.show', ([], {}), True, 'import matplotlib.pyplot as plt\n'), (94, 'tensorflow.keras.models.load_model', 'keras.models.load_model', (['"""model-whole.h5"""'], {}), False, 'from tensorflow import keras\n'), (100, 'tensorflow.keras.callbacks.ModelCheckpoint', 'keras.callbacks.ModelCheckpoint', (['"""best-model.h5"""'], {'save_best_only': '(True)'}), False, 'from tensorflow import keras\n'), (104, 'tensorflow.keras.models.load_model', 'keras.models.load_model', (['"""best-model.h5"""'], {}), False, 'from tensorflow import keras\n'), (109, 'tensorflow.keras.callbacks.ModelCheckpoint', 'keras.callbacks.ModelCheckpoint', (['"""best-model.h5"""'], {'save_best_only': '(True)'}), False, 'from tensorflow import keras\n'), (113, 'tensorflow.keras.models.load_model', 'keras.models.load_model', (['"""best-model.h5"""'], {}), False, 'from tensorflow import keras\n'), (118, 'tensorflow.keras.callbacks.ModelCheckpoint', 'keras.callbacks.ModelCheckpoint', (['"""best-model.h5"""'], {'save_best_only': '(True)'}), False, 'from tensorflow import keras\n'), (119, 'tensorflow.keras.callbacks.EarlyStopping', 'keras.callbacks.EarlyStopping', ([], {'patience': '(2)', 'restore_best_weights': '(True)'}), False, 'from tensorflow import keras\n'), (124, 'matplotlib.pyplot.plot', 'plt.plot', (["history.history['loss']"], {}), True, 'import matplotlib.pyplot as plt\n'), (125, 'matplotlib.pyplot.plot', 'plt.plot', (["history.history['val_loss']"], {}), True, 'import matplotlib.pyplot as plt\n'), (126, 'matplotlib.pyplot.xlabel', 'plt.xlabel', (['"""epoch"""'], {}), True, 'import matplotlib.pyplot as plt\n'), (127, 'matplotlib.pyplot.ylabel', 'plt.ylabel', (['"""loss"""'], {}), True, 'import matplotlib.pyplot as plt\n'), (128, 'matplotlib.pyplot.legend', 'plt.legend', (["['train', 'val']"], {}), True, 'import matplotlib.pyplot as plt\n'), (129, 'matplotlib.pyplot.show', 'plt.show', ([], {}), True, 'import matplotlib.pyplot as plt\n'), (17, 'tensorflow.keras.Sequential', 'keras.Sequential', ([], {}), False, 'from tensorflow import keras\n'), (66, 'tensorflow.keras.layers.Dropout', 'keras.layers.Dropout', (['(0.3)'], {}), False, 'from tensorflow import keras\n'), (80, 'tensorflow.keras.layers.Dropout', 'keras.layers.Dropout', (['(0.3)'], {}), False, 'from tensorflow import keras\n'), (88, 'tensorflow.keras.layers.Dropout', 'keras.layers.Dropout', (['(0.3)'], {}), False, 'from tensorflow import keras\n'), (92, 'numpy.mean', 'np.mean', (['(val_labels == val_target)'], {}), True, 'import numpy as np\n'), (98, 'tensorflow.keras.layers.Dropout', 'keras.layers.Dropout', (['(0.3)'], {}), False, 'from tensorflow import keras\n'), (107, 'tensorflow.keras.layers.Dropout', 'keras.layers.Dropout', (['(0.3)'], {}), False, 'from tensorflow import keras\n'), (116, 'tensorflow.keras.layers.Dropout', 'keras.layers.Dropout', (['(0.3)'], {}), False, 'from tensorflow import keras\n'), (18, 'tensorflow.keras.layers.Flatten', 'keras.layers.Flatten', ([], {'input_shape': '(28, 28)'}), False, 'from tensorflow import keras\n'), (19, 'tensorflow.keras.layers.Dense', 'keras.layers.Dense', (['(100)'], {'activation': '"""relu"""'}), False, 'from tensorflow import keras\n'), (22, 'tensorflow.keras.layers.Dense', 'keras.layers.Dense', (['(10)'], {'activation': '"""softmax"""'}), False, 'from tensorflow import keras\n')]