前言
github
上开源的成熟案例,大多是基于Pytorch
或tf1.x
的框架实现的,tf2.x
的案例不多,而且文档资料也有限,作为实战新人,看到官网都升级到2.x
了,也没有必要过多的纠结老版本了,看一些相关介绍,tf2.x
用到很多keras
的代码,看上去通俗易懂些,所以,就直接入手2.x
版本了,并借助CSDN
的平台记录下学习心得,也更好的为初学者提供点借鉴资料。
既然是实战,所以,在这里,介绍的API
以及Python
相关的会多点,原理性质的会有所涉及,但不会过多的介绍。
一、文章是什么?
如果你啥也不懂,就想了解下DL
,你也可以看看这个博客;
如果你就是想凑凑热闹,那也可以了解下;
如果你看过CNN
的相关理论,但还是一头雾水,不知该如何下手,那这个文章是比较适合你的;
如果你了解的东西也挺多的,但现在给你一堆图片需要进行分类,那强烈建议你看看这个文章。
二、流程介绍
对于一般性的训练,主要分为以下几个过程:
- 读取数据:从本地读取图片以及标注信息,并按照一定的规则进行存储
- 数据预处理:比如图片分辨率修改,数据增强处理等
- 模型搭建:简单来说就是搭建起你的
CNN
网络 - 编译与训练:训练模型
对于预测来讲,主要过程如下:
- 读取模型:将训练好的模型读取进来
- 待识别图片读取与预处理:更改图片分辨率等操作
- 预测:识别图片中的信息
三、模型训练
3.1数据准备
在本地硬盘上准备好数据,其结构关系如下所示:
文件格式 ---data ----train ----Cat ----*.jpg/png ----Dog ----*.jpg/png ----validation ----Cat ----*.jpg/png ----Dog ----*.jpg/png ----test ----*.jpg/png
其中,猫狗的数据集来自于网上的猫狗识别数据集,很容易下载的。
数据准备好了,下面看下代码,先导入一系列所需要的包:
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
import numpy as np
import glob
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from PIL import Image
import matplotlib.pyplot as plt
import os
好的,截止目前为止,准备工作已经ok了,下面就开始正题了:
# 设置计算是否使用GPU,可以不用此设置
gpus = tf.config.list_physical_devices("GPU")
if gpus:
gpu0 = gpus[0]
tf.config.experimental.set_memory_growth(gpu0, True)
tf.config.set_visible_devices([gpu0], "GPU")
# 设置训练时相关参数
width = 200 # 图像分辨率
height = 200 #图像分辨率
channel = 3 #图像通道数
num_classes = 2 #分类个数
bt = 32 #batch_size 一次性加载图片的数量
说一下几个重要点的参数:
num_classes
:表示分类个数,比如,猫狗识别就是二分类,要么是猫要么是狗,所以在这里设置为2,如果是分辨花(向日葵,玫瑰等,官网示例),则需要设置为5。
bt = 32
: batch_size
一次性加载图片的数量,如果电脑配置好点,就设置的大点,如果配置低,就将此值设置的小点。
3.1数据预处理
Keras
已经集成了数据读取与处理相关的API
,只需要调节
#指定数据路径
train_dir = "./data/flower_photos/"
# 实现图像的增强功能
train_datagen = keras.preprocessing.image.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', # constant, reflect, wrap
)
#读取数据
train_generator = train_datagen.flow_from_directory(
train_dir,
target_size=(200, 200),
batch_size=bt,
seed=7,
shuffle=True,
class_mode='categorical',
# save_to_dir = saved_to_dir,
save_prefix='gen',
save_format='jpg'
)
上述实现从文件中读取图片,其中ImageDataGenerator
的函数是定义如何对图像进行操作,如像素值缩放,旋转,平移,缩放等,当然,如果采用一切从简的思想,只需要定义rescale=1/255
即可。flow_from_directory
则实现对每一个图片进行上述相关的处理,同时,也要设定生成图片的分辨率target_size
,训练切片大小batch_size
等相关参数。
同样的,对于validation
文件,可以做同样的处理:
valid_datagen = keras.preprocessing.image.ImageDataGenerator(
rescale=1. / 255,
)
valid_dir = "./data/validation-1/"
valid_generator = valid_datagen.flow_from_directory(
valid_dir,
target_size=(200, 200),
batch_size=bt,
seed=7,
shuffle=False,
class_mode="categorical"
)
3.3模型搭建
tf2.x
在搭建模型方面确实比tf1.x
要好很多,至少是在搭建顺序模型的时候是这样的,目前我也只接触这些简单的模型,所以不做过多评价.
本次模型是采用的经典的Lenet_5
的模型,模型的网络结构网上很多,不做过多的赘述,看下实现代码:(ps:
# 搭建模型
model = keras.models.Sequential([
keras.layers.Conv2D(filters=32, kernel_size=3,
padding='same', activation='relu',
input_shape=[width, height, channel]),
keras.layers.Conv2D(filters=32, kernel_size=3,
padding='same', activation='relu'),
keras.layers.MaxPool2D(pool_size=2),
keras.layers.Conv2D(filters=64, kernel_size=3,
padding='same', activation='relu'),
keras.layers.Conv2D(filters=64, kernel_size=3,
padding='same', activation='relu'),
keras.layers.MaxPool2D(pool_size=2),
keras.layers.Conv2D(filters=128, kernel_size=3,
padding='same', activation='relu'),
keras.layers.Conv2D(filters=128, kernel_size=3,
padding='same', activation='relu'),
keras.layers.MaxPool2D(pool_size=2),
keras.layers.Flatten(),
keras.layers.Dense(128, activation='relu'),
keras.layers.Dense(num_classes, activation='softmax')
])
3.4编译与训练
编译
这个概念目前没有过多的私人感悟,从API
上来看,就是设置下损失函数(可以设置,也可以自己编写,目前本着一切从简的思路学习,还没有学习怎么定义损失函数,后期会陆续增加)与优化器;训练的过程比较简单,就是让计算机跑
就行了。
# 模型编译
model.compile(loss='categorical_crossentropy',
optimizer='adam', metrics=['accuracy'])
model.summary()
# 模型训练
epochs = 10
history = model.fit(
train_generator,
epochs=epochs,
# validation_data = valid_generator,
)
model.save('f_model.h5')
截止到这里,整个训练过程已经讲解完了,最后一句save
就是把训练的模型保存下来。
四、模型预测
相对于模型训练而言,模型预测功能简单的多,根据功能需求,模型预测的话,主要是针对两种对象,一个是针对于单张图片,另一个是针对于一组图片:
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
import numpy as np
import glob
from tensorflow.keras.preprocessing.image import ImageDataGenerator
import cv2
# import matplotlib.pyplot as plt
from PIL import Image
width = 200
height = 200
channel = 3
相对标准化的流程,需要注意的是,width, height, channel
需要与训练时候的参数保持一致。
下面看一下预测一组图片的代码:
# 预测批量图片
def predict_files(path, model):
valid_datagen = keras.preprocessing.image.ImageDataGenerator(
rescale=1. / 255,
)
# valid_dir = "./data/test-1"
valid_generator = valid_datagen.flow_from_directory(
path,
target_size=(width, height),
batch_size=100,
# save_to_dir='./Test',
# save_prefix='t_',
)
#for it in range(len(valid_generator)):
# valid_generator.next()
p = model.predict_generator(valid_generator, verbose = 1)
i = 1
for it in p:
# print(it)
if it.argmax() == 0:
str = '第{}张图为:'.format(i) + 'dog'
print(str)
else:
str = '第{}张图为:'.format(i) + 'cat'
print(str)
i = i + 1
上述代码与在训练阶段的数据预处理有点相似,在使用时,只需要修改下valid_dir
就可以了。
预测单张图片的过程更简单,但是过程有点曲折,折腾了接近一周才实现了此功能:
# 预测单张图片
def predict_file(path, model):
img = cv2.imread(path)
img = cv2.resize(img, (200, 200))
img = img.reshape(1, width, height, channel)
img = img / 255.0
c = model.predict(img)
print(c)
重点还是在图片的预处理上,一定要保证图片的width, height, dim
是一致的。
总结
本文已经记录了从图片准备到训练以及后期图片预测的流程,如果还是没有看明白的话,可以在以下网址下载资源:
基于tf2.x的猫狗识别代码下载