keras实现猫狗识别模型训练并验证

训练模型

在项目中,我们可能没那么多时间去思考从算法方面去解决,更多的时候想的是能用就行,但是网上很多的例子很多是基于内置的数据,这是非常让人难受的,或者是基于一张图片进行数据增强,很痛苦。更一般的情况是,对训练集下的某一个文件夹的所有图片进行数据增强。
因此需要下面这两个函数:
首先介绍两个函数一个是图片读取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)
  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值