目录
一、人脸微笑识别
1.准备工作
需要安装tensorflow、keras以及dlib。
2.genki4k笑脸数据集准备
下载图像数据集genki4k.tar,把它解压到相应的目录(我的目录是在jupyter工作目录下的GENKI4K-datasets目录下)
可以看到里面有些许不合格的数据,我们需要将其剔除。
导入需要的包
import keras #导入人工神经网络库
import matplotlib.pyplot as plt # matplotlib进行画图
import matplotlib.image as mpimg # # mpimg 用于读取图片
import numpy as np # numpy操作数组
from IPython.display import Image #显示图像
import os #os:操作系统接口
划分数据集
(在GENKI4K-dataset同级目录下会产生一个GENKI4K-data的文件夹,包括 train :训练集;validation:验证集;test:测试集。)
# 原目录的路径
original_dataset_dir = 'GENKI4K-datasets'
# 结果路径,存储较小的数据集
base_dir = 'GENKI4K-data'
os.mkdir(base_dir)
# 训练目录,验证和测试拆分
train_dir = os.path.join(base_dir, 'train')
os.mkdir(train_dir)
validation_dir = os.path.join(base_dir, 'validation')
os.mkdir(validation_dir)
test_dir = os.path.join(base_dir, 'test')
os.mkdir(test_dir)
# 训练微笑图片目录
train_smile_dir = os.path.join(train_dir, 'smile')
os.mkdir(train_smile_dir)
# 训练没微笑图片目录
train_unsmile_dir = os.path.join(train_dir, 'unsmile')
#s.mkdir(train_dogs_dir)
# 验证的微笑图片目录
validation_smile_dir = os.path.join(validation_dir, 'smile')
os.mkdir(validation_smile_dir)
# 验证的没微笑图片目录
validation_unsmile_dir = os.path.join(validation_dir, 'unsmile')
os.mkdir(validation_unsmile_dir)
# 测试的微笑图片目录
test_smile_dir = os.path.join(test_dir, 'smile')
os.mkdir(test_smile_dir)
# 测试的没微笑图片目录
test_unsmile_dir = os.path.join(test_dir, 'unsmile')
os.mkdir(test_unsmile_dir)
分配数据集,可以使用人为划分和代码划分
进行一次检查,计算每个分组中有多少张照片(训练/验证/测试)
print('total training smile images:', len(os.listdir(train_smile_dir)))
print('total training unsmile images:', len(os.listdir(train_umsmile_dir)))
print('total testing smile images:', len(os.listdir(test_smile_dir)))
print('total testing unsmile images:', len(os.listdir(test_umsmile_dir)))
print('total validation smile images:', len(os.listdir(validation_smile_dir)))
print('total validation unsmile images:', len(os.listdir(validation_unsmile_dir)))
有2400个训练图像,然后是600个验证图像,1200个测试图像,其中每个分类都有相同数量的样本,是一个平衡的二元分类问题,意味着分类准确度将是合适的度量标准。
3.网络模型
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.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(128, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(128, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Flatten())
model.add(layers.Dense(512, activation='relu'))
model.add(layers.Dense(1, activation='sigmoid'))
model.summary()
在编译步骤里,使用RMSprop优化器。由于用一个单一的神经元(Sigmoid的激活函数)结束了网络,将使用二进制交叉熵(binary crossentropy)作为损失函数
from keras import optimizers
model.compile(loss='binary_crossentropy',
optimizer=optimizers.RMSprop(lr=1e-4),
metrics=['acc'])
4.数据预处理
from keras.preprocessing.image import ImageDataGenerator
# 所有的图像将重新进行归一化处理 Rescaled by 1./255
train_datagen = ImageDataGenerator(rescale=1./255)
validation_datagen=ImageDataGenerator(rescale=1./255)
test_datagen = ImageDataGenerator(rescale=1./255)
# 直接从目录读取图像数据
train_generator = train_datagen.flow_from_directory(
# 训练图像的目录
train_dir,
# 所有图像大小会被转换成150x150
target_size=(150, 150),
# 每次产生20个图像的批次
batch_size=20,
# 由于这是一个二元分类问题,y的label值也会被转换成二元的标签
class_mode='binary')
# 直接从目录读取图像数据
validation_generator = test_datagen.flow_from_directory(
validation_dir,
target_size=(150, 150),
batch_size=20,
class_mode='binary')
test_generator = test_datagen.flow_from_directory(test_dir,
target_size=(150, 150),
batch_size=20,
class_mode='binary')
for data_batch, labels_batch in train_generator:
print('data batch shape:', data_batch.shape)
print('labels batch shape:', labels_batch)
break
输出结果的0(笑脸)和1(非笑脸)
train_generator.class_indices
5.开始训练
epochs值为训练轮数
history = model.fit_generator(
train_generator,
steps_per_epoch=120,
epochs=10,
validation_data=validation_generator,
validation_steps=50)
训练集中共有1200张,选择10轮训练,每轮120张
训练完后将模型保存下来
model.save('GENKI4K-data/smileAndUnsmile_1.h5')
使用图表来绘制在训练过程中模型对训练和验证数据的损失(loss)和准确性(accuracy)数据
6.数据增强
datagen = ImageDataGenerator(
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')
查看增强后的图片例子
import matplotlib.pyplot as plt
# 图像预处理功能模块
from keras.preprocessing import image
# 取得训练数据集中微笑的图片列表
fnames = [os.path.join(train_smile_dir, fname) for fname in os.listdir(train_smile_dir