一、导包:
import numpy as np
import cv2
from keras.layers import Dense, Dropout, Flatten
from keras.models import Model
from keras.applications.vgg16 import VGG16
import matplotlib.pyplot as plt
#from keras.optimizers import Adam, Adadelta
from sklearn.model_selection import train_test_split
width = 125
二、数据集准备:
width = 125
####################################################################################
'''猫狗数据集'''
n_train = 1000
train_cat = np.zeros((n_train, width, width, 3), dtype = np.float32)
train_cat_label = np.zeros((n_train, 1), dtype=np.uint8)
train_dog = np.zeros((n_train, width, width, 3), dtype = np.float32)
train_dog_label = np.ones((n_train, 1), dtype=np.uint8)
for i in range(n_train):
dog_img = cv2.imread('C:/Users/panansi/Desktop/dc_2000/train/dog/dog.%d.jpg'%i)
dog_img = cv2.resize(dog_img, dsize=(width, width))
train_dog[i] = dog_img / 255.0
cat_img = cv2.imread('C:/Users/panansi/Desktop/dc_2000/train/cat/cat.%d.jpg'%i)
cat_img = cv2.resize(cat_img, dsize=(width, width))
train_cat[i] = cat_img / 255.0
n_test = 500
test_cat = np.zeros((n_test, width, width, 3), dtype = np.float32)
test_cat_label = np.zeros((n_test, 1), dtype=np.uint8)
test_dog = np.zeros((n_test, width, width, 3), dtype = np.float32)
test_dog_label = np.ones((n_test, 1), dtype=np.uint8)
for i in range(n_test):
dog_img = cv2.imread('C:/Users/panansi/Desktop/dc_2000/test/dog/dog.%d.jpg'%(i+n_train))
dog_img = cv2.resize(dog_img, dsize=(width, width))
test_dog[i] = dog_img / 255.0
cat_img = cv2.imread('C:/Users/panansi/Desktop/dc_2000/test/cat/cat.%d.jpg'%(i+n_train))
cat_img = cv2.resize(cat_img, dsize=(width, width))
test_cat[i] = cat_img / 255.0
x_dc_train = np.concatenate((train_dog, train_cat),axis=0)
y_dc_train = np.concatenate((train_dog_label, train_cat_label),axis=0)
x_dc_test = np.concatenate((test_dog, test_cat),axis=0)
y_dc_test = np.concatenate((test_dog_label, test_cat_label),axis=0)
三、训练集/验证集拆分:
x_dc_tra, x_dc_val, y_dc_tra, y_dc_val = train_test_split(x_dc_train, y_dc_train, test_size=0.2)
四、搭建模型:
'''VGG16_Net'''
#def VGG16_Net():
#vgg_model = load_model('C:/Users/xdtech/Desktop/rent/vgg16.h5')
vgg_model = VGG16(weights='imagenet', include_top=False, input_shape = (width, width, 3))
for layer in vgg_model.layers:
layer.trainable = False
cat_model = Flatten()(vgg_model.output)
cat_model = Dense(256, activation='relu')(cat_model)
cat_model = Dropout(0.5)(cat_model)
cat_model = Dense(units=1, activation='sigmoid')(cat_model)
v_model = Model(inputs=vgg_model.input, outputs=cat_model)
这段代码能够成功运行的前提是在C:\Users\panansi.keras\models这个路径下面包含一个叫vgg16_weights_tf_dim_ordering_tf_kernels_notop.h5的文件。
五、训练模型:
'''训练猫狗数据集'''
batch_size = 32
epochs=20
v_model.compile(optimizer = 'adam', loss='binary_crossentropy', metrics=['accuracy'])
h_v = v_model.fit(x_dc_tra, y_dc_tra,
batch_size=batch_size,
epochs=epochs,
validation_data=(x_dc_val,y_dc_val))
六、结果可视化:
plt.figure(figsize=(10,4))
plt.subplot(1, 2, 1)
plt.plot(h_v.history['loss'])
plt.plot(h_v.history['val_loss'])
plt.legend(['loss', 'val_loss'])
plt.ylabel('loss')
plt.xlabel('epoch')
plt.subplot(1, 2, 2)
plt.plot(h_v.history['accuracy'])
plt.plot(h_v.history['val_accuracy'])
plt.legend(['acc', 'val_cc'])
plt.ylabel('acc')
plt.xlabel('epoch')
可视化结果如下:
从图中的训练结果可知:
20个epoch内,训练准确率达到98%,验证集准确率在87%~89%之间。从猫狗数据集的训练结果可以看出,模型是工作的。
测试集结果没有进行,因为只是为了验证模型的可行性。
代码如下:
'''结果评估'''
s = np.arange(x_dc_test.shape[0])
np.random.shuffle(s)
x_dc_test = x_dc_test[s]
y_dc_test = y_dc_test[s]
dc_pre = v_model.evaluate(x_dc_test, x_dc_test)
进行shuffle的原因是打乱数据,因为evaluate的时候数据进入模型的批次是固定的,打乱数据让数据的分布更随机化。
七、总结:当模型在一个数据集上表现非常非常糟糕的时候,可以更换一个数据集训练网络,我用的是小猫狗数据集共2000张训练验证(猫1000, 狗1000)和1000张验证(猫500,狗500)。如果模型在新的数据集上表现还行,而在想要实验的数据集处理表现糟糕,说明是想要实验的数据集处理上存在一些问题,最常见的问题可能是数据标签对应的问题,还有一个是图像数据归一化(像素/255.0)。