Keras CIFAR-10彩色圖像物體識別 卷積神經網絡

參考書籍《Tensorflow+Keras 深度學習人工智能實踐應用》林大貴著
第九章,第十章。
這是一本很通俗易懂的入門實踐書,所有代碼,事無鉅細地進行了解釋


CIFAR-10數據集是60000個32x32的彩色圖像,分爲10類,飛機、汽車、鳥、貓、鹿、狗、青蛙、馬、船、卡車。50000個訓練圖像,10000個測試圖像

1.數據集處理
1-1. 下載CIFAR-10數據集

from keras.datasets import cifar10
import numpy as np
np.random.seed(10)

(x_image_train,y_label_train),\
(x_image_test,y_label_test)=cifar10.load_data()

cifar10.load_data()用於下載或者讀取CIFAR-10數據集,第一次下載會花費一點時間

1-2. 查看訓練數據
查看x_image_train的形狀
1-3.查看多項訓練數據(label and image)

import matplotlib.pyplot as plt
label_dict={0:'airplane',1:'automobile',2:'bird',3:'cat',4:'deer',5:'dog',6:'frog',
													7:'horse',8:'ship',9:'truck'}
#用字典dict定義每一個數字所代表的圖像類別名稱
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,1+i)
         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_image_train,y_label_train,[],0)#查看訓練數據前十項

prediction=[],暫無prediction的查看
1-4.對image,label 數據進行預處理
image 標準化,label轉換爲獨熱碼(One-Hot Encoding)
數字標準化可以提高模型的準確率,模型精度,提升模型收斂速度。

#image預處理 (RGB各通道除以255標準化)
x_image_train_norm=x_image_train.astype('float32')/255.0
x_image_test_norm=x_image_test.astype('float32')/255.0
x_image_train_norm[0][0][0]

查看了訓練數據第一個圖像第一個點的標準化結果,3個數據分別代表RGB
Out[12]: array([ 0.23137255, 0.24313726, 0.24705882], dtype=float32)

對label預處理
查看label形狀,前5項數據
在這裏插入圖片描述
在這裏插入圖片描述
將label轉爲One-Hot Encoding
(0—(1000000000),1–(0100000000),6對應的就是----(0000001000))

#label 預處理
#Keras 提供了np_utils.to_categorical方法可進行One-Hot Encoding轉換
from keras.utils import np_utils
y_label_train_OneHot=np_utils.to_categorical(y_label_train).reshape(50000,10)
y_label_test_OneHot=np_utils.to_categorical(y_label_test).reshape(10000,10)

輸入:y_label_train_OneHot[:5]在這裏插入圖片描述
2. Keras 卷積神經網絡識別CIFAR-10圖像
上接第一部分數據集下載和處理
2-1
卷積神經網絡可分爲兩部分
圖像特徵提取:卷積層1(conv1),池化層1(pooling1),conv2,pooling2,提取圖像特徵。
完全連接神經網絡:平坦層,隱藏層,輸出層所組成的神經網絡。

2-2 建立模型
卷積層、池化層、全連接網絡(平坦、隱藏、輸出層)線性堆疊
model.add() 爲模型增加層

#2-1 建立模型
from keras.models import Sequential
from keras.layers import Dense,Dropout,Activation,Flatten
from keras.layers import Conv2D,MaxPooling2D,ZeroPadding2D

#建立線性堆疊模型,後續只要將各個神經網絡加入模型即可
model=Sequential()
#建立卷積層1
model.add(Conv2D(filters=32,kernel_size=(3,3),input_shape=(32,32,3),
                 activation='relu',padding='same'))
#建立池化層1,將32x32的圖像縮減爲16x16的圖像
model.add(MaxPooling2D(pool_size=(2,2)))
#建立卷積層2
model.add(Conv2D(filters=64,kernel_size=(3,3),activation='relu',padding='same'))
#加入Dropout避免過擬合
model.add(Dropout(0.25))
#建立池化層2
model.add(MaxPooling2D(pool_size=(2,2)))
#建立神經網絡
    #建立平坦層
model.add(Flatten())
model.add(Dropout(0.25))
    #建立隱藏層
model.add(Dense(1024,activation='relu'))
model.add(Dropout(0.25))    
    #建立輸出層
model.add(Dense(10,activation='softmax'))
  • Conv1層參數
    | filters=32, | 設置隨機產生32個濾鏡 |
    |kernel_size=(3,3) |每個濾鏡大小爲3x3|
    | padding=‘same’ |讓卷積運算產生的卷積圖像大小不變 |
    |input_size=(32,32,3)|三維,前兩維代表圖像形狀大小32x32,第3維代表是彩色圖像,RGB三個通道 |
    |activation=‘relu’ |設置該層激活函數爲relu|
  • Pooling 1參數
  • pool_size=(2,2),將32x32圖像縮減爲16x16
  • Conv1層參數
    | filters=64, | 設置隨機產生64個濾鏡 |
    |kernel_size=(3,3) |每個濾鏡大小爲3x3|
    | padding=‘same’ |讓卷積運算產生的卷積圖像大小不變 |
    |activation=‘relu’ |設置該層激活函數爲relu|
  • Dropout 避免過度擬合
  • model.add(Dropout(0.25)) 每次訓練迭代在神經網絡放棄25%的神經元
    剩下的參數設置和上面相似
    輸入:print(model.summary()) 查看模型摘要
    在這裏插入圖片描述
    2-3 進行訓練
