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
深度學習入門——利用卷積神經網路訓練CIFAR—10資料集
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