2023-12-19 課程補充資料 Week 15

Demo Project

  1. 手寫辨識系統 by MNIST

import os

import numpy as np
import matplotlib.pyplot as plt

# plt.rcParams['figure.figsize'] = (7, 7)  # Make the figures a bit bigger

from keras.datasets import mnist
from keras.models import Sequential
from keras.layers.core import Dense, Dropout, Activation
from keras.utils import np_utils
from keras.models import load_model

nb_classes = 10

(train_images, train_labels), (test_images, test_labels) = mnist.load_data()
print("train_images original shape", train_images.shape)
print("train_labels original shape", train_labels.shape)

from keras import models
from keras import layers
from keras.utils import to_categorical

modeFileName = "./model_by_me.h5"
if (os.path.exists(modeFileName)):
    network = load_model(modeFileName)
    print("Read the previous model")
    fix_test_images = test_images.reshape((10000, 28 * 28)).astype('float32') / 255
    fix_test_labels = to_categorical(test_labels)

    test_loss, test_acc = network.evaluate(fix_test_images, fix_test_labels)
    print('test_loss:', test_loss)
    print('test_acc:', test_acc)
else:
    network = models.Sequential()
    print("Start to build the fresh model")

    # Hidden layer
    network.add(layers.Dense(512, activation='relu', input_shape=(28 * 28,)))

    # Output layer
    network.add(layers.Dense(10, activation='softmax'))

    network.compile(optimizer='rmsprop',  # 優化器選擇
                    loss='categorical_crossentropy',  # 損失函數
                    metrics=['accuracy'])  # 用準確度做評量

    fix_train_images = train_images.reshape((60000, 28 * 28)).astype('float32') / 255
    fix_train_labels = to_categorical(train_labels)

    fix_test_images = test_images.reshape((10000, 28 * 28)).astype('float32') / 255
    fix_test_labels = to_categorical(test_labels)

    result = network.fit(
        fix_train_images,  # training data
        fix_train_labels,  # 正確答案
        epochs=12,  # 代表要跑幾次
        batch_size=128,  # 每次訓練使用幾筆資料, 所以 60000 /128 約等於 469 組
        validation_data=(fix_test_images, fix_test_labels))

    test_loss, test_acc = network.evaluate(fix_test_images, fix_test_labels)
    print('test_loss:', test_loss)
    print('test_acc:', test_acc)

    # 儲存 model
    network.save('model_by_me.h5')  # creates a HDF5 file 'model_by_me.h5'

    # for draw chart, 畫出學習曲線 by 準確率
    history_dict = result.history
    loss_values = history_dict['loss']
    val_loss_values = history_dict['val_loss']
    epochs = range(1, len(loss_values) + 1)

    plt.clf()
    acc = history_dict['accuracy']
    val_acc = history_dict['val_accuracy']

    plt.plot(epochs, acc, 'bo', label='Training acc')
    plt.plot(epochs, val_acc, 'b', label='Validation acc')
    plt.title('Training and validation accuracy')
    plt.xlabel('Epochs')
    plt.ylabel('Accuracy')
    plt.legend()
    plt.show()

# 查看輸出結果
# predicted_classes = models.predict_classes(test_images)
# predict_x = network.predict(test_images)
predicted_classes = network.predict(fix_test_images)
predicted_classes = np.argmax(predicted_classes, axis=1)
correct_indices = np.nonzero(predicted_classes == test_labels)[0]
incorrect_indices = np.nonzero(predicted_classes != test_labels)[0]
plt.figure()
for i, correct in enumerate(correct_indices[:9]):
    plt.subplot(3, 3, i + 1)
    plt.imshow(test_images[correct].reshape(28, 28), cmap='gray', interpolation='none')
    plt.title("Predicted {}, Class {}".format(predicted_classes[correct], test_labels[correct]))
plt.tight_layout()
plt.show()
plt.figure()
for i, incorrect in enumerate(incorrect_indices[:9]):
    plt.subplot(3, 3, i + 1)
    plt.imshow(test_images[incorrect].reshape(28, 28), cmap='gray', interpolation='none')
    plt.title("Predicted {}, Class {}".format(predicted_classes[incorrect], test_labels[incorrect]))
plt.tight_layout()
plt.show()