#使用vgg模型的第二种方法:载入vgg模型文件还原模型,让后将这个模型
#包含到自己的模型中,构建分类模型重新训练得到一个全新的模型保存文件。
#计算量很大CPU不可算出,精度97%。
from keras.applications import vgg16
conv_base = vgg16.VGG16(weights='imagenet',#指定模型初始化的权重检测点
include_top=False,#模型最后是否包含密集连接分类器.
#后添加的层在顶部
input_shape=(150,150,3)#图像的形状,默认可以处理任意形状
)
#下载文件到C:\Users\Administrator\.keras\models\vgg16_weights_tf_dim_ordering_tf_kernels_notop.h5
import os
import numpy as np
import json
from keras import callbacks
from keras import models,layers,optimizers
#这个路径是在运行了_5_2中的图片复制部分后又数据的目录
base_dir = 'D:/File/Study/MachineLearning/Python深度学习/练习/vs2017/trainData/cats_and_dogs_samll'
train_dir = os.path.join(base_dir,'train')
validation_dir = os.path.join(base_dir,'validation')
test_dir = os.path.join(base_dir,'test')
history_Dir = '_5_3_2history.json'
history=callbacks.History()
from keras.preprocessing.image import ImageDataGenerator
test_datagen = ImageDataGenerator(rescale=1. / 255)
model={}
if os.path.exists(history_Dir) != True:
#################从头训练vgg模型+自己的分类模型################
model = models.Sequential()
model.add(conv_base)
model.add(layers.Flatten())
model.add(layers.Dense(256,activation='relu'))
model.add(layers.Dense(1,activation='sigmoid'))
print(model.summary())
#_________________________________________________________________
#Layer (type) Output Shape Param #
#=================================================================
#vgg16 (Model) (None, 4, 4, 512) 14714688
#_________________________________________________________________
#flatten_1 (Flatten) (None, 8192) 0
#_________________________________________________________________
#dense_1 (Dense) (None, 256) 2097408
#_________________________________________________________________
#dense_2 (Dense) (None, 1) 257
#=================================================================
#Total params: 16,812,353
#参数总数:1681万个
#Trainable params: 16,812,353
#Non-trainable params: 0
#################################################################
print('This is the number of trainable weights '
'before freezing the conv base:', len(model.trainable_weights))
conv_base.trainable = False#冻结vgg模型防止他的权重改变编译后生效
print('This is the number of trainable weights '
'after freezing the conv base:', len(model.trainable_weights))
##########################使用增强数据参数#########################
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,
fill_mode='nearest')
train_generator = train_datagen.flow_from_directory(train_dir,
target_size=(150,150),
batch_size=20,
class_mode='binary')
validation_generator = test_datagen.flow_from_directory(validation_dir,
target_size=(150,150),
batch_size=20,
class_mode='binary')
#################################################################
model.compile(optimizer=optimizers.RMSprop(lr=2e-5),
loss='binary_crossentropy',
metrics=['acc'])
history = model.fit_generator(train_generator,
steps_per_epoch=100,
epochs=30,
validation_data=validation_generator,
validation_steps=50)
#####################书上说精度约96%:我实测验证精度90%训练11分钟##############
#可能跟我的显存总是不够有关。
####################使用模型微调fineTunning调整卷积基的最后几层################
conv_base.trainable = True
set_trainable = False
for layer in conv_base.layers:
if layer.name == 'block5_conv1':
set_trainable = True
if set_trainable:
layer.trainable = True
else:
layer.trainable = False
model.compile(loss='binary_crossentropy',
optimizer=optimizers.RMSprop(lr=1e-5),
metrics=['acc'])
history = model.fit_generator(
train_generator,
steps_per_epoch=100,
epochs=100,
validation_data=validation_generator,
validation_steps=50)
model.save('_5_3_2.h5')#
###############训练时间太长了,训练一次就存起来方便还原###########
historyStr = json.dumps(history.history)
#history不能直接被序列化
with open(history_Dir, 'w', encoding='utf-8') as f:
f.write(historyStr)
f.close()
else :
#with open(history_Dir, encoding='utf-8') as f:
# history.history = json.load(f)
# f.close()
model=models.load_model('_5_3_2.h5')
####################显示精度曲线和损失曲线,精度到了97%提升了1%#######################
#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, 'bo', label='Training acc')
#plt.plot(epochs, val_acc, 'b', label='Validation acc')
#plt.title('Training and validation accuracy')
#plt.legend()
#plt.figure()
#plt.plot(epochs, loss, 'bo', label='Training loss')
#plt.plot(epochs, val_loss, 'b', label='Validation loss')
#plt.title('Training and validation loss')
#plt.legend()
#plt.show()
######################################################################################
#使得曲线变的平滑
#def smooth_curve(points, factor=0.8):
# smoothed_points = []
# for point in points:
# if smoothed_points:
# previous = smoothed_points[-1]
# smoothed_points.append(previous * factor + point * (1 - factor))
# else:
# smoothed_points.append(point)
# return smoothed_points
#####################################################################################
#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, smooth_curve(acc), 'bo', label='Training acc')
#plt.plot(epochs, smooth_curve(val_acc), 'b', label='Validation acc')
#plt.title('Training and validation accuracy')
#plt.legend()
##################
#plt.figure()
#plt.plot(epochs,smooth_curve(loss), 'bo', label='Training loss')
#plt.plot(epochs, smooth_curve(val_loss), 'b', label='Validation loss')
#plt.title('Training and validation loss')
#plt.legend()
#plt.show()
##没有画出图来,训练时间太长回头再修改
#############################在测试数据上最终评估模型##########################
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)