我的毕业设计之基于深度学习的⼈脸识别系统
如今在⼈脸识别领域中,开始逐步加强对深度学习技术的运⽤,这促使⼈脸识别的相关技术的发展速度得到显著提升,在此背景下,⼈脸识别技术在未来必然会拥有更为⼴阔的发展前景。
本⽂主要以卷积神经⽹络为基础对⼈脸识别模型进⾏设计,使⽤深度学习框架,通过Keras完成对卷积神经⽹络模型进⾏构建,使⽤OpenCV接⼝识别⼈脸并处理⼈脸数据建⽴数据集,然后对设⽴的模型开展训练,在完成训练后,运⽤该模型来实现⼈脸识别打卡。系统主要分为⼈脸采集、⼈脸图像处理、训练⼈脸模型训练和⼈脸识别打卡⼩程序四个模块,四个模块均能按照预定⽅式实现相应功能,整体来看,系统所具备的性能能够达到预期⽔平。
关键词 ⼈脸识别 卷积神经⽹络 OpenCV Keras
5 系统实现
经过前期的需求分析与系统设计,本章将按照⼈脸检测收集、⼈脸处理、模型训练和⼈脸识别GUI打卡⼩程序模块,分别介绍基于深度学习的⼈脸识别系统的开发的具体过程及实现代码。
5.1 ⼈脸检测收集
设定获取图⽚后的保存路径save_path,然后执⾏get_face.py中的__name__ == '__main__⽅法,⾸先使⽤OpenCV中的VideoCapture函数调⽤并启⽤摄像头,然后使⽤OpenCV中的级联分类器(CascadeClassifier)加载⼈脸识别分类器
haarcascade_l,针对所收集每帧图像中包含的⼈脸相关信息进⾏检测,且把得到的信息保存⾄特定位置,同时在视频中标记出⼈脸框与当前以保存图⽚张数,实现效果如图5.1所⽰。
图5.1 ⼈脸检测收集实现
实现代码如下:
def getface(name, cameraid, max_num, path_name):
cv2.namedWindow(name)
videocap = cv2.VideoCapture(cameraid)
data_path = "haarcascade_l"
classfier = cv2.CascadeClassifier(data_path)#加载OpenCV⼈脸识别器
color = (0, 255, 0)
num = 0
while videocap.isOpened):
ok, frame = ad()
if not ok:
break
grey = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
faceRects = classfier.detectMultiScale(grey, scaleFactor=1.2, minNeighbors=3, minSize=(32, 32)
if len(faceRects) >0: #检测到⼈脸,对⼈脸进⾏加框
for faceRect in faceRects:
x, y, w, h = faceRect
img_name = '%s/%d.jpg ' %(path_name, num)#保存⼈脸到⽬录
if num > max_num: #如果下载数量完成,退出
break
if num > max_num:
break
cv2.imshow(name, frame)
c = cv2.waitKey(10)
if c & 0xFF == ord('q'):
break
cv2.destroyAllWindows()
5.2 ⼈脸处理
⾸先设置图像⼤⼩参数IMAGE_SIZE,对图像尺⼨进⾏调整。若图⽚初始长宽存在差异,先确定哪⼀个边的长度是最长的,之后对其跟短边的差距进⾏计算,以明确短边对应的像素宽度需增加的具体数值,给图像增加边界,然后使⽤OpenCV中的pyMakeBorder函数进⾏边缘填充,最后使⽤OpenCV中的size函数调整图像⼤⼩并返回。当训练模型时,会调⽤load_dataseth函数,从指定路径读取训练数据对图⽚进⾏转换并得到相应的四维数组,
尺⼨为最后标注数据,chenkepu⽂件夹下都是需要被识别的脸部图像,全部指定为0,其他⽂件夹下是其他⼈脸,全部指定为1,最后返回数据集。实现代码如下:
IMAGE_SIZE = 64 #图像⼤⼩参数IMAGE_SIZE
def resize_image(image,value=BLACK)
size(constant,(height, width))
images = [] #保存图⽚
labels = []#保存标签
# 读取图⽚
def read_path(path_name):
for dir_item in os.listdir(path_name):
full_path = os.path.abspath(os.path.join(path_name, dir_item)
if os.path.isdir(full_path): #读取路径
read_path(full_path)
else:
if dswith('.jpg'):
image = cv2.imread(full_path)
image = resize_image(image, IMAGE_SIZE, IMAGE_SIZE)
images.append(image)
labels.append(path_name)
return images, labels
def load_dataset(path_name): #加载数据时调⽤此函数
images, labels = read_path(path_name)
images = np.array(images)
labels = np.array([0 dswith('chenkepu') else 1 for label in labels])#打上标签
return images, labels#返回图⽚与标签
5.3 模型训练
5.3.1 数据集处理
收集⼈脸数据完成后,开始训练模型,完成对所需数据的全⾯加载后,基于函数对数据集进⾏合理划分,以得到分别⽤于训练、测试不同⽅⾯的集,本次运⽤⽐例为7:3的,划分前,先会将数据全部都打乱,使得训练集和测试集的数据分布均匀。划分好数据集以后,若Keras中运⽤的后端引擎为,则具备的属性为,若为Theano,则具备的属性为,为保证程序具有更⾼的稳健性,需先对具备的实际属性进⾏判定,且以此为依据来调整维度顺序。最后要开展归⼀化处理,保证各特征值所对应的尺度能够相对⼀致。若不开展该处理,所具备尺度不同的特征值对应的梯度会存在显著差异,但对梯度进⾏更新的过程中,对应的学习率却具备较⾼统⼀性,若其对应数值较⼩,则较⼩的梯度难以实现快速的更新,若其对应的数值较⼤,则较⼤的梯度在⽅向上⾯会缺乏稳定性,不易收敛,⼀般会将学习率对应的数值调低,以实现跟所具备尺度较⼤的维度实现匹配,进⽽保证损失函数能够处于较低范围内,因此,通过归⼀化,把不同维度的特征值范围调整到相近的范围内,就能统⼀使⽤较⼤的学习率加速学习。因为图⽚像素值的范围都在0~255,图⽚数据的归⼀化可以简单地除以255。实现代码如下:
class Dataset:
def __init__(self, path_name):
# 训练集
# 验证集
self.valid_images = None
self.valid_labels = None
# 测试集
# 数据集加载路径
self.path_name = path_name
#def load(self, img_rows=IMAGE_SIZE, img_cols=IMAGE_SIZE,
img_channels=3, nb_classes=2):
# 加载数据集到内存
images, labels = load_dataset(self.path_name)
#训练 验证 训练标签 验证标签
train_images, valid_images, train_labels, valid_labels = train_test_split(images, labels, test_size=0.3,
random_state=random.randint(0, 100))
_, test_images, _, test_labels = train_test_split(images, labels, test_size=0.5,
random_state=random.randint(0, 100))
if K.image_data_format() == 'channels_first':
train_images = shape(train_images.shape[0], img_channels, img_rows, img_cols)
valid_images = shape(valid_images.shape[0], img_channels, img_rows, img_cols)
test_images = shape(test_images.shape[0], img_channels, img_rows, img_cols)
self.input_shape = (img_channels, img_rows, img_cols)
else:
train_images = shape(train_images.shape[0], img_rows, img_cols, img_channels)
valid_images = shape(valid_images.shape[0], img_rows, img_cols, img_channels)
test_images = shape(test_images.shape[0], img_rows, img_cols, img_channels) self.input_shape = (img_rows, img_cols, img_channels)
valid_labels = _categorical(valid_labels, nb_classes)
test_labels = _categorical(test_labels, nb_classes)
# 像素数据浮点化以便归⼀化
train_images = train_images.astype('float32')
valid_images = valid_images.astype('float32')
test_images = test_images.astype('float32')
# 将其归⼀化,图像的各像素值归⼀化到0~1区间
train_images /= 255
valid_images /= 255
test_images /= 255
self.valid_images = valid_images #加载验证数据
self.valid_labels = valid_labels #加载验证标签
5.3.2 搭建神经⽹络
该⽹络具备的整体结构列⽰在表5.1中,Layer指各层对应的具体类型,Filters指输出滤波器的具体数量,Size为卷积核体积,为输出数据信息。
表5.1 ⽹络结构概况
Layer (type) Filters Size Output Shape
conv2d (Conv2D)32(3,3) (22, 22, 32)
activation (Activation) (22, 22, 32)
conv2d_1 (Conv2D) 32(3,3)(20, 20, 32)
activation_1
(20, 20, 32)
(Activation)
(2,2)(10, 10, 32)
max_pooling2d
(MaxPooling2D)
dropout (Dropout) (10, 10, 32)
conv2d_2 (Conv2D) 64(3,3)(10, 10, 64)
activation_2 (Activation) (10, 10, 64)
conv2d_3 (Conv2D) 64(3,3)(8, 8, 64)
activation_3 (Activation) (8, 8, 64)
(2,2)(4, 4, 64)
max_pooling2d_1
(MaxPooling2)
dropout_1 (Dropout) (4, 4, 64)
flatten (Flatten)(1024)
dense (Dense) (512)
activation_4 (Activation) (512)
dropout_2 (Dropout)(512)
dense_1 (Dense) (2)
activation_5 (Activation)(2)
上表描述了搭建神经⽹络的详细信息,如下图5.2是基于CNN的⼈脸识别神经⽹络结构图。包含4个卷积层、池化及全连接层各2各、Flatten及分类层各1个,其中每⼀层的作⽤如下:
图5.2 基于CNN的⼈脸识别神经⽹络结构图
(1)卷积层(convolution layer):运⽤keras内包含的函数基于⼆维层⾯开展相关的卷积计算。输⼊图像纯为64*64,对其开展滑窗计算,如下图5.2所⽰:
图5.3 卷积计算
(2)激活函数层:激活函数将简单的线性分类变成复杂的⾮线性分类以获得更好的分类效果,该⽹络主要运⽤了relu函数,输⼊的具体数值若⼩于0,则输出的所有数值均为0,若输⼊部分超过0,那么最终输出的数值会与之相等。其优点为能够在较短时间内实现收敛,其数学形式如下:
图5.4 池化
(4)Dropout层:随机对⼀定数量的输⼊神经元间存在的链接进⾏断开,避免出现过拟合情况。
(5)Flatten层:完成上⾯提及的各个过程后,数据仍旧以⼆维⽅式呈现,⽽基于该层能够将其压缩为⼀维。
(6)全连接层:负责将数据划分成不同类型且开展回归处理。该层会对512个特征进⾏保留并传给下层。函数为基础完成整个分类过程。基于分类层⾯,若神经元所输出的具体数值较⼤,则更可能被归为真实类别。所以通过该函数进⾏处理后,从上层得到的N个输⼊会以映射⽅式形成与之对应的概率分布,且所有概率相加后为1,所对应概率最⾼的便是预估的具备类别。其函数式如下:
实现代码如下:
# 建⽴模型
def build_model(self, dataset, nb_classes=2):
# 构建⼀个空的线性堆叠⽹络模型
input_shape=dataset.input_shape))# 2维卷积层
# 输出模型概况
rectangle函数opencv
5.3.3 模型训练
搭建神经⽹络后,开始训练模型。 在开始训练前,先对优化器对应的函数进⾏设置,优化器在训练过程主要对相关参数进⾏调节,保证处于最优⽔平,本次基为主要依据来判定是不是要运⽤相应的动量⽅法,相对于传统动量法,其效率更⾼,实现代码如下:
# 训练模型
def train(self, dataset, batch_size = 32, nb_epoch = 5, data_augmentation=True):
sgd = SGD(lr=0.01, decay=1e-6,
momentum=0.9, nesterov=True)# 采⽤SGD+momentum的优化器进⾏训练,⾸先⽣成⼀个优化器对象delpile(loss='categorical_crossentropy',
optimizer=sgd,
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论