Tensorflow2.0學習(三) — Keras基礎應用(Cifar-10圖像分類)

關於Cifar-10數據集大家應該也比較熟悉,屬於比較經典的入門分類的數據集。這裏我們不採用Cifar-100,因爲類別太多訓練時間過長,因此用10類別的Cifar-10代替,這個數據集包括:飛機、汽車、鳥、貓、鹿、狗、青蛙、馬、船、卡車 共10個類別。代碼的整體流程和前兩節內容差不多,一些相似的代碼不做過多解釋,有疑問的朋友們可以查看一下之前的內容。

一.CIFAR-10數據集下載

1.導入相關使用到的庫。

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

2.加載數據集。這裏有可能加載的時候速度非常慢,所以有另一個解決方法就是直接點擊https://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz下載,迅雷下載的速度會快一點,下載完直接將文件複製到當前環境目錄,keras/datasets的中,然後把文件的名字改爲cifar-10-batches-py.tar.gz即可。

(x_train,y_train),(x_test,y_test) = tf.keras.datasets.cifar10.load_data()

二.CIFAR-10數據集的查看

1.查看圖片數量和大小。因爲這裏的圖像已經是彩色圖像了,因此第四維的值爲3。

print(len(x_train))
print(len(x_test))
print(x_train.shape)

2.查看圖片單個點信息。因爲是彩色圖片,所以單個點的信息包含R、G、B三個顏色通道的值。

%第一個[0]代表取50000張圖片中的第一張,第二個[0]代表取第一行,第三個[0]代表取第一列
x_train[0][0][0] 

3.定義數字對應類別的字典,因爲我們訓練時的標籤是0-9,要映射成對應的類別名稱顯示。

label_dict={0:'airplane',1:'automobile',2:'bird',3:'cat',4:'deer',5:'dog',6:'frog',7:'horse',8:'ship',9:'truck'}

4.定義顯示圖片函數並顯示圖片,該函數和第一節大體一樣,有小部分需要修改一下。

def plot_images_labels_prediction(images,labels,prediction,idx,num=10):
    fig=plt.gcf()
    fig.set_size_inches(12,14)
    if num>25: num=25
    for i in range(0,num):
        ax = plt.subplot(5,5,i+1)
        ax.imshow(images[idx],cmap='binary') 
        title= str(i)+' '+label_dict[labels[i][0]]   #顯示數字對應的類別
        if len(prediction)>0:
            title+= '=>'+label_dict[prediction[i]]   #顯示數字對應的類別
        ax.set_title(title,fontsize=10)
        ax.set_xticks([])
        ax.set_yticks([])
        idx+=1
    plt.show()

plot_images_labels_prediction(x_train,y_train,[],0)

三.CIFAR-10數據集的預處理

1.數據標準化並查看一個點的值。

x_train_normalize = x_train.astype('float32')/255
x_test_normalize = x_test.astype('float32')/255
print(x_train_normalize[0][0][0])

2.對標籤進行One-Hot(獨熱編碼)。

y_train_OneHot = tf.keras.utils.to_categorical(y_train)
y_test_OneHot = tf.keras.utils.to_categorical(y_test)

四.模型搭建

1.這裏搭建3層卷積神經網絡提取特徵,之後在進行訓練。

model = tf.keras.models.Sequential()
model.add(layers.Conv2D(filters=32,kernel_size=(3,3),padding='same',input_shape=(32,32,3),activation='relu'))
model.add(layers.Dropout(0.3))
model.add(layers.Conv2D(filters=32,kernel_size=(3,3),padding='same',activation='relu'))
model.add(layers.MaxPooling2D(pool_size=(2,2)))
model.add(layers.Conv2D(filters=64,kernel_size=(3,3),activation='relu',padding='same'))
model.add(layers.Dropout(0.3))
model.add(layers.Conv2D(filters=64,kernel_size=(3,3),padding='same',activation='relu'))
model.add(layers.MaxPooling2D(pool_size=(2,2)))
model.add(layers.Conv2D(filters=128,kernel_size=(3,3),activation='relu',padding='same'))
model.add(layers.Dropout(0.3))
model.add(layers.Conv2D(filters=128,kernel_size=(3,3),padding='same',activation='relu'))
model.add(layers.MaxPooling2D(pool_size=(2,2)))
model.add(layers.Flatten())
model.add(layers.Dropout(0.3))
model.add(layers.Dense(2500,activation='relu'))
model.add(layers.Dropout(0.3))
model.add(layers.Dense(1500,activation='relu'))
model.add(layers.Dropout(0.3))
model.add(layers.Dense(10,activation='softmax'))

2.打印模型概要。

print(model.summary())

3.模型參數設置。

model.compile(loss='categorical_crossentropy',optimizer='adam',metrics=['accuracy'])

4.模型訓練,爲了節省時間這邊只訓練了5次。

train_history=model.fit(x_train_normalize,y_train_OneHot,validation_split=0.2,epochs=5,batch_size=128,verbose=1)

5.定義曲線顯示函數並顯示(和前兩節的一樣)。

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')
    plt.ylabel(train)
    plt.legend(['train','validation'],loc='upper left')

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

五.模型測試及預測

1.測試集進行測試。

scores = model.evaluate(x_test_normalize,y_test_OneHot,verbose=2)
print(scores[1])

2.模型預測。

prediction = model.predict_classes(x_test_normalize)
print(prediction)

3.調用之前定義的plot_images_labels_prediction函數查看具體圖片信息和結果。

plot_images_labels_prediction(x_test,y_test,prediction,0,10)

4.keras的model.predict_classes是用於直接預測出類別結果,如果我們想知道預測圖片分別對應10個類別的概率,我們可以用model.predict來進行查看。

prediction_probability = model.predict(x_test_normalize)
print(prediction_probability[0])

這裏的10個數字代表的預測圖片對應識別成10個類別的概率。

5.我們可以定義一個圖片+預測概率的函數,方便查看預測概率結果。

def show_predicted_probability(x,y,prediction,prediction_probability,i):
    print("label:",label_dict[y[i][0]],'predict,',label_dict[prediction[i]])
    plt.figure(figsize=(2,2))
    plt.imshow(x[i])
    plt.show()
    for j in range(10):          %輸出10個類別概率
        print(label_dict[j]+'Probability:%1.9f'%(prediction_probability[i][j]))

6.使用pandas的crosstab函數查看混淆矩陣。這裏要注意的是pandas.crosstab的輸入必須是一維數組,所以傳入的prediction和測試集的label都需要是一維的,如果不是一維數組,需要用reshape轉爲一維數組。

print(prediction.shape)
print(y_test.shape)

我們發現測試集的標籤不是一維數組,因此我們需要使用reshape(-1)去轉換,這裏的reshape(-1)就是將數據平鋪展開成了一維數組。之後傳入函數,發現運行成功。

pd.crosstab(y_test.reshape(-1),prediction,rownames=['label'],colnames=['prediction'])

六.模型保存和加載

1.訓練完模型之後我們可以用model.save_weights對模型進行保存,可以保存成h5格式的,如果出現保存失敗,可能原因是你電腦裏沒有安裝h5py這個東西或是版本不匹配直接卸載再安裝即可,在anaconda prompt中輸入pip install h5py就好了。

model.save_weights("cifar.h5")

2.如果要加載一個已經訓練好的模型的參數,則用load_weights進行讀取.

model.load_weights("cifar.h5")

 

以上是這一節的相關內容,謝謝大家的觀看,前三節都是基於圖像的訓練,下幾節內容將對文本數據進行分析。

 

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