1. 程式人生 > >使用Keras建立神經網路對資料集MNIST分類

使用Keras建立神經網路對資料集MNIST分類

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