#開始訓練
train_history=model.fit(x=x_image_train_norm,y=y_label_train_OneHot,validation_split=0.2,
                                epochs=20,batch_size=128,verbose=2)

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


show_train_history(train_history,'acc','val_acc')

plt.figure()
show_train_history(train_history,'loss','val_loss')
  • loss:設置損失函數,在深度學習中使用交叉熵訓練效果較好
  • optimizer:在訓練時,使用adam優化器可以讓訓練更快收斂,並提高準確率
  • metrics設置評估模型的方式是準確率
  • model.fit訓練,訓練過程存在train_history裏面,model.fit需要的參數:
  • 輸入訓練數據參數
  • x_image_train_norm,y_label_train_OneHot
  • 設置訓練與驗證數據的比例
  • validation_split=0.2, 80%爲訓練數據(50000x0.8=40000),20%爲驗證數據
  • epochs=20,網絡訓練20次
  • batch_size=128,每批次128項數據,共40000/128=313個批次,每次網絡訓練要處理313個批次的數據
  • verbose=2, 顯示訓練過程
#2-3
#查看模型正確率
scores=model.evaluate(x_image_test_norm,y_label_test_OneHot,verbose=1)

在這裏插入圖片描述

#2-4 進行預測
prediction=model.predict_classes(x_image_test_norm)
#預測結果,前10項數據
prediction[:10]
#顯示前10項結果
plt.figure()
plot_images_labels_prediction(x_image_test,y_label_test,prediction,0,10)

在這裏插入圖片描述
2-5 顯示預測概率
查看第1項test數據的概率(被分類爲各類的概率)

#2-5 顯示預測概率
#預測概率
Predicted_Probability=model.predict(x_image_test_norm)

def show_Predicted_Probability(y_label,prediction,x_image,
                                   Predicted_Probabilty,i):
    print('label:',label_dict[y_label[i][0]],
              'predict',label_dict[prediction[i]])
    plt.figure(figsize=(2,2))
    plt.imshow(np.reshape(x_image_test[i],(32,32,3)))
    plt.show()
    for j in range(10):
        print(label_dict[j]+' '+'Probability:%1.9f'%(Predicted_Probability[i][j]))
show_Predicted_Probability(y_label_test,prediction,x_image_test,Predicted_Probability,1)  

在這裏插入圖片描述在這裏插入圖片描述

可以看出這張船圖片,被分類爲船的概率爲0.8812,概率最高,最後預測結果是正確的,第0項是分類錯誤的,也可以查看概率,如上。

2-6 顯示混淆矩陣
用pd.crosstab建立混淆矩陣,它的輸入要求是一維數組,所有用y_label_test.shape,prediction.shape,分別查看是不是一維數,其中y_label_test爲(10000,1),要用reshape,轉換爲一維數組

#2-6 顯示混淆矩陣
y=y_label_test.reshape(-1)  #將其轉換爲一維數組

import pandas as pd
print(label_dict)
pd.crosstab(y,prediction,rownames=['labels'],colnames=['predict'])

在這裏插入圖片描述
對角線是預測正確的,可以分析出最容易混淆的類別,和最不容易混淆的。

2-7 模型的加載與保存
每次訓練卷積神經網絡都會花費很長時間,,可以在每次完成訓練後,保存模型,或者保存權重,下次執行訓練先加載模型權重,再繼續訓練

'''
#2-7 模型的加載與保存
model.save('model.h5')
#保存模型權重
model.save_weights('my_model_weights.h5')
#下次使用的時候
model = load_model('model.h5')
model.load_weights('my_model_weights.h5')
'''

在這裏插入圖片描述
在你保存腳本文件的文件夾就會出現保存好的h5文件

END
建立3次的卷積運算神經網絡會進一步提高準確率。

遇到的問題:
1.小白問題,變量名手抖打錯
2.注意關注維數,原書中的np_utils.to_categorical方法可進行One-Hot Encoding轉換,轉換後的形狀卻是(50000,1,10),後面進行網絡訓練報錯,提示輸出層需要輸入一個二維向量,而收到的是(50000,1,10),所以我又去reshape了一下。也沒查明白,這個np_utils.to_categorical怎麼不好使了,在之前MNIST手寫數字識別,這個就沒什麼問題。
更改爲:
y_label_train_OneHot=np_utils.to_categorical(y_label_train).reshape(50000,10)

Thank you for reading…繼續堅持不懈地記錄學習過程

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