Keras深度学习应用1——基于卷积神经网络(CNN)的人脸识别(下)

Keras深度学习应⽤1——基于卷积神经⽹络(CNN)的⼈脸识别(下)
基于CNN的⼈脸识别(下)
,上⼀篇博客已经详细叙述了CNN的理论基础,该篇博客具体叙述使⽤Keras实现⼈脸识别的具体代码。
代码下载
三、⼈脸识别数据
3.1 数据集划分
本实验选取MegaFace⼈脸库中40个⼈的6127张图像作为作为实验数据集,其中训练集4742张,验证集1185张,测试集200张。Name_label =[]#姓名标签
path ='./data/face/'#数据集⽂件路径
dir= os.listdir(path)#列出所有⼈
防静电水磨石
label =0#设置计数器
#数据写⼊
with open('./','w')as f:
for name in dir:
Name_label.append(name)
print(Name_label[label])
after_generate = os.listdir(path +'\\'+ name)
for image in after_generate:
dswith(".png"):
f.write(image +";"+str(label)+"\n")
label +=1
通过上述代码将实验数据集写⼊⽂件中实现数据的迭代读取,减少内存占⽤率,提⾼训练速度。
# 打开数据集的txt
with open(r".\","r")as f:
lines = f.readlines()
#打乱数据集
np.random.seed(10101)
np.random.shuffle(lines)
np.random.seed(None)
# 80%⽤于训练,20%⽤于测试。三维景点
num_val =int(len(lines)*0.2)#
num_train =len(lines)- num_val  #4715
电子管功放电路
通过上述代码实现数据集的划分,并设置随机种⼦使得同类数据不会过度集中影响实验准确率。
3.2 数据增强
通过对原训练集⼈脸图⽚进⾏模糊、旋转、添加噪声制造出多种复杂的“环境”,在原有的数据基础上更⼤的扩充数据量,进⽽提升识别准确率;通过模拟不良的成像环境以及⼲扰,更⼤的强化卷积神经⽹络对不同恶劣条件下进⾏⼈脸识别的适应性,代码如下:
def rand(a=0, b=1):
return np.random.rand()*(b-a)+ a
def get_random_data(image, input_shape, random=True, jitter=.1, hue=.1, sat=1.2, val=1.2, proc_img=True):
h, w = input_shape
new_ar = w/h * rand(1-jitter,1+jitter)/rand(1-jitter,1+jitter)
scale = rand(.7,1.3)
if new_ar <1:
nh =int(scale*h)
nw =int(nh*new_ar)
else:
nw =int(scale*w)
nh =int(nw/new_ar)
image = size((nw,nh), Image.BICUBIC)
# place image
dx =int(rand(0, w-nw))
dy =int(rand(0, h-nh))
new_image = w('RGB',(w,h),(0,0,0))
new_image.paste(image,(dx, dy))
image = new_image
# flip image or not
flip = rand()<.5
if flip:
image = anspose(Image.FLIP_LEFT_RIGHT)
# distort image
hue = rand(-hue, hue)
sat = rand(1, sat)if rand()<.5else1/rand(1, sat)
val = rand(1, val)if rand()<.5else1/rand(1, val)
x = rgb_to_hsv(np.array(image)/255.)
x[...,0]+= hue
x[...,0][x[...,0]>1]-=1
x[...,0][x[...,0]<0]+=1
x[...,1]*= sat
x[...,2]*= val
x[x>1]=1
x[x<0]=0
image_data = hsv_to_rgb(x)*255# numpy array, 0 to 1
return image_data
效果图:
四、搭建CNN⽹络模型
4.1 搭建CNN模型
本⽂搭建的卷积神经⽹络模型如图所⽰,该模型⼀共10层,由1个输⼊层,3个卷积层、3个最⼤池化层、1个Flatten层、1个全连接层和1个Softmax层构成。
⾸先,输⼊层的输⼊数据为⼀个200×200×3的图⽚矩阵,第⼀个卷积层的卷积核为3×3的⼤⼩,默认的滑动步长为1个像素点。矩阵经过卷积核的卷积运算后,形成了⼀个198×198×64的矩阵数据,接下来经过2×2尺⼨、默认滑动步长为2的最⼤池化层进⾏池化处理,特征缩⼩为99×99×64的矩阵数据。
然后,第⼀个最⼤池化层输出的99×99×64的矩阵数据作为第⼆个卷积层的输⼊数据,经过第⼆个3×3尺⼨卷积核、滑动步长为1的卷积层进⾏卷积运算后,得到⼀个97×97×32的矩阵数据,再对该矩阵数据进⾏2×2尺⼨、滑动步长为2的最⼤池化层进⾏池化处理,特征缩⼩为48×48×32的特征矩阵,将该特征矩阵传⼊Dropout层。Dropout层⽤于抑制模型的过度拟合,设置的概率为25%。
在最后⼀层的卷积层和最⼤池化层中,卷积和池化的过程与前两层类似,将48×48×32的特征矩阵与3×3尺⼨卷积核进⾏卷积,得到⼀个46×46×32的矩阵数据,再传⼊2×2尺⼨的最⼤池化层进⾏最⼤池化运算,特征最后缩⼩为23×23×3的特征矩阵,将该矩阵传⼊概率为25%的Dropout层来更新参数。
数据在经过上述的卷积池化过程后,输出的数据是⼀个⼆维向量,⽽模型需要对卷积运算结果进⾏分类,因此需要对该⼆维矩阵降维成⼀维矩阵,这⾥需要⽤到Faltten层,该层的把多维输⼊数据⼀维化,提供了从卷积层到全连接层的过渡作⽤。在这⼀步中,23×23×32的特征矩阵被“压平”成⼀组⼀维矩阵,共计包含16928个特征值,将这些特征值传⼊全连接层。
本⽂设计的全连接层含有128个神经元,将16928个特征值与128个神经元进⾏全连接,经过relu函数激活处理后⽣成128个特征数据,再传⼊概率为50%的Dropout层来做为Softmax层的输⼊数据。
最后,本⽂把全连接层的128个特征数据与分类标签的数量进⾏全连接,经过Softmax层进⾏⼈脸的分类识别。实现代码如下:
def MmNet(input_shape, output_shape):光伏板安装
model = Sequential()# 建⽴模型
# 第⼀层
model.add(Conv2D(64, kernel_size=(3,3), activation='relu', input_shape=input_shape))
model.add(MaxPooling2D(pool_size=(2,2)))
# 第⼆层
model.add(Conv2D(32,(3,3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Dropout(0.25))
# 第三层
model.add(Conv2D(32,(3,3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Dropout(0.25))
# 全连接层
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dropout(0.5))
# 全连接层
model.add(Dense(output_shape, activation='softmax'))
print("-----------模型摘要----------\n")# 查看模型摘要
model.summary()
return model
4.2 模型训练
在训练开始阶段,使⽤遍历的⽅法分别将各个⼦⽬录下的⼈脸图⽚归⼀化为200×200像素,并将图像转换成矩阵的形式读取到内存中,把数据集划分为训练集和测试集,然后分别对训练集和测试集添加⼈脸识别的分类标签。
接下来开始对搭建好的神经⽹络模型进⾏训练,本⽂选取Adam下降法作为优化器,学习率为0.01,利⽤GPU加速的⽅式进⾏训练。将处理好的数据按照集合标签传⼊神经⽹络中,进⾏迭代训练,在每
次迭代过程中对每次训练结果进⾏评估并将训练好的⽹络模型保存到本地以使得迭代不中断。实现代码如下:
#3. 训练模型
def train(model, batch_size):
model = model  #读取模型
#定义保存⽅式,每三代保存⼀次
checkpoint_period1 = ModelCheckpoint(
log_dir +'ep{epoch:03d}-loss{loss:.3f}-val_loss{val_loss:.3f}.h5',
monitor='acc',
save_weights_only=False,
period=3
)
#学习率下降⽅式,acc三次不下降就下降学习率继续训练
reduce_lr = ReduceLROnPlateau(
monitor='val_acc',
patience=3,
verbose=1
)
#val_loss⼀直不下降意味模型基本训练完毕,停⽌训练
early_stopping = EarlyStopping(
monitor='val_loss',
min_delta=0,
patience=10,
verbose=1
)
#交叉熵
钢铁清洗剂
modelpile(loss ='categorical_crossentropy',
optimizer =Adam(lr=1e-4),
metrics=['accuracy'])
#Tebsorboard可视化
tb_Tensorboard = TensorBoard(log_dir="./model", histogram_freq=1, write_grads=True)
#开始训练
history = model.fit_generator(generate_arrays_from_file(lines[:num_train], batch_size,True),
steps_per_epoch=max(1, num_train//batch_size),
validation_data=generate_arrays_from_file(lines[num_train:], batch_size,False),
validation_steps=max(1, num_val//batch_size),
verbose =1,
epochs=10,
initial_epoch=0,
callbacks=[early_stopping, checkpoint_period1, reduce_lr, tb_Tensorboard])
return history, model
4.3 加载需要识别的⼈脸
该节代码实现过程为:加载训练好的神经⽹络模型、加载需要识别的⼈脸图像、识别、将识别结果打印出来并将该⼈脸照⽚显⽰在窗⼝中,窗⼝的标题为该图⽚路径名称,具体代码实现
import os
import glob
import h5py
import keras
import numpy as np
from tkinter import*
from tkinter import ttk
from PIL import Image,ImageTk
dels import load_model
from keras.preprocessing.image import load_img, img_to_array
from keras.applications.imagenet_utils import preprocess_input
dels import Model
from Name import*
img_rows =300# ⾼
img_cols =300# 宽
def letterbox_image(image, size):
iw, ih = image.size
w, h = size
scale =min(w/iw, h/ih)
财务报销管理系统nw =int(iw*scale)
nh =int(ih*scale)
image = size((nw,nh), Image.BICUBIC)
new_image = w('RGB', size,(0,0,0))
new_image.paste(image,((w-nw)//2,(h-nh)//2))
return new_image
def test_accuracy(lines, model):
t =0
n =len(lines)
i =0#计数器
# 遍历测试集数据
for i in range(n):
name = lines[i].split(';')[0]#⼈脸图像名字xxx_xxx.png
label_name =(lines[i].split(';')[1]).strip('\n')#⼈脸数字标签0-39
label_name =int(label_name)
file_name =(label_name))#对应⼈名str
# 从⽂件中读取图像
img = Image.open(r".\data\test"+"\\"+ name)
img = np.array(letterbox_image(img,[img_rows,img_cols]),dtype = np.float64)
img = preprocess_input(np.array(img).reshape(-1,img_cols,img_rows,3))
pre_name = model.predict_classes(img)# 返回预测的标签值
print(int(pre_name),label_name)
if int(pre_name)== label_name:
t+=1
print(t/n)
def main():
#获取模型权重h5⽂件
model = load_model('./logs/easy1.h5')
with open('./','r')as f:
lines = f.readlines()
for img_location in glob.glob('./data/test/*.png'):# 限制测试图像路径以及图像格式
img = load_img(img_location)
img = img_to_array(img)
#图像处理
img = preprocess_input(np.array(img).reshape(-1,img_cols,img_rows,3))
img_name =(img_location.strip("face\\")).rstrip(".png")
pre_name = model.predict_classes(img)# 返回预测的标签值
print(pre_name)
pre = model.predict(img)
for i in pre_name:
for j in pre:
name = (i)
#print(name)
# if name != "Audrey_Landers":
acc = np.max(j)*100
print("\nPicture name is [%s]\npPredicted as [%s] with [%f%c]\n"%(img_name, name, acc,'%'))                MainFrame = Tk()
MainFrame.title(img_name)
img = Image.open(img_location)
img = ImageTk.PhotoImage(img)
label_img = ttk.Label(MainFrame, image = img)
label_img.pack()
MainFrame.mainloop()

本文发布于:2024-09-22 12:39:54,感谢您对本站的认可!

本文链接:https://www.17tex.com/tex/1/144842.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:数据   卷积   训练
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议