# 定义一个包含dropout的新卷积神经网络
# 定义一个包含dropout的新卷积神经网络
from keras import layers
from keras import models
model = models.Sequential()
model.add(layers.Conv2D(32, (3, 3), activation='relu',
input_shape=(150, 150, 3)))
model.add(layers.MaxPool2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.MaxPool2D((2, 2)))
model.add(layers.Conv2D(128, (3, 3), activation='relu'))
model.add(layers.MaxPool2D((2, 2)))
model.add(layers.Conv2D(128, (3, 3), activation='relu'))
model.add(layers.MaxPool2D((2, 2)))
model.add(layers.Flatten())
model.add(layers.Dropout(0.5)) # 添加dropout正则化
model.add(layers.Dense(512, activation='relu'))
model.add(layers.Dense(1, activation='sigmoid'))
from keras import optimizers
model.compile(loss='binary_crossentropy',
optimizer=optimizers.RMSprop(lr=1e-4),
metrics=['acc'])
添加 Dropout 层,进一步降低过拟合。
# 利用数据增强生成器训练卷积神经网络
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, # 布尔值,随机水平翻转。
)
test_datagen = ImageDataGenerator(rescale=1./255) # 注意,不能增强验证数据
train_generator = train_datagen.flow_from_directory(
train_dir, # 目标目录
target_size=(150, 150), # 将所有图像大小调整为 150*150
batch_size=32, # 批量数据尺寸(默认:32)
class_mode='binary' # 因为使用了binary_crossentropy损失,索引使用1D二进制标签
)
validation_generator = test_datagen.flow_from_directory(
validation_dir,
target_size=(150, 150),
batch_size=32,
class_mode='binary'
)
history = model.fit_generator(
train_generator,
steps_per_epoch=100,
epochs=100,
validation_data=validation_generator,
validation_steps=50
)
model.save('cats_and_dogs_small_2.h5') # 模型保存,5.4节用
# 绘制训练过程中的损失曲线和精度曲线
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()
进一步使用正则化以及调节网络参数(卷积层过滤器个数或网络的层数),可以得到更高的训练精度,可到87%。但由于数据太少,再想提高精度不容易。需要使用预训练的模型。
呵呵呵呵呵呵呵呵呵呵呵