Tensorflow2.0學習(一) — Keras基礎應用(MNIST手寫數字圖像識別)

近期準備開始學習Tensorflow2.0, 順便複習一下Keras的一些相關原理,因此特此寫一些系列教程來分享以及記錄我學習過程中的一些知識,總結一些看過的書的內容和網上教程,文章內容均爲原創,可能會有些錯誤的地方,希望大家多多批評和支持,博主會不間斷進行更新。

新版的Tensorflow2.0與原版的Tensorflow有着較大的更新和變動,Tensorflow2.0將Keras作爲默認高級API,並捨棄掉其它的API。此外,另外較大的變動的是將用於機器學習的實驗和研究平臺 Eager execution 設置爲默認優先模式, 這樣設置的好處是我們不用再像以前一樣預先定義靜態圖,任何的運算在調用之後都可以直接執行。與原版相比,Tensorflow2.0更方便,大幅降低了初學者學習的難度。

這裏並不對Tensorflow2.0的其它特性做具體描述,總之我們可以比較清楚的明白,Keras是我們學習的首要基礎,下文便是對Keras一些常用操作結合一些基本案例來進行描述。

一.Tensorflow2.0的安裝

1.Tensorflow2.0的主要配置環境及使用還是在Anaconda及Jupyter notebook裏,對於Anaconda的安裝這裏不做過多描述,有很多博客有很仔細的教程,這裏主要想講的一點的關於Tensorflow2.0安裝的點,因爲現在用在Anaconda Prompt 直接 pip install 指令安裝實在是太慢了,經常會中斷,因此我們可以用國內的一些鏡像源進行安裝,大家可以輸入以下指令,中間多了一個網站,然後就會發現安裝速度特別快了,其它庫的安裝也是一樣的,把後面庫的名字改掉即可。

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple tensorflow-gpu==2.0.0-alpha0

2.這裏要提醒的是,Tensorflow2.0 目前只能和python3.6版本進行匹配,因此大家安裝時記得創建新的虛擬環境,而且先前安裝的其它第三方庫可能會有衝突容易導致導入失敗,如果有這種情況可以將原來的一些的第三方庫進行卸載再重新安裝即可。

二.MNIST的數據查看

1.相關包導入,爲了方便起見,我們直接使用tensorflow2.0導入keras,就不用另外安裝了。

import tensorflow as tf                 
from tensorflow.keras import layers
import matplotlib.pyplot as plt
import pandas as pd

2.讀取MNIST數據。

#分別讀入MNIST數據集的訓練集數據和測試集數據
(X_train_image,y_train_label),(X_test_image,y_test_label) = tf.keras.datasets.mnist.load_data()

3.打印MNIST數據的尺寸大小

print(len(X_train_image))
print(len(X_test_image))
print(X_train_image.shape)

顯示的結果:

 

60000張圖像是訓練集的數目,10000張則是測試集的數目,(60000,28,28)中的60000代表的是Batch_size, 28和28分別代表一張圖像的長和寬。

4.定義函數顯示數字的圖像

def plot_image(image):
    fig=plt.gcf()    #圖表生成
    fig.set_size_inches(3,3)  #設置圖表大小
    plt.imshow(image,cmap='binary') #以黑白灰度顯示圖片
    plt.show()    #開始繪圖

plot_image(X_train_image[0]) #顯示一張圖片

5.爲了更加方便查看圖像、標籤及預測結果之間對應的關係,我們定義一個函數來顯示。

def plot_image_labels_prediction(images,labels,prediction,idx,nums=10):
    fig = plt.gcf() 
    fig.set_size_inches(12,14)  #設置圖表大小
    if nums>25: nums=25 #最多顯示25張圖像
    for i in range(0,nums):
        ax = plt.subplot(5,5,1+i) #子圖生成
        ax.imshow(images[idx],cmap='binary') #idx是爲了方便索引所要查詢的圖像
        title = 'label=' + str(labels[idx]) #定義title方便圖像結果對應
        if(len(prediction)>0): #如果有預測圖像,則顯示預測結果
            title += 'prediction='+ str(prediction[idx])
        ax.set_title(title,fontsize=10) #設置圖像title
        ax.set_xticks([]) #無x刻度
        ax.set_yticks([]) #無y刻度
        idx+=1
    plt.show()

plot_image_labels_prediction(X_train_image,y_train_label,[],0,10) #顯示前10張的圖像

下圖爲最後一行命令的顯示結果:

三.MNIST的數據預處理

1.將image轉化爲一維向量, 轉化過程是圖像大小相乘,結果爲:28x28 = 784, 以便於能作爲神經網絡的第一層輸入。

X_train = X_train_image.reshape(60000,784).astype('float32') #二維轉一維
X_test = X_test_image.reshape(10000,784).astype('float32')

2.對圖像數據進行歸一化。歸一化是必要操作,可以提高準確率。原因是如果沒有歸一化那麼圖像的數據值是0-255,不同的圖像之間的值差異很大,在訓練過程中,小的值很容易被忽略。因此我們需要對數據進行縮放,常見的一種方法是將數據的值壓縮到(0,1)區間內,在本例中,直接將數據除以255即可。

X_train_normalize = X_train/255 #歸一化
X_test_normalize = X_test/255

