【學習筆記】用VGG16實現貓狗分類

 【學習筆記】用VGG16實現貓狗分類

與前一篇博文不同,這次使用VGG16 來完成貓狗分類。

在項目文件夾中新建VGGClassification.py文件,導入相關工具

from keras.applications.vgg16 import VGG16
from keras.models import Sequential
from keras.layers import Conv2D,MaxPool2D,Activation,Dropout,Flatten,Dense
from keras.optimizers import SGD
from keras.preprocessing.image import ImageDataGenerator,load_img,img_to_array
from keras.models import  load_model
import numpy as np
from matplotlib import pyplot as plt

首先下載VGG16模型

#VGG16模型是使用imagenet數據集訓練出來的
#include_top=False代表只需VGG16模型中的卷積和池化層
#input_shape=(150,150,3):特徵提取
vgg16_model=VGG16(weights='imagenet',include_top=False,input_shape=(150,150,3))

這裏只需要VGG16的卷積層和池化層是因爲原本模型的全連接層是做1000個分類的,而這個貓狗識別只需要兩個分類,所以去掉全連接層重新搭建。運行這行代碼,就會從網上下載模型,在IDE中獲取一般容易失敗。也可以選擇複製鏈接在網頁中下載,或者其他渠道,但下載好的模型要放在C:\Users\Administrator\.keras\models 這個路徑下。我是在程序中下載的:

因爲我們已經獲取到了VGG16的卷積層和池化層,接下來搭建全連接層:

#搭建全連接層
top_model=Sequential()
top_model.add(Flatten(input_shape=vgg16_model.output_shape[1:]))#圖片輸出四維,1代表數量
top_model.add(Dense(256,activation='relu'))
top_model.add(Dropout(0.5))
top_model.add(Dense(2,activation='softmax'))

創建訓練模型

#把VGG16和全連接層整合
model=Sequential()
model.add(vgg16_model)
model.add(top_model)

接下來的內容和上一篇博文幾乎一樣,只是把優化器改爲SGD

#數據增強
train_datagen=ImageDataGenerator(
    rotation_range=40,#隨機旋轉度數
    width_shift_range=0.2,#隨機水平平移
    height_shift_range=0.2,#隨機豎直平移
    rescale=1/255,#數據歸一化
    shear_range=0.2,#隨機裁剪
    zoom_range=0.2,#隨機放大
    horizontal_flip=True,#水平翻轉
    fill_mode='nearest',#填充方式
)
test_datagen=ImageDataGenerator(
    rescale=1/255,#數據歸一化
)

batch=32#每次訓練傳入32張照片

#生成訓練數據
train_generator=train_datagen.flow_from_directory(
    'images/training_set',#從訓練集這個目錄生成數據
    target_size=(150,150),#把生成數據大小定位150*150
    batch_size=batch,
)
#測試數據
test_generator=test_datagen.flow_from_directory(
    'images/test_set',#從訓練集這個目錄生成數據
    target_size=(150,150),#把生成數據大小定位150*150
    batch_size=batch,
)
#查看定義類別分類
print(train_generator.class_indices)
#定義優化器、代價函數、訓練過程中計算準確率
model.compile(optimizer=SGD(lr=1e-4,momentum=0.9),loss='categorical_crossentropy',metrics=['accuracy'])
#傳入生成的訓練數據、每張圖片訓練1次,驗證數據爲生成的測試數據
model.fit_generator(train_generator,epochs=1,validation_data=test_generator)

訓練結果:

D:\Anaconda\envs\Tensorflow\python.exe "E:/cat_dog recognition/VGGClassification.py"
Using TensorFlow backend.
2020-04-07 16:19:21.125956: I tensorflow/core/platform/cpu_feature_guard.cc:145] This TensorFlow binary is optimized with Intel(R) MKL-DNN to use the following CPU instructions in performance critical operations:  AVX AVX2
To enable them in non-MKL-DNN operations, rebuild TensorFlow with the appropriate compiler flags.
2020-04-07 16:19:21.127107: I tensorflow/core/common_runtime/process_util.cc:115] Creating new thread pool with default inter op setting: 4. Tune using inter_op_parallelism_threads for best performance.
Found 3873 images belonging to 2 classes.
Found 1018 images belonging to 2 classes.
{'cats': 0, 'dogs': 1}
Epoch 1/1

  1/122 [..............................] - ETA: 2:20:26 - loss: 0.7548 - accuracy: 0.6250
  2/122 [..............................] - ETA: 1:35:16 - loss: 0.8686 - accuracy: 0.5312
  3/122 [..............................] - ETA: 1:13:30 - loss: 0.8074 - accuracy: 0.5417
121/122 [============================>.] - ETA: 15s - loss: 0.6540 - accuracy: 0.6228
122/122 [==============================] - 2123s 17s/step - loss: 0.6539 - accuracy: 0.6230 - val_loss: 0.4662 - val_accuracy: 0.8075

訓練過程會比之前的慢,因爲VGG16結構比自己寫的要複雜。可以看到,起初的準確率是50%左右,訓練完成達到了80%,這裏主要看測試集的準確率。如果訓練週期次數多,準確率可以達到90%以上。

接下來保存訓練好的模型:

#保存模型
model.save('model_vgg.h5')

在文件夾中顯示

測試

和前一篇的程序也是一樣的,分別用兩個模型測試一張圖片

label=np.array(['cat','dog'])
#載入模型
#model=load_model('model_cnn.h5')
model=load_model('model_vgg.h5')
#導入圖片
image=load_img('images/test_set/dogs/dog.4024.jpg')
plt.imshow(image)
plt.show()
image=image.resize((150,150))
image=img_to_array(image)
image=image/255
image=np.expand_dims(image,0)
print(image.shape)
print(label[model.predict_classes(image)])

運行結果:

用隨便寫的模型輸出是cat:

用VGG16輸出就是dog:

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章