一、keras環境配置

二、貓狗影象資料集準備

kaggle官網下載,主要註冊賬號,得科學上網才行:

不能科學上網的同學來百度網盤:

連結:

https://

pan。baidu。com/share/ini

t?surl=3hw4LK8ihR6-6-8mpjLKDA

密碼:dmp4

三、資料集預處理

這個資料集包含25000張貓狗影象(每類有12500 張)。由於我們

機器效能限制性原因

,建立一個新資料集(資料夾),其中包含三個子集:每個類別各1000個樣本的訓練集、每個類別各500個樣本的驗證集和每個類別各500個樣本的測試集。資料集結構為:

dataset

|— train

|— dogs

|— cats

|— validation

|— dogs

|— cats

|— test

|— dogs

|— cats

直接手動將貓狗影象複製貼上到新資料夾下即可,程式碼亦可:

import os

import shutil

original_dataset_dir = r“data\train”

train_cats_dir = r“dataset\train\cats”

validation_cats_dir = r“dataset\validation\cats”

test_cats_dir = r“dataset\test\cats”

train_dogs_dir = r“dataset\train\dogs”

validation_dogs_dir = r“dataset\validation\dogs”

test_dogs_dir = r“dataset\test\dogs”

fnames = [‘cat。{}。jpg’。format(i) for i in range(1000)]

for fname in fnames:

src = os。path。join(original_dataset_dir, fname)

dst = os。path。join(train_cats_dir, fname)

shutil。copyfile(src, dst)

fnames = [‘cat。{}。jpg’。format(i) for i in range(1000, 1500)]

for fname in fnames:

src = os。path。join(original_dataset_dir, fname)

dst = os。path。join(validation_cats_dir, fname)

shutil。copyfile(src, dst)

fnames = [‘cat。{}。jpg’。format(i) for i in range(1500, 2000)]

for fname in fnames:

src = os。path。join(original_dataset_dir, fname)

dst = os。path。join(test_cats_dir, fname)

shutil。copyfile(src, dst)

fnames = [‘dog。{}。jpg’。format(i) for i in range(1000)]

for fname in fnames:

src = os。path。join(original_dataset_dir, fname)

dst = os。path。join(train_dogs_dir, fname)

shutil。copyfile(src, dst)

fnames = [‘dog。{}。jpg’。format(i) for i in range(1000, 1500)]

for fname in fnames:

src = os。path。join(original_dataset_dir, fname)

dst = os。path。join(validation_dogs_dir, fname)

shutil。copyfile(src, dst)

fnames = [‘dog。{}。jpg’。format(i) for i in range(1500, 2000)]

for fname in fnames:

src = os。path。join(original_dataset_dir, fname)

dst = os。path。join(test_dogs_dir, fname)

shutil。copyfile(src, dst)

新的資料集準備好之後,將資料輸入神經網路之前,我們應該

將資料格式化為經過歸一化(神經網路喜歡處理較小的輸入值)、統一尺寸預處理的浮點數張量

。Keras有一個影象處理輔助工具的模組,位於keras。preprocessing。image。其中的ImageDataGenerator 類,可以快速建立Python 生成器,能夠將硬碟上的影象檔案自動轉換為預處理好的張量批次。

from keras。preprocessing。image import ImageDataGenerator

# 將所有影象乘以1/255 縮放

train_datagen = ImageDataGenerator(rescale=1。/255)

validation_datagen = ImageDataGenerator(rescale=1。/255)

train_dir = r“dataset\train”

validation_dir = r“dataset\validation”

train_generator = train_datagen。flow_from_directory(train_dir,

# 將所有影象的大小調整為150×150

target_size=(150, 150),

# 批次大小

batch_size=20,

# 需要用二進位制標籤

class_mode=‘binary’)

validation_generator = validation_datagen。flow_from_directory(validation_dir,

target_size=(150, 150),

batch_size=20,

class_mode=‘binary’)

生成器的輸出:它生成了150×150 的RGB影象[形狀為(20,150, 150, 3)]與二進位制標籤[形狀為(20,)]組成的批次。每個批次中包含20 個樣本(批次大小)。生成器會不停地生成這些批次,它會不斷迴圈目標資料夾中的影象。

學習樣本太少容易導致過擬合

,導致無法訓練出能夠泛化到新資料的模型。如果擁有無限的資料,那麼模型能夠觀察到資料分佈的所有內容,這樣就永遠不會過擬合。

資料增強是從現有的訓練樣本中生成更多的訓練資料

,其方法是利用多種能夠生成可信影象的隨機變換來增加樣本。其目標是,模型在訓練時不會兩次檢視完全相同的影象。這讓模型能夠觀察到資料的更多內容,從而具有更好的泛化能力。在Keras 中,這可以透過對ImageDataGenerator 例項讀取的影象執行多次隨機變換來實現。所以上面的程式碼更改為:

from keras。preprocessing。image import ImageDataGenerator