3.對數據標籤進行One-hot編碼(獨熱編碼),我們都知道數字識別的結果是0-9,但爲了滿足神經網絡的最後一層的10個神經元輸出,我們需要將數字轉換爲二進制的10個0和1的組合,具體可看下面代碼例子,第一個爲數據的原標籤,第二個是One-hot編碼後的標籤。

y_train_label[:5] #顯示前5個圖像的對應標籤數字

之後大家可以直接調用keras的utils中的to_categorical函數進行直接數字編碼。

y_TrainOneHot = tf.keras.utils.to_categorical(y_train_label) #One-Hot編碼
y_TestOneHot = tf.keras.utils.to_categorical(y_test_label)

y_TrainOneHot[0:5] #顯示前5個數據編碼後的結果

 

上圖爲編碼結果,其中1在第幾個位置則代表了數字的大小是多少。

四.模型的搭建

1.建立線性堆疊模型Sequential,使用它我們可以搭建出很多複雜的神經網絡模型,後面的層就猶如疊麪包一樣一層一層通過add指令疊加上去就好了,十分方便。

model = tf.keras.models.Sequential() # 調用Sequential模型

2.不斷疊加層上去,Dense層是全連接層,指的是神經前後前後兩層神經元中兩兩都有互相連接,而Dropout的層的作用是爲了防止過擬合(過擬合概念可自行查詢),隨機使多少比例的神經元失活,等於是斷了之間的連接關係。

#units是該層神經元數量,input_dim是數據輸入大小,kernel_initializer=normal指的是用正態分佈來初始化神經元的權重和偏差,activation指的是激活函數
model.add(layers.Dense(units=256,input_dim=784,kernel_initializer='normal',activation='relu')) 
model.add(layers.Dropout(0.5)) #使50%的神經元失活
#最終輸出是0-9,因此是10個神經元,softmax激活函數可以將輸出轉化爲預測每個數字的概率
model.add(layers.Dense(units=10,kernel_initializer='normal',activation='softmax'))

3.通過summary我們可以查看我們剛纔搭建的模型的概要。

print(model.summary()) #顯示模型信息

大家可以從上圖看到我們剛建立的模型信息,其中Param指的是該層神經元總的參數數量,具體的計算公式是 Param=(上一層神經元數量)x(本層神經元數量)+(本層神經元數量)

比如圖中的200960是由(784x256+256)得到的。

五.模型的訓練

1.在訓練模型之間,我們需要定義一些訓練的相關參數,比如優化器、損失函數和評估模型的方式。

#loss這裏採用的交叉熵損失,優化器採用的是adam優化器,評估方式爲準確率
model.compile(loss='categorical_crossentropy',optimizer='adam',metrics=['accuracy'])

2.開始訓練,其中validation_split是將原數據集劃分一部分爲驗證集,epoch是訓練次數,batch_size是每一批訓練的數據量,verbose=2代表顯示所有訓練過程。

train_history = model.fit(x=X_train_normalize,y=y_TrainOneHot,validation_split=0.2,epochs=10,batch_size=200,verbose=2) 

3.我們可以通過train_history查看訓練過程,之前的訓練步驟的值都保存在這裏面。這裏共有loss,accuracy,val_loss,val_accuracy四個參數。

train_history.history

4.我們還可以定義函數,顯示訓練的曲線圖。

def show_train_history(train_history,train,validation):
    plt.plot(train_history.history[train]) #繪製訓練數據的執行結果
    plt.plot(train_history.history[validation]) #繪製驗證數據的執行結果
    plt.title('Train History') #圖標題 
    plt.xlabel('epoch') #x軸標籤
    plt.ylabel(train) #y軸標籤
    plt.legend(['train','validation'],loc='upper left') #添加左上角圖例

show_train_history(train_history,'accuracy','val_accuracy')

六.模型的測試

1.我們通過evaluate可以使用模型在測試集上進行測試。

scores = model.evaluate(X_test_normalize,y_TestOneHot) 
print('accuracy=',scores[1]) #顯示測試準確率

2.對模型進行預測,並使用之前我們定義的函數plot_image_labels_prediction,可以方便查看預測結果之間的對應關係。

prediction = model.predict_classes(X_test) #結果預測
plot_image_labels_prediction(X_test_image,y_test_label,prediction,idx=340)

3.我們還可以通過pandas中的crosstab調用混淆矩陣,來查看哪些結果最容易混淆,對角線部分,爲正確預測的部分,其它部分則是預測錯誤的部分。

pd.crosstab(y_test_label,prediction,rownames=['label'],colnames=['predict'])

4.我們還可以通過pandas的DataFrame來查看預測錯誤數據的位置。

df = pd.DataFrame({'label':y_test_label,'predict':prediction})
print(df[(df.label==5)&(df.predict==3)]) #查看是5預測錯成3的數據位置

或者通過我們先前定義的plot_image_labels_prediction函數,也可以直接查看預測錯誤的圖像。

plot_image_labels_prediction(X_test_image,y_test_label,prediction,idx=340,nums=1)

 

以上便是Keras第一個實例的操作內容,該實例比較完整的演示了一個簡單數據集在訓練、測試及預測的整體流程,過段時間會分享後續的系列內容,感謝大家的觀看!

 

 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章