训练模型
在项目中,我们可能没那么多时间去思考从算法方面去解决,更多的时候想的是能用就行,但是网上很多的例子很多是基于内置的数据,这是非常让人难受的,或者是基于一张图片进行数据增强,很痛苦。更一般的情况是,对训练集下的某一个文件夹的所有图片进行数据增强。
因此需要下面这两个函数:
首先介绍两个函数一个是图片读取ImageDataGenerator()。
这是详细介绍。
还有一个就是ImageDataGenerator里的flow_from_directory()。
详细介绍。
第一个是定义一个生成器,第二个是使用生成器真正处理,操作数据。
由于计算机内存限制,没有办法将所有数据都读入到内存来训练神经网络。因此需要用到model的fit_generator()。他的参数不是fit的x_train和y_train,而是generator。并且数据多的时候会一点点的读入数据,提高运行速度。
Keras中Flatten层的作用。
评价函数:和损失函数相似,但是结果不会影响模型(可用函数请点击链接进官方文档查看)。
数据地址:百度网盘,提取码:gfq8(如果过期请评论我更新)。
详细的在代码中讲
# -*- coding: utf-8 -*-
"""
Created on Sun Dec 22 09:51:41 2019
@author: acm
"""
from keras.preprocessing.image import ImageDataGenerator
from keras.layers import Conv2D, MaxPooling2D, Dense, Flatten
from keras.models import Sequential
from keras import optimizers
train_dir = r'C:\Users\acm\Desktop\data\train' #训练集地址,根据自己下载位置进行更改
test_dir = r'C:\Users\acm\Desktop\data\test' #测试集地址
#构建训练集数据的generator
train_pic_gen = ImageDataGenerator(rescale=1./255, #像素缩到0-1之间
rotation_range=20, #数据随机转动角度
width_shift_range=0.2, #图片水平偏移的角度
height_shift_range=0.2, #图片数值偏移的角度
shear_range=0.2, #剪切强度
zoom_range=0.2, #随机缩放的幅度
horizontal_flip=True, #时候进行随机水平翻转
fill_mode='nearest') #进行变换时,超出边界的点的处理方式
#构建测试集数据的generator
test_pic_gen = ImageDataGenerator(rescale=1./255)
#生成训练集数据
train_flow = train_pic_gen.flow_from_directory(train_dir,
target_size=(224, 224),
batch_size=64,
class_mode='binary')
#生成测试集数据
test_flow = test_pic_gen.flow_from_directory(test_dir,
target_size=(224, 224),
batch_size=64,
class_mode='binary')
#输出一下图片的分类,由于数据中分为了两个文件夹,他会自动把一个文件夹看作一个类
print(train_flow.class_indices)
#构造模型
model = Sequential()
#加卷积层,activation在卷积神经网络中基本上都用relu
model.add(Conv2D(32, (3, 3), activation='relu', input_shape=(224, 224, 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(Dense(512, activation='relu'))
model.add(Dense(1, activation='sigmoid'))
#配置训练模型,分别为损失函数,优化程序使用keras中自带的optimizers,步长设置好,评价函数使用acc
model.compile(loss='binary_crossentropy', optimizer=optimizers.RMSprop(lr=1e-4), metrics=['acc'])
#训练数据,保存模型
history = model.fit_generator(
train_flow,
steps_per_epoch=100,
epochs=30,
validation_data=test_flow,
validation_steps=50)
model.save('cat_and_dog.h5')
#画出结果
import matplotlib.pyplot as plt
#查看变量,发现history.history中就只有这四个值,分别是准确度,验证集准确度,损失,验证集损失
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.figure(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.savefig('acc.png')
plt.show()
#损失
plt.figure(2)
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.savefig('loss.png')
plt.show()
验证模型
模型的训练使用了cv2库,如果没有先安装一个opencv库在进行测试,当然别的也可以。
测试的图片在train目录下有三张,你也可以自己下载并测试。
# -*- coding: utf-8 -*-
"""
Created on Sun Dec 22 11:05:28 2019
@author: acm
"""
from keras.models import load_model
import cv2
model = load_model('cat_and_dog.h5') #引入模型,上面的代码运行后,模型就在你的保存代码的目录下,可以自己修改地址
model.summary() #显示一下模型形状
image = cv2.imread(r'C:\Users\acm\Desktop\data\3.jpg') #读取测试图片
image = cv2.resize(image, (224, 224)) #将测试图片缩小
image = image.reshape(1, 224, 224, 3) #把图片转换成模型输入的维度
print('识别为:')
predict = model.predict_classes(image)
if (predict[0] == 0):
print('A cat')
else:
print('A dog')
#展示图片
images = image
images = images.reshape(224, 224, 3)
cv2.imshow('Image1', images)
cv2.waitKey(0)