MINST手寫數字識別(一)—— 全連接網絡


這是一個簡單快速入門教程——用Keras搭建神經網絡實現手寫數字識別,它大部分基於Keras的源代碼示例 minst_mlp.py.

1、安裝依賴庫

首先,你需要安裝最近版本的Python,再加上一些包Keras,numpy,matplotlib和jupyter.你可以安裝這些報在全局,但是我建議安裝它們在virtualenv虛擬環境,

這基本上封裝了一個完全孤立的Python環境。

安裝Python包管理器

sudo easy_install pip

安裝virtualenv

pip install virtualenv

使用cd ~進入主目錄,並創建一個名為kerasenv的虛擬環境

virtualenv kerasenv

再激活這個虛擬環境

source kerasenv/bin/activate

現在你可以安裝前面提到的包到這個環境

pip install numpy jupyter keras matplotlib

 

2、搭建神經網絡

以下代碼都在Google Colab中運行

2.1 導入一些依賴

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

 2.2 裝載訓練數據

nb_classes = 10

# the data, shuffled and split between tran and test sets
(X_train, y_train), (X_test, y_test) = mnist.load_data()
print("X_train original shape", X_train.shape)
print("y_train original shape", y_train.shape)

結果:

Downloading data from https://s3.amazonaws.com/img-datasets/mnist.npz
11493376/11490434 [==============================] - 0s 0us/step
X_train original shape (60000, 28, 28)
y_train original shape (60000,)

讓我們看看訓練集中的一些例子:

for i in range(20):
    plt.subplot(4,5,i+1)
    plt.imshow(X_train[i], cmap='gray', interpolation='none')
    plt.title("Class {}".format(y_train[i]))

 2.3 格式化訓練數據

對於每一個訓練樣本我們的神經網絡得到單個的數組,所以我們需要將28x28的圖片變形成784的向量,我們還將輸入從[0,255]縮到[0,1].

X_train = X_train.reshape(60000, 784)
X_test = X_test.reshape(10000, 784)
X_train = X_train.astype('float32')
X_test = X_test.astype('float32')
X_train /= 255
X_test /= 255
print("Training matrix shape", X_train.shape)
print("Testing matrix shape", X_test.shape)

結果:

Training matrix shape (60000, 784)
Testing matrix shape (10000, 784)

將目標矩陣變成one-hot格式

0 -> [1, 0, 0, 0, 0, 0, 0, 0, 0]
1 -> [0, 1, 0, 0, 0, 0, 0, 0, 0]
2 -> [0, 0, 1, 0, 0, 0, 0, 0, 0]
etc.
Y_train = np_utils.to_categorical(y_train, nb_classes)
Y_test = np_utils.to_categorical(y_test, nb_classes)

 

2.4 搭建神經網絡

2.4.1  搭建三層全連接網絡

我們將做一個簡單的三層全連接網絡,如下:

model = Sequential()
model.add(Dense(512, input_shape=(784,)))
model.add(Activation('relu')) # An "activation" is just a non-linear function applied to the output
                              # of the layer above. Here, with a "rectified linear unit",
                              # we clamp all values below 0 to 0.
                           
model.add(Dropout(0.2))   # Dropout helps protect the model from memorizing or "overfitting" the training data
model.add(Dense(512))
model.add(Activation('relu'))
model.add(Dropout(0.2))
model.add(Dense(10))
model.add(Activation('softmax')) # This special "softmax" activation among other things,
                                 # ensures the output is a valid probaility distribution, that is
                                 # that its values are all non-negative and sum to 1.

結果:

WARNING:tensorflow:From /usr/local/lib/python3.6/dist-packages/tensorflow/python/framework/op_def_library.py:263: colocate_with (from tensorflow.python.framework.ops) is deprecated and will be removed in a future version.
Instructions for updating:
Colocations handled automatically by placer.
WARNING:tensorflow:From /usr/local/lib/python3.6/dist-packages/keras/backend/tensorflow_backend.py:3445: calling dropout (from tensorflow.python.ops.nn_ops) with keep_prob is deprecated and will be removed in a future version.
Instructions for updating:
Please use `rate` instead of `keep_prob`. Rate should be set to `rate = 1 - keep_prob`.

2.4.2  編譯模型

      Keras是建立在Theano(現在TensorFlow也是),這兩個包都允許你定義計算圖,然后高效地在CPU或GPU上編譯和運行,而沒有Python解釋器地開銷。

      當編譯一個模型,Keras要求你確定損失函數和優化器,我使用的是分類交叉熵(categorical crossentropy),它是一種非常適合比較兩個概率分布的函數。

      在這里,我們的預測是十個不同數字的概率分布(例如,80%認為這個圖片是3,10%認為是2,5%認為是1等),目標是一個概率分布,正確類別為100%,其他所有類別為0。交叉熵是度量兩個概率分布差異程度的方法,詳情wiki

      優化器幫助模型快速的學習,同時防止“卡住“和“爆炸”的情況,我們不討論其太多的細節,但是“adam”是一個經常使用的好的選擇。

model.compile(loss='categorical_crossentropy', optimizer='adam')

2.4.3  訓練模型!

這是有趣的部分:你可以喂入之前加載好的訓練集到模型,它將學習如何分類數字.

model.fit(X_train, Y_train,
          batch_size=128, epochs=4,
          verbose=1,
          validation_data=(X_test, Y_test))

結果:

Train on 60000 samples, validate on 10000 samples
Epoch 1/4
60000/60000 [==============================] - 10s 171us/step - loss: 0.0514 - val_loss: 0.0691
Epoch 2/4
60000/60000 [==============================] - 10s 170us/step - loss: 0.0410 - val_loss: 0.0700
Epoch 3/4
60000/60000 [==============================] - 11s 177us/step - loss: 0.0349 - val_loss: 0.0750
Epoch 4/4
60000/60000 [==============================] - 11s 184us/step - loss: 0.0298 - val_loss: 0.0616
<keras.callbacks.History at 0x7f531f596fd0>

2.4.4  最后,評估其性能

score = model.evaluate(X_test, Y_test,
                       verbose=0)
print('Test score:', score)

效果:

Test score: 0.061617326979574866

檢查輸出,檢查輸出並確保一切看起來都很合理,這總是一個好主意。接下來,我們看一些分類正確的例子和錯誤的例子.

# The predict_classes function outputs the highest probability class
# according to the trained classifier for each input example.
predicted_classes = model.predict_classes(X_test)

# Check which items we got right / wrong
correct_indices = np.nonzero(predicted_classes == y_test)[0]
incorrect_indices = np.nonzero(predicted_classes != y_test)[0]
plt.figure()
for i, correct in enumerate(correct_indices[:9]):
    plt.subplot(3,3,i+1)
    plt.imshow(X_test[correct].reshape(28,28), cmap='gray', interpolation='none')
    plt.title("Predicted {}, Class {}".format(predicted_classes[correct], y_test[correct]))
    
plt.figure()
for i, incorrect in enumerate(incorrect_indices[:9]):
    plt.subplot(3,3,i+1)
    plt.imshow(X_test[incorrect].reshape(28,28), cmap='gray', interpolation='none')
    plt.title("Predicted {}, Class {}".format(predicted_classes[incorrect], y_test[incorrect]))

結果:

 

總之,這是一個完整的程序,在Keras主頁http://keras.io/和githubhttps://github.com/fchollet/keras有其它許多優秀的例子。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM