1. 程式人生 > >Keras卷積神經網路識別CIFAR-10影象(2)

Keras卷積神經網路識別CIFAR-10影象(2)

上一篇文章簡單介紹了卷積神經網路的結構,本篇文章則會利用上一篇文章的理論知識搭建神經網路模型來識別CIFAR-10影象。

2.Keras卷積神經網路識別CIFAR-10影象

首先簡單介紹一下什麼是CIFAR-10,CIFAR-10是是用於物件識別的已建立的計算機視覺資料集。它是8000萬個微小影象資料集的一個子集,由60,000個32x32彩色影象組成,包含10個物件類別中的一個,每個類別有6000個影象。它由Alex Krizhevsky,Vinod Nair和Geoffrey Hinton收集。其中,這10個物件類別分別是飛機,汽車,鳥,貓,鹿,狗,青蛙,馬,船,卡車。

2.1資料預處理

(1)首先匯入所需要的模組和資料

from keras.datasets import cifar10  #下載CIFAR-10資料集
import numpy as np
np.random.seed(10)        #設定seed產生需要的隨機數
import matplotlib.pyplot as plt
from keras.utils import np_utils
from keras.models import Sequential
from keras.layers import Dense,Dropout,Activation,Flatten
from keras.layers import Conv2D,
MaxPooling2D,ZeroPadding2D import pandas as pd

(2)讀取下載的資料集

(x_img_train,y_label_train),(x_img_test,y_label_test)=cifar10.load_data()

我們看一下訓練集與測試集的影象和標籤的大小和形狀

print(x_img_train.shape)
print(y_label_train.shape)
print(x_img_test.shape)
print(y_label_test.shape)

執行結果
在這裡插入圖片描述
可以看到,訓練集中有50000個大小為32x32的三原色圖,而測試集有10000個大小為32x32的三原色圖,最後那個3代表影象是一個RGB三原色圖。

(3) 建立一個dict,定義每一個數字所代表的影象類別的名稱

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

為了方便檢視多項資料的images,labels和prediction,所以定義一個名為plot_images_labels_prediction的函式來實現目的

def plot_images_labels_prediction(images,labels,prediction,idx,num=10):#images為影象,labels為標籤,prediction為預測,idx為要開始顯示的影象的索引,num為要顯示影象的數量,預設是10,最多25
    fig=plt.gcf()
    fig.set_size_inches(12,14) #設定畫布大小為12x14英寸
    if num>25:         #設定最多可以顯示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)+".labels:"+label_dict[labels[i][0]] #label[i][0]即為第i個影象所屬的類別
        if len(prediction)>0:
            title=title+",prediction:"+label_dict[prediction[i]]
        ax.set_title(title,fontsize=10)
        ax.set_xticks([])
        ax.set_yticks([])
        idx+=1
    plt.show()

(4)分別將訓練集和測試集中的影象進行標準化轉換,這樣做可以提高模型預測的準確度,並且更快收斂。

x_img_train_normalize=x_img_train.astype('float32')/255.0
x_img_test_normalize=x_img_test.astype('float32')/255.0

(5)將label以一位有效編碼進行轉換,即轉換為10個由0和1組成的組合,分別代表10個不同的分類。例如0000000000代表airplay,0100000000代表automobile。

y_label_train_OneHot=np_utils.to_categorical(y_label_train)
y_label_test_OneHot=np_utils.to_categorical(y_label_test)

2.2建立卷積神經網路並訓練模型

在模型中我們交替增加三個卷積層,三個池化層,每個卷積層進行兩次卷積運算,然後再增加全連線層(包括一個平坦層,兩個隱藏層和一個輸出層),並且在每個卷積層和池化層之間增加,兩個隱藏層之間增加一個Dropout功能,其目的是選擇性地放棄一些神經元,防止模型過擬合。模型架構及說明如下圖所示:
在這裡插入圖片描述
在這裡插入圖片描述

(1)首先建立一個Sequential線性堆疊模型,後續要增加捲積層,池化層,全連線層的話,只需直接呼叫add()方法即可。

model=Sequential()

(2)三個卷積層的卷積核大小均為3x3,第一個卷積層卷積核個數為32,第二個卷積層卷積核個數為64,第三個卷積層卷積核個數為128,每個卷積層均作兩次卷積運算。

model.add(Conv2D(filters=32,kernel_size=(3,3),input_shape=(32,32,3),activation='relu',padding='same'))  #卷積層1第一次卷積運算
model.add(Dropout(0.3))
model.add(Conv2D(filters=32,kernel_size=(3,3),activation='relu',padding='same')) #卷積層1第二次卷積運算
model.add(MaxPooling2D(pool_size=(2,2)))#池化層1
model.add(Conv2D(filters=64,kernel_size=(3,3),activation='relu',padding='same'))#卷積層2第一次卷積運算
model.add(Dropout(0.3))
model.add(Conv2D(filters=64,kernel_size=(3,3),activation='relu',padding='same'))#卷積層2第二次卷積運算
model.add(MaxPooling2D(pool_size=(2,2)))#池化層2
model.add(Conv2D(filters=128,kernel_size=(3,3),activation='relu',padding='same'))#卷積層3第一次卷積運算
model.add(Dropout(0.3))
model.add(Conv2D(filters=128,kernel_size=(3,3),activation='relu',padding='same'))#卷積層3第二次卷積運算
model.add(MaxPooling2D(pool_size=(2,2)))#池化層3

model.add(Flatten())  #建立平坦層
model.add(Dropout(0.3))
model.add(Dense(2500,activation='relu'))  #第一個隱藏層,共有2500個神經元
model.add(Dropout(0.3))
model.add(Dense(1500,activation='relu'))  #第二個隱藏層,共有1500個神經元
model.add(Dropout(0.3))
model.add(Dense(10,activation='softmax')) #輸出層,共有10個輸出,代表10個不同的類別

以下為各引數的說明

引數名 說明
filters 卷積核的個數,本層卷積核的個數決定下一層最少需要的卷積核的個數
kernel_size 卷積核的大小
input_shape 從模型外輸入資料的大小
activation 啟用函式,可以把模型從線性的轉換為非線性的
padding 這個設定讓卷積產生的影象大小不變,其實就是在輸入影象的外圍加入數字0的圈數,最小值為0
Dropout 防止模型過擬合

訓練前還要設定損失函式,優化器,評估模型的方式

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

(3)為了增加準確率,我們設定訓練週期數為50。訓練時間和電腦本身效能有關,博主的電腦是i5 6300HQ+GTX960M的,因為運算量大,所以使用GPU來完成訓練

train_history=model.fit(x_img_train_normalize,y_label_train_OneHot,validation_split=0.2,epochs=50,batch_size=300,verbose=1)
引數名 說明
validation_split=0.2 把x_img_train_normalize中的50000x80%=40000個數據項用來訓練模型,剩下的50000x20%=10000個數據項用來驗證模型,防止模型過擬合
epochs=50 設定50個訓練週期
batch_size=300 在每一個訓練週期中的每一次訓練都從40000個數據中抽取300個數據出來訓練
verbose=1 verbose=1表示輸出訓練進度條記錄

由於截圖太長,只截了部分
在這裡插入圖片描述
在這裡可以看到,訓練大概用了不到20分鐘,博主之前試過用CPU進行訓練,時間大約是這個的8倍,可見GPU的平行計算能力是十分強大的!

接下來,定義一個函式來查看準確率的變化

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

看下訓練過程中準確率的變化

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

執行結果
在這裡插入圖片描述
可以看到訓練的準確率不是很高,想要提高準確率可能要增加捲積核的數目,或者是卷積層的數目等。

2.3檢視訓練結果並對測試集進行預測

前面通過構建卷積神經網路訓練了模型,下面用訓練得到的模型對測試集進行預測。

先來看下預測準確率

scores=model.evaluate(x_img_test_normalize,y_label_test_OneHot,verbose=0)

在這裡插入圖片描述
模型的預測準確率為0.7959,但損失函式也達到了0.78.

(1)用以下指令進行結果預測

prediction=model.predict_classes(x_img_test_normalize)

看下前10個影象的預測結果

prediction[:10]

在這裡插入圖片描述
可以看到第一張圖的預測結果是3,第二張圖的預測結果是8。。。。。
(2)檢視每張圖的預測概率

Predicted_Probability=model.predict(x_img_test_normalize) #計算每張圖片被預測為某個類的概率

我們可以定義一個函式來檢視每張圖片被預測為某個類的概率

def show_Predicted_Probability(y,prediction,x_img,Predicted_Probability,i):
    print('label:',label_dict[y[i][0]],'prediction:',label_dict[prediction[i]])
    plt.figure(figsize=(2,2))
    plt.imshow(np.reshape(x_img[i],(32,32,3)))
    plt.show()
    for j in range(10):
        print(label_dict[j]+' probability:%1.9f'%Predicted_Probability[i][j])
引數名 解釋
y 標籤
prediction 預測結果
x_img 原圖
Predicted_Probability x_img中每張圖片被預測為10個類中的每個類的概率
i 索引

我們隨便看一張圖

show_Predicted_Probability(y_label_test,prediction,x_img_test,Predicted_Probability,60)

執行結果如圖
在這裡插入圖片描述
可以看到被預測為馬的概率最高,被預測為鹿的概率次之,被預測為青蛙的概率為最低,被預測為其它類的概率為零。

我們看一個被預測錯誤的影象

for i in range (0,10000):
    if(y_label_test[i]!=prediction[i]):
        show_Predicted_Probability(y_label_test,prediction,x_img_test,Predicted_Probability,i)
        break

在這裡插入圖片描述
可以看到被預測為“貓”的概率最高,但正確結果卻是“汽車”,預測有誤了。

(3)建立混淆矩陣,作進一步分析
我們需要把y_label_test和prediction組合建立一個混淆矩陣,但由文章的開頭得知,y_label_test是一個二維陣列,所以要把它轉換為一維陣列才行。

y_label_tset=y_label_test.reshape(-1)
y_label_test.shape

執行結果
在這裡插入圖片描述
建立混淆矩陣

print(label_dict)
pd.crosstab(y_label_test,prediction,rownames=['label'],colnames=['prediction'])

執行結果
在這裡插入圖片描述
仔細觀察分析,我們可以得出一些結論

1.  在識別錯誤的影象中, label值是”5“,但prediction是”3“的錯誤數量最多,即”狗“容易被誤識別為”貓“,同樣,label值是”3“,但prediction是”5“的數量次之,即”貓“也容易被誤識別為”狗“,據說識別”貓“和”狗“這個問題吳恩達大大做得很好,大家可以去百度看下。
2.  在2,3,4,5,6,7這六個類別中,被識別成1和9的概率最低,也就是說2(鳥),3(貓),4(鹿),5(狗),6(蛙),7(馬)這些動物被識別為1(汽車)和9(卡車)的概率很低。
3.  在8(船)和9(卡車)中,被預測為0(飛機)和1(汽車)的概率很高,即交通工具容易被預測為交通工具,動物容易被預測為動物。

2.4模型儲存

將訓練得到的模型儲存起來

model.save_weights("CIFAR-10 Model.h5")
print("Save model successfuly")

模型將會儲存在你當前的工作目錄下。

另外,儲存模型後,如果下一次要用這個模型,使用以下方法載入模型

try:
	model.load_weights("CIFAR-10 Model.h5")
	print("Load model successfuly")
except:
	print("Load model error")

(完)

參考書籍:

《TensorFlow+Keras深度學習人工智慧實踐應用》林大貴 著

《圖解深度學習》

相關推薦

Keras神經網路識別CIFAR-10影象2

上一篇文章簡單介紹了卷積神經網路的結構,本篇文章則會利用上一篇文章的理論知識搭建神經網路模型來識別CIFAR-10影象。 2.Keras卷積神經網路識別CIFAR-10影象 首先簡單介紹一下什麼是CIFAR-10,CIFAR-10是是用於物件識別的已建立的計算機

【翻譯】TensorFlow神經網路識別CIFAR 10Convolutional Neural Network (CNN)| CIFAR 10 TensorFlow

原網址:https://data-flair.training/blogs/cnn-tensorflow-cifar-10/ by DataFlair Team · Published May 21, 2018 · Updated September 15, 2018 1、目標-TensorFlow C

深度學習入門——利用神經網路訓練CIFAR10資料集

CIFAR-10資料集簡介 CIFAR-10是由Hinton的學生Alex Krizhevsky和Ilya Sutskever整理的一個用於普適物體的小型資料集。它一共包含10個類別的RGB彩色圖片:飛機、汽車、鳥類、貓、鹿、狗、蛙類、馬、船: 資料集包含50000張訓練圖片和1000

TensorFlow學習--神經網路訓練CIFAR-10資料集

CIFAR-10資料集 CIFAR-10資料集包含10個類的60000張32x32的彩色影象,每個類有6000張影象。 有50000張訓練影象和10000張測試影象。 10個分類明細及對應的部分圖片: 卷積神經網路訓練CIFAR-10資料集

cs231n斯坦福基於神經網路的CV學習筆記神經網路訓練細節

五,神經網路 注意點part1 例項:邏輯迴歸二層神經網路訓練函式 使用權重w和偏差值biase計算出第一個隱含層h,然後計算損失,評分,進行反向傳播回去 多種常用啟用函式(一般預設max(0,x)),如sigmoid函式具有飽和區梯度0,非零點中心,計算x複

神經網路—目標檢測 學習筆記

3.7 非極大值抑制(Non-max suppresion) 非極大值抑制,即只保留極大值(概率最大的預測結果)。 之前介紹的YOLO還存在的一個問題:同一個目標可能出現多個預測結果。如下圖所示: 對於右邊的汽車,會有三個網格認為中點落在了自己中,

基於Keras mnist手寫數字識別---Keras神經網路入門教程

目錄 1、一些說明 2、常量定義 3、工具函式 4、模型定義以及訓練 4.1、匯入庫 4.2、主入口 4.3、主函式 4.3.1、獲取訓練資料 4.3.1、定義模型 4.3.2

keras+神經網路HWDB手寫漢字識別

寫在前面 HWDB手寫漢字資料集來自於中科院自動化研究所,下載地址: 原始碼 按照github上的提示操作: (1)解壓 unzip HWDB1.1trn_gnt.zip Archive: HWDB1.1trn_gnt.zip inflating:

eclipse擼一發Keras神經網路對手寫數字識別

一、導讀     1、window10 python環境Anaconda 安裝   &

用TensorFlow訓練神經網路——識別驗證碼

需要用到的包:numpy、tensorflow、captcha、matplotlib、PIL、random import numpy as np import tensorflow as tf # 深度學習庫 from captcha.image import ImageCaptcha

神經網路, 識別人臉性別

原博地址https://laboo.top/2018/12/02/tfjs-face/#more 在傳統程式設計中, 影象識別一直是一個難點, 雖然人能輕鬆做到, 但是用邏輯來描述這個過程, 並轉換成程式是很難的。機器學習的出現讓影象識別技術有了突破性的進展, 卷積神經網路的出現, 又使影象識別更上了一次層

神經網路CIFAR資料集分類

本例通過一個具有全域性平局池化層的神經網路對CIFAR資料集分類 1.匯入標頭檔案引入資料集 這部分使用cifar10_input裡面的程式碼,在cifar10資料夾下建立卷積檔案,部分程式碼如下: import cifar10_input import tensorf

利用神經網路識別手寫數字

1.測試資料準備 1.我們使用的測試資料,可以直接從keras.datasets.mnist匯入 import numpy as np import seaborn as sns import matplotlib.pyplot as plt plt.rcParams['figure

機器學習實驗:用tensorflow實現神經網路識別人類活動

在近幾年,越來越多的使用者在智慧手機上安裝加速度感測器等一些裝置,這就為做一些應用需要收集相關的資料提供了方便。人類活動識別(human activity recognition (HAR))是其中的一個應用。對於HAR,有很多的方法可以去嘗試,方法的performance很大程度上依賴於特徵工程。傳統的機

基於PyTorch的CNN神經網路識別MNIST手寫數字

本篇部落格主要介紹基於PyTorch深度學習框架來實現MNIST經典的手寫數字,運用CNN卷積神經網路。MNIST資料集來自美國國家標準與技術研究所,其中訓練資料有60000張,測試資料有10000張,每張圖片的大小是28*28畫素我們可以基於PyTorch直接下載該資料集。

機器學習與深度學習系列連載: 第二部分 深度學習十二神經網路 3 經典的模型LeNet-5,AlexNet ,VGGNet,GoogLeNet,ResNet

卷積神經網路 3 經典的模型 經典的卷積神經網路模型是我們學習CNN的利器,不光是學習原理、架構、而且經典模型的超引數、引數,都是我們做遷移學習最好的源材料之一。 1. LeNet-5 [LeCun et al., 1998] 我們還是從CNN之父,LeCun大神在98年提出的模

利用tensorflow實現簡單的神經網路-對程式碼中相關函式介紹——遷移學習小記

  上篇文章對cnn進行了一些介紹,附了完整小例子程式碼,介紹了一部分函式概念,但是對我這樣的新手來說,程式碼中涉及的部分函式還是無法一下子全部理解。於是在本文中將對程式碼中使用的函式繼續進行一一介紹。 具體程式碼見上一篇(二) 一、 #定義輸入的placehoder,x是特徵

神經網路課程筆記-實際應用第三、四周

所插入的圖片仍然來源於吳恩達老師的課件。 第三週 目標檢測 1. 物件的分類與定位,在輸出層不僅輸出類別,還應輸出包含物體的邊界框(bx,by,bh,bw),從而達到定位的目的。注意網路的輸出(例如下圖的輸出就有是否為目標,邊界框的引數,以及是哪類的判斷)和損失函式的定義

神經網路 + 機器視覺: L10_RNN_LSTM (斯坦福CS231n

完整的視訊課堂連結如下: 完整的視訊課堂投影片連線: 前一課堂筆記連結: RNN 是一個包含非常廣泛的應用領域與知識範圍的一大門類,他的全名又叫做 Recurrent Neural Network,也是神經網路的一種,但是差別就在於 RNN 讓神經網路中的節點(node

第4門課程-神經網路-第四周作業(影象風格轉換)

0- 背景 所謂的風格轉換是基於一張Content影象和一張Style影象,將兩者融合,生成一張新的影象,分別兼具兩者的內容和風格。 所需要的依賴如下: import os import sys import scipy.io import scipy