1. 程式人生 > >Keras入門課3 -- 使用CNN識別cifar10資料集

Keras入門課3 -- 使用CNN識別cifar10資料集

Keras入門課3:使用CNN識別cifar10資料集

cifar10是一個日常物品的資料集,一共有10類,屬於是比較小的資料集。這次用一個4個卷積層加2個全連線層的典型CNN網路來進行分類

import keras
from keras.datasets import cifar10
from keras.preprocessing.image import ImageDataGenerator
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation, Flatten
from keras.
layers import Conv2D, MaxPooling2D
Using TensorFlow backend.
/usr/local/Cellar/python3/3.6.2/Frameworks/Python.framework/Versions/3.6/lib/python3.6/importlib/_bootstrap.py:205: RuntimeWarning: compiletime version 3.5 of module 'tensorflow.python.framework.fast_tensor_util' does not match runtime version 3.6
  return f(*args, **kwds)

↓首先載入cifar10資料集,和mnist資料集的載入方法一致,本地沒有資料的話會先下載

(x_train,y_train),(x_test,y_test) = cifar10.load_data()

cifar10資料集影象大小是32*32的3通道彩圖,訓練集5萬張,測試集1萬張。和之前的mnist資料集不同,由於是彩色的,所以樣本直接就是4維的。

print(x_train.shape,y_train.shape)
print(x_test.shape,y_test.shape)
(50000, 32, 32, 3) (50000, 1)
(10000, 32, 32, 3) (10000, 1)
import matplotlib.
pyplot as plt plt.imshow(x_train[0]) plt.show() plt.imshow(x_train[1]) plt.show()

這裡寫圖片描述
這裡寫圖片描述

可以看到資料讀入沒有問題,第一張是蛤蟆,第二張是一個卡車。

↓規範化資料

x_train = x_train/255
x_test = x_test/255
y_train = keras.utils.to_categorical(y_train,10)
y_test = keras.utils.to_categorical(y_test,10)

↓構建模型。之前構建模型都是先生成一個model,然後使用add方法來一層一層的加,現在用另一種更方便的方法。直接在Sequential初始化的時候按陣列一個一個寫進去就可以了。

model = Sequential([
    Conv2D(32,(3,3),padding='same',input_shape=(32,32,3),activation='relu'),
    Conv2D(32,(3,3),activation='relu'),
    MaxPooling2D(pool_size=(2,2)),
    Dropout(0.25),
    
    Conv2D(64,(3,3),padding='same',activation='relu'),
    Conv2D(64,(3,3),activation='relu'),
    MaxPooling2D(pool_size=(2,2)),
    Dropout(0.25),
    
    Flatten(),
    Dense(512,activation='relu'),
    Dropout(0.5),
    Dense(10,activation='softmax')    
])
model.summary()
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_1 (Conv2D)            (None, 32, 32, 32)        896       
_________________________________________________________________
conv2d_2 (Conv2D)            (None, 30, 30, 32)        9248      
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 15, 15, 32)        0         
_________________________________________________________________
dropout_1 (Dropout)          (None, 15, 15, 32)        0         
_________________________________________________________________
conv2d_3 (Conv2D)            (None, 15, 15, 64)        18496     
_________________________________________________________________
conv2d_4 (Conv2D)            (None, 13, 13, 64)        36928     
_________________________________________________________________
max_pooling2d_2 (MaxPooling2 (None, 6, 6, 64)          0         
_________________________________________________________________
dropout_2 (Dropout)          (None, 6, 6, 64)          0         
_________________________________________________________________
flatten_1 (Flatten)          (None, 2304)              0         
_________________________________________________________________
dense_1 (Dense)              (None, 512)               1180160   
_________________________________________________________________
dropout_3 (Dropout)          (None, 512)               0         
_________________________________________________________________
dense_2 (Dense)              (None, 10)                5130      
=================================================================
Total params: 1,250,858
Trainable params: 1,250,858
Non-trainable params: 0
_________________________________________________________________

↓指定優化函式的引數

opt = keras.optimizers.rmsprop(lr=0.0001,decay=1e-6)
model.compile(loss='categorical_crossentropy',
             optimizer=opt,
             metrics=['accuracy'])

至此直接呼叫fit方法就可以進行訓練了。但是為了模型更快的收斂以及更好的泛化效能,往往我們會對影象做一些變換,比如縮放、平移、旋轉等等。下面我們要用keras自帶的影象增強來對影象做一些變換

↓這裡生成了一個數據增強器,包含了範圍20°內的隨機旋轉,±15%的縮放以及隨機的水平翻轉。可調的引數還有很多,具體的可以檢視文件。

datagen = ImageDataGenerator(
    rotation_range = 20,
    zoom_range = 0.15,
    horizontal_flip = True,
)
# datagen.fit(x_train) 只有使用featurewise_center,featurewise_std_normalization或zca_whitening時需要此函式

↓通過ImageDataGenerator生成的資料需要使用model的fit_generator方法來進行訓練,其中的workers引數表示多執行緒運算。

datagen的flow方法可以按批次的生成訓練所需資料,注意這裡生成的資料都是經過了資料增強的,並且是實時的。

model.fit_generator(datagen.flow(x_train,y_train,batch_size=64),steps_per_epoch = 1000,epochs = 2,validation_data=(x_test,y_test),workers=4,verbose=1)
Epoch 1/2
1000/1000 [==============================] - 598s - loss: 1.8554 - acc: 0.3212 - val_loss: 1.5670 - val_acc: 0.4366
Epoch 2/2
1000/1000 [==============================] - 506s - loss: 1.5633 - acc: 0.4319 - val_loss: 1.4035 - val_acc: 0.4967

↓儲存模型,包括了模型的結構以及引數。字尾用h5

model.save('cifar10_trained_model.h5')
scores = model.evaluate(x_test,y_test,verbose=1)
print('Test loss:',scores[0])
print('Test accuracy:',scores[1])
10000/10000 [==============================] - 29s    
Test loss: 1.40354908714
Test accuracy: 0.4967

總結

  1. 學習了一種新的使用Sequential()構建模型的方法,更加的簡單快捷
  2. 學習了使用Keras內建的ImageDataGenerator來做資料增強的方法
  3. 呼叫model的fit_generator來進行鍼對增強資料的訓練
  4. 學習瞭如何儲存模型

參考