在上一篇博客:數據挖掘入門系列教程(十一點五)之CNN網絡介紹中,介紹了CNN的工做原理和工做流程,在這一篇博客,將具體的使用代碼來講明如何使用keras構建一個CNN網絡來對CIFAR-10數據集進行訓練。html
若是對keras不是很熟悉的話,能夠去看一看官方文檔。或者看一看我前面的博客:數據挖掘入門系列教程(十一)之keras入門使用以及構建DNN網絡識別MNIST,在數據挖掘入門系列教程(十一)這篇博客中使用了keras構建一個DNN網絡,並對keras的作了一個入門使用介紹。python
CIFAR-10數據集是圖像的集合,一般用於訓練機器學習和計算機視覺算法。它是機器學習研究中使用比較廣的數據集之一。CIFAR-10數據集包含10 種不一樣類別的共6w張32x32彩色圖像。10個不一樣的類別分別表明飛機,汽車,鳥類,貓,鹿,狗,青蛙,馬,輪船 和卡車。每一個類別有6,000張圖像git
在keras剛好提供了這些數據集。加載數據集的代碼以下所示:github
from keras.datasets import cifar10 (x_train, y_train), (x_test, y_test) = cifar10.load_data() print(x_train.shape, 'x_train samples') print(x_test.shape, 'x_test samples') print(y_train.shape, 'y_trian samples') print(y_test.shape, 'Y_test samples')
輸出結果以下:算法
訓練集有5w張圖片,測試集有1w張圖片。在\(x\)數據集中,圖片是\((32,32,3)\),表明圖片的大小是\(32 \times 32\),爲3通道(R,G,B)的圖片。網絡
咱們能夠稍微的展現一下圖片的內容,python代碼以下所示:機器學習
import matplotlib.pyplot as plt %matplotlib inline plt.figure(figsize=(12,10)) x, y = 8, 6 for i in range(x*y): plt.subplot(y, x, i+1) plt.imshow(x_train[i],interpolation='nearest') plt.show()
下面就是數據集中的部分圖片:ide
一樣,咱們須要將類標籤進行one-hot編碼:學習
import keras # 將類向量轉換爲二進制類矩陣。 y_train = keras.utils.to_categorical(y_train, 10) y_test = keras.utils.to_categorical(y_test, 10)
實際上這一步還有不少牛逼(騷)操做,好比說對數據集進行加強,變換等等,這樣均可以在必定程度上提升模型的魯棒性,防止過擬合。這裏咱們就怎麼簡單怎麼來,就只對數據集標籤進行one-hot編碼就好了。測試
構建的網絡模型代碼以下所示:
from keras.models import Sequential from keras.layers import Dense, Dropout, Activation, Flatten,Conv2D, MaxPooling2D # 構建CNN網絡 model = Sequential() # 添加捲積層 model.add(Conv2D(32, (3, 3), padding='same',input_shape=x_train.shape[1:])) # 添加激活層 model.add(Activation('relu')) model.add(Conv2D(32, (3, 3))) model.add(Activation('relu')) # 添加最大池化層 model.add(MaxPooling2D(pool_size=(2, 2))) model.add(Dropout(0.25)) model.add(Conv2D(64, (3, 3), padding='same')) model.add(Activation('relu')) model.add(Conv2D(64, (3, 3))) model.add(Activation('relu')) model.add(MaxPooling2D(pool_size=(2, 2))) model.add(Dropout(0.25)) # 將上一層輸出的數據變成一維 model.add(Flatten()) # 添加全鏈接層 model.add(Dense(512)) model.add(Activation('relu')) model.add(Dropout(0.5)) model.add(Dense(10)) model.add(Activation('softmax')) # 網絡模型的介紹 print(model.summary())
這裏解釋一下代碼:
Conv2D表明2D的卷積層,可能這裏會有人問,個人圖片不是3通道(RGB)的嗎?爲何使用的是Conv2D而不是Conv3D。首先先說明,在Conv2D中的這個「2」表明的是卷積層能夠在兩個維度(也就是width,length)進行移動。那麼同理Conv3D中的「3」表明這個卷積層能夠在3個維度進行移動(好比說視頻中的width ,length,time)。那麼針對RGB這種3通道(channels),卷積過程當中輸入有多少個通道,則濾波器(卷積核)就有多少個通道。
簡單點來講就是:
輸入
單色圖片的input,是2D, \(w \times h\)
彩色圖片的input,是3D,\(w \times h \times channels\)
卷積核filter
單色圖片的filter,是2D, \(w \times h\)
彩色圖片的filter,是3D, \(w \times h \times channels\)
值得注意的是,卷積以後的結果是二維的。(由於會將3維卷積獲得的結果進行相加)
接着繼續解釋Conv2D
的參數:
Conv2D(32, (3, 3), padding='same',input_shape=x_train.shape[1:])
32
表示的是輸出空間的維度(也就是filter濾波器的輸出數量)(3,3)
表明的是卷積核的大小strides
(這裏沒有用到):這個表明是滑動的步長。input_shape
:輸入的維度,這裏是(28,28,3)padding
在上一篇博客介紹過,在keras中有兩個取值:"valid"
或 "same"
(大小寫敏感)。
Flatten這一層就是爲了將多維數據變成一維數據:
from keras.optimizers import RMSprop # 利用 RMSprop 來訓練模型。 model.compile(loss='categorical_crossentropy', optimizer=RMSprop(), metrics=['accuracy'] )
其餘的參數在上兩篇博客中已經講了,就再也不贅述。
這裏你們能夠根據本身的電腦配置適當調整一下batch_size的大小。
history = model.fit(x_train, y_train, batch_size=32, epochs=64, verbose=1, validation_data=(x_test, y_test) )
在i5-10代u,mx250的狀況下,訓練一輪大概須要27s左右。
訓練完成以後,進行評估:
score = model.evaluate(x_test, y_test, verbose=0) print('Test loss:', score[0]) print('Test accuracy:', score[1])
結果以下所示:
這個結果能夠說的上是一言難盡,😔。
import matplotlib.pyplot as plt # 繪製訓練過程當中訓練集和測試集合的準確率值 plt.plot(history.history['accuracy']) plt.plot(history.history['val_accuracy']) plt.title('Model accuracy') plt.ylabel('Accuracy') plt.xlabel('Epoch') plt.legend(['Train', 'Test'], loc='upper left') plt.show() # 繪製訓練過程當中訓練集和測試集合的損失值 plt.plot(history.history['loss']) plt.plot(history.history['val_loss']) plt.title('Model loss') plt.ylabel('Loss') plt.xlabel('Epoch') plt.legend(['Train', 'Test'], loc='upper left') plt.show()
最終在batch_size=1024
的狀況下(爲何不用代碼中batch_size=32
的那張圖呢?由於那張圖沒有保存,而我實在是不想再訓練等那麼久了。)
總的來講效果不是很好,由於我就是用最基本的網絡結構,用的圖片也沒有進行其餘處理。不過原本這篇博客就是爲了簡單的介紹如何使用keras搭建一個cnn網絡,效果差一點就差一點吧。若是想獲得更好的效果,kaggle歡迎你們。
項目地址:Github