# 訓練資料增強

train_datagen = ImageDataGenerator(rescale=1。/255,

# 表示影象隨機旋轉的角度範圍

rotation_range=40,

# 影象在水平方向上平移的範圍

width_shift_range=0。2,

# 影象在垂直方向上平移的範圍

height_shift_range=0。2,

# 隨機錯切變換的角度

shear_range=0。2,

# 影象隨機縮放的範圍

zoom_range=0。2,

# 隨機將一半影象水平翻轉

horizontal_flip=True)

# 驗證資料不能增強

validation_datagen = ImageDataGenerator(rescale=1。/255)

train_dir = r“dataset\train”

validation_dir = r“dataset\validation”

train_generator = train_datagen。flow_from_directory(train_dir,

# 將所有影象的大小調整為150×150

target_size=(150, 150),

# 批次大小

batch_size=32,

# 需要用二進位制標籤

class_mode=‘binary’)

validation_generator = validation_datagen。flow_from_directory(validation_dir,

target_size=(150, 150),

batch_size=32,

class_mode=‘binary’)

利用生成器,我們讓模型對資料進行擬合

。我們將使用fit_generator方法來擬合,它在資料生成器上的效果和fit方法相同。

四、定義模型以及模型訓練

定義模型結構,我們採用一個簡單的CNN結構:卷積+池化+卷積+池化+卷積+池化+卷積+池化+Dropout+全連線+全連線:

from keras import models

from keras。layers import Conv2D, MaxPooling2D, Dense, Flatten, Dropout

def model():

model = models。Sequential()

model。add(Conv2D(32, (3, 3), activation=‘relu’, input_shape=(150, 150, 3)))

model。add(MaxPooling2D((2, 2)))

model。add(Conv2D(64, (3, 3), activation=‘relu’))

model。add(MaxPooling2D((2, 2)))

model。add(Conv2D(128, (3, 3), activation=‘relu’))

model。add(MaxPooling2D((2, 2)))

model。add(Conv2D(128, (3, 3), activation=‘relu’))

model。add(MaxPooling2D((2, 2)))

model。add(Flatten())

model。add(Dropout(0。5))

model。add(Dense(512, activation=‘relu’))

model。add(Dense(1, activation=‘sigmoid’))

return model

設定一些模型引數,之後進行模型訓練:

# 初始化模型

model = model()

# 用於配置訓練模型(最佳化器、目標函式、模型評估標準)

model。compile(optimizer = ‘adam’, loss = ‘binary_crossentropy’, metrics=[‘accuracy’])

# 檢視各個層的資訊

model。summary()

# 回撥函式,在每個訓練期之後儲存模型

model_checkpoint = ModelCheckpoint(‘model。hdf5’,#儲存模型的路徑

monitor=‘loss’,#被監測的資料

verbose=1,#日誌顯示模式:0=>安靜模式,1=>進度條,2=>每輪一行

save_best_only=True)#若為True,最佳模型就不會被覆蓋

# 用history接收返回值用於畫loss/acc曲線

history = model。fit_generator(train_generator,

steps_per_epoch=100,

epochs=30,

validation_data=validation_generator,

validation_steps=50)

# 繪製loss,acc

import matplotlib。pyplot as plt

acc = history。history[‘acc’]

val_acc = history。history[‘val_acc’]

loss = history。history[‘loss’]

val_loss = history。history[‘val_loss’]

epochs = range(1, len(acc) + 1)

plt。plot(epochs, acc, ‘r’, label=‘Training acc’)

plt。plot(epochs, val_acc, ‘b’, label=‘Validation acc’)

plt。title(‘Training and validation accuracy’)

plt。legend()

plt。savefig(‘accuracy。png’,dpi=300)

plt。figure()

plt。plot(epochs, loss, ‘r’, label=‘Training loss’)

plt。plot(epochs, val_loss, ‘b’, label=‘Validation loss’)

plt。title(‘Training and validation loss’)

plt。legend()

plt。savefig(‘loss。png’,dpi=300)

plt。show()

10輪過後,訓練集精度acc達到0。8969;驗證集acc: 0。8471。

keras_GPU實現卷積神經網路CNN貓狗影象分類

訓練和驗證資料的loss走向圖

keras_GPU實現卷積神經網路CNN貓狗影象分類

訓練和驗證資料的acc走向圖

五、檢視測試集訓練精度

test_dir = r“dataset\test”

test_datagen = ImageDataGenerator(rescale=1。/255)

test_generator = test_datagen。flow_from_directory(

test_dir,

target_size=(150, 150),

batch_size=20,

class_mode=‘binary’)

test_loss, test_acc = model。evaluate_generator(test_generator, steps=50)

print(‘test acc:’, test_acc)

測試集精度為:0。8370

jupyder檔案:

keras_GPU實現卷積神經網路CNN貓狗影象分類

dogs_and_cats。ipynb

89K

·

百度網盤

參考