使用Keras建立神經網路對資料集MNIST分類
阿新 • • 發佈:2018-12-12
0. 環境
Ubuntu 18.04,64bit,i3-6100,8G
Python 2.7
1. 例程所需檔案
│ keras_mnist.py │ ├─mldata │ mnist-original.mat │ └─output
備註:這個樹形圖在win7下可以在cmd中輸入tree /F >D:\tree.txt
這個output是需要自行建立的,需要把損失函式和迭代次數的曲線圖輸出到影象檔案。而程式碼中matplotlib的儲存圖形函式似乎不會自動建立資料夾。
1.1 keras_mnist.py
# import the necessary packages from sklearn.preprocessing import LabelBinarizer from sklearn.model_selection import train_test_split from sklearn.metrics import classification_report from keras.models import Sequential from keras.layers.core import Dense from keras.optimizers import SGD from sklearn import datasets import matplotlib.pyplot as plt import numpy as np import argparse import os # construct the argument parse and parse the arguments ap = argparse.ArgumentParser() ap.add_argument("-o", "--output", default = "output/keras_mnist.png", #required=True, help="path to the output loss/accuracy plot") args = vars(ap.parse_args()) # grab the MNIST dataset (if this is your first time running this # script, the download may take a minute -- the 55MB MNIST dataset # will be downloaded) print("[INFO] loading MNIST (full) dataset...") path1 = os.path.dirname(os.path.abspath(__file__)) dataset = datasets.fetch_mldata("MNIST Original", data_home=path1) # scale the raw pixel intensities to the range [0, 1.0], then # construct the training and testing splits data = dataset.data.astype("float") / 255.0 (trainX, testX, trainY, testY) = train_test_split(data, dataset.target, test_size=0.25) # convert the labels from integers to vectors lb = LabelBinarizer() trainY = lb.fit_transform(trainY) testY = lb.transform(testY) # define the 784-256-128-10 architecture using Keras model = Sequential() model.add(Dense(256, input_shape=(784,), activation="sigmoid")) model.add(Dense(128, activation="sigmoid")) model.add(Dense(10, activation="softmax")) # train the model using SGD print("[INFO] training network...") sgd = SGD(0.01) model.compile(loss="categorical_crossentropy", optimizer=sgd, metrics=["accuracy"]) H = model.fit(trainX, trainY, validation_data=(testX, testY), epochs=100, batch_size=128) # evaluate the network print("[INFO] evaluating network...") predictions = model.predict(testX, batch_size=128) print(classification_report(testY.argmax(axis=1), predictions.argmax(axis=1), target_names=[str(x) for x in lb.classes_])) # plot the training loss and accuracy plt.style.use("ggplot") plt.figure() plt.plot(np.arange(0, 100), H.history["loss"], label="train_loss") plt.plot(np.arange(0, 100), H.history["val_loss"], label="val_loss") plt.plot(np.arange(0, 100), H.history["acc"], label="train_acc") plt.plot(np.arange(0, 100), H.history["val_acc"], label="val_acc") plt.title("Training Loss and Accuracy") plt.xlabel("Epoch #") plt.ylabel("Loss/Accuracy") plt.legend() plt.savefig(args["output"])
2. 執行結果
[INFO] evaluating network... precision recall f1-score support 0.0 0.95 0.96 0.95 1725 1.0 0.95 0.97 0.96 1988 2.0 0.91 0.89 0.90 1741 3.0 0.89 0.91 0.90 1752 4.0 0.91 0.92 0.91 1685 5.0 0.88 0.85 0.87 1606 6.0 0.94 0.94 0.94 1694 7.0 0.93 0.93 0.93 1874 8.0 0.89 0.87 0.88 1693 9.0 0.89 0.89 0.89 1742 avg / total 0.91 0.91 0.91 17500
可以見到精度是較高的,最低也達到了88%。
小結:例程用keras新建了full connnected的(784-256-128-10)網路。精度可達到80%。據說這已經是幾年前的水平了。如果使用CNN網路,結果可達98%。
本身本次例程是想在筆記本上跑的,跑得太吃力了。一次迭代需要1分鐘有多,而桌上型電腦只要2、3秒……電腦是要吃雞配置才行吶。
另外因為主要程式碼都不是我寫的,只要標轉載了。程式碼除了資料集的讀取路徑部分,其他都沒改,主要程式碼來源於Deep.Learning.for.Computer.Vision.with.Python.Starter.Bundle