tensorflow搭建cnn人脸识别训练+识别代码(python)

阅读: 评论:0

tensorflow搭建cnn⼈脸识别训练+识别代码(python)
环境介绍:
Balabalabala
任何东西的起步都是把它的环境给搭建好,关于tensorflow的环境搭建⽹上⼀众博客这⾥就不多说了,⾃⼰使⽤的是Anaconda那套安装流程。这次代码还需要的⼀些其他python库,⼤家可以在跑的时候发现哪个no moudle了在install即可。
总的来说代码的⼤致情况如下:
1.搭建⼯具:windows +tensorflow 1.4.0 + python 3.5 + opencv3
2.训练代码:test
3.py
训练的代码cmd运⾏就好了,你要做的就是双⼿离开键盘睡⼀觉第⼆天就能跑完。训练后的模型保存为ckpt1 ⽂件夹,⾥⾯有四种⽂件
3.识别代码:hahaha.py(不要在意我丢死⼈的⽂件名)
在cmd 窗⼝运⾏hahaha.py。
cmd 窗⼝显⽰让你选择识别图⽚(G)或者视频流(V)识别。
①选择图⽚识别
输⼊图⽚路径,⾃动弹出识别框,⼈脸部分画框,cmd 窗⼝显⽰学号。
②选择摄像头视频流识别
按下英⽂字母“s”,会进⾏识别,画⼈脸框,cmd 窗⼝显⽰学号。
按下英⽂字母“q”,结束识别。
注:如果像素过低,此时不会在⼈脸部分画框,⽽是识别整个画⾯。如果像素不低,会在⼈脸部分画框。
废话不多说来看代码吧(最后会给出完整源码):
训练代码test3.py:
# -*- coding: utf-8 -*-
from skimage import io,transform
import glob
import os
import tensorflow as tf
import numpy as np
import time
导包不多说,有报moudle XXX没有的去Anaconda环境⾥装上就好
接下来是⼀系列准备⼯作,我们的训练集是由60个同学每⼈500张经过裁剪的128*128的jpg图⽚构成的,每个⼈的500张照⽚都装在由
其学号构成的⽂件夹中(如下图)苯胺的制备
所以我们的准备⼯作分为两部分:
1.练集⽬录下读取60*500张照⽚resize统⼀⼀下⼤⼩,并且更重要的是,伴随着打开每⼀个⼦⽂件夹,我们要为其设置⼀个labels,⼀个⽂件夹的500张照⽚对应⼀个label,共60个label,这是后⾯检验acc的唯⼀指标,即是否能把测试集的照⽚通过我们的⽹络输出到指定出⼝得到正确的label。
path='D:/code/python/Anaconda3/envs/faces'
#将所有的图⽚resize成100*100
w=128
h=128
c=3
#读取图⽚
def read_img(path):
cate=[path+'/'+x for x in os.listdir(path) if os.path.isdir(path+'/'+x)]
imgs=[]
labels=[]
for idx,folder in enumerate(cate):
for im in glob.glob(folder+'/*.png'):
print('reading the images:%s'%(im))
img=io.imread(im)
size(img,(w,h,c))
imgs.append(img)
labels.append(idx)
return np.asarray(imgs,np.float32),np.asarray(labels,np.int32)
data,label=read_img(path)
当然,为了我们后边批量拿数据时候不会只拿到同⼀个⼈的⼏⼗张图⽚⽽尽量是⼏⼗个⼈的不同图⽚,我们借⽤np的⼀些函数将他们打乱⼀下顺序。
#打乱顺序
num_example=data.shape[0]
arr=np.arange(num_example)
np.random.shuffle(arr)
data=data[arr]
label=label[arr]
2.第⼆个步骤就是在这30000张照⽚⾥⼆⼋分成验证集和训练集
#将所有数据分为训练集和验证集
ratio=0.8
s=np.int(num_example*ratio)
x_train=data[:s]
y_train=label[:s]
x_val=data[s:]
y_val=label[s:]
这⾥需要定义⼀个函数,为了最后训练时候⼀批⼀批的传⼊数据⽽不是⼏万张⼀起丢
#定义⼀个函数,按批次取数据
def minibatches(inputs=None, targets=None, batch_size=None, shuffle=False):
assert len(inputs) == len(targets)
if shuffle:
indices = np.arange(len(inputs))
np.random.shuffle(indices)
for start_idx in range(0, len(inputs) - batch_size + 1, batch_size):
if shuffle:
excerpt = indices[start_idx:start_idx + batch_size]
else:
excerpt = slice(start_idx, start_idx + batch_size)
yield inputs[excerpt], targets[excerpt]
之后进⼊正式的构建CNN的步骤,⾸先是两个占位符,使⽤占位符的原因教程说的很清楚了,为了不使⽹络过于庞⼤⼆设计的
#-----------------构建⽹络----------------------
#占位符
x=tf.placeholder(tf.float32,shape=[None,w,h,c],name='x')
y_=tf.placeholder(tf.int32,shape=[None,],name='y_')
四个卷积层按照tesorflow1.0以后的版本按照参数要求填⼊对应的数值即可,具体每个参数的要求⼤家看看官⽅教程对应了解。同理⼏个全连接层也是如此。
def CNNlayer():
#第⼀个卷积层(128——>64)
conv1=v2d(
inputs=x,
filters=32,
kernel_size=[5, 5],
padding="same",
lu,
kernel_uncated_normal_initializer(stddev=0.01))
实验室制硝酸pool1=tf.layers.max_pooling2d(inputs=conv1, pool_size=[2, 2], strides=2)
#第⼆个卷积层(64->32)
conv2=v2d(
inputs=pool1,
filters=64,
kernel_size=[5, 5],
padding="same",
lu,
kernel_uncated_normal_initializer(stddev=0.01))
pool2=tf.layers.max_pooling2d(inputs=conv2, pool_size=[2, 2], strides=2)
#第三个卷积层(32->16)
conv3=v2d(
inputs=pool2,
filters=128,
kernel_size=[3, 3],
padding="same",
lu,
kernel_uncated_normal_initializer(stddev=0.01))
pool3=tf.layers.max_pooling2d(inputs=conv3, pool_size=[2, 2], strides=2)
#第四个卷积层(16->8)
conv4=v2d(
inputs=pool3,
filters=128,
kernel_size=[3, 3],
padding="same",
lu,
kernel_uncated_normal_initializer(stddev=0.01))
pool4=tf.layers.max_pooling2d(inputs=conv4, pool_size=[2, 2], strides=2)
re1 = tf.reshape(pool4, [-1, 8 * 8 * 128])
#全连接层
dense1 = tf.layers.dense(inputs=re1,
units=1024,
lu,
kernel_uncated_normal_initializer(stddev=0.01),                          kernel_ib.layers.l2_regularizer(0.003))
dense2= tf.layers.dense(inputs=dense1,
units=512,
lu,
kernel_uncated_normal_initializer(stddev=0.01),                          kernel_ib.layers.l2_regularizer(0.003))
logits= tf.layers.dense(inputs=dense2,
units=60,
activation=None,规整填料
kernel_uncated_normal_initializer(stddev=0.01),                            kernel_ib.layers.l2_regularizer(0.003))
return logits
这样在tensorflow这个⿊匣⼦下我们就搭好了⼀个七层的CNN神经⽹络到⽬前为⽌,我们对数据进⾏了⼀些预处理,对我们的图的结构进⾏了设置,那么接下来我们就要定义⼀些参数,他们的作⽤是接下来正式训练以后作为从图中的⼀些输出和我们进⾏交互,我们要做的就是根据这些输出来判定这⼀遍迭代得到的效果如何。主要的参数就是loss即cost也就是损失值,还有acc就是准确率,我们所做的⼀切操作的⽬的都是使loss越低越好,acc越⾼越好。当然不是每⼀次迭代都会使得loss变低acc变⾼,我们会经常发现到快接近极限时候loss和acc将会出现反复甚⾄直线下降(这⾥指测试集的loss和
acc,训练集的对应值当然基本不会往下⾛的),这是因为出现了过拟合现象,即在训练集的精确度太⾼导致的泛化能⼒很差的结果。对于过拟合的防⽌tensorflow也有其解决⽅式,在⽹络搭建的时候可以加上⼀层特殊的⽹络层来防⽌过拟合,不过本代码没有出现过拟合,所以相关内容⼤家可以⾃⾏搜索。
logits=CNNlayer()
loss=tf.losses.sparse_softmax_cross_entropy(labels=y_,logits=logits)
train_ain.AdamOptimizer(learning_rate=0.001).minimize(loss)
correct_prediction = tf.equal(tf.cast(tf.argmax(logits,1),tf.int32), y_)
acc= tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
于是乎我们正式的训练即将千呼万唤使出来,在这⾥我们看到了saver的操作,为了把对应⽹络层整个图架构的所有变量参数都保存起来,在预测部分的代码恢复再使⽤。可能你会奇怪为啥神经⽹络要分为训练的代码和预测的代码呢?这是因为训练往往需要⼤量的计算和数据以及千万次的迭代来使这些参数达到最优解,这将是⼗分耗费cpu gpu等计算资源的操作,所以我们往往把训练部分实现在计算能⼒强的服务器进⾏,将训练得到的参数变量保存下来作为预测代码的输⼊值赋予其构建的与训练代
码⼀样的图结构。所以我们丢给⽤户的软件app往往不是特别⼤,仅仅只是图的结构和参数⽽已。回到正题,对应的saver函数的使⽤如下,在session的每⼀次迭代我们都在批数据(前⾯定义的函数来取)跑完cnn后得到对应的训练集合测试集loss以及acc,选取这么多次迭代中测试集经度最⾼的三次进⾏保存。
#训练和测试数据,可将n_epoch设置更⼤⼀些
ain.Saver(max_to_keep=3)
max_acc=0
f=open('','w')
海鲜机n_epoch=10苹果灯
batch_size=64
sess=tf.InteractiveSession()
sess.run(tf.global_variables_initializer())
for epoch in range(n_epoch):
start_time = time.time()
#training
train_loss, train_acc, n_batch = 0, 0, 0
for x_train_a, y_train_a in minibatches(x_train, y_train, batch_size, shuffle=True):
_,err,ac=sess.run([train_op,loss,acc], feed_dict={x: x_train_a, y_: y_train_a})
train_loss += err; train_acc += ac; n_batch += 1
print("  train loss: %f" % (train_loss/ n_batch))
print("  train acc: %f" % (train_acc/ n_batch))
#validation
val_loss, val_acc, n_batch = 0, 0, 0
for x_val_a, y_val_a in minibatches(x_val, y_val, batch_size, shuffle=False):
err, ac = sess.run([loss,acc], feed_dict={x: x_val_a, y_: y_val_a})
val_loss += err; val_acc += ac; n_batch += 1
智能操作票print("  validation loss: %f" % (val_loss/ n_batch))
print("  validation acc: %f" % (val_acc/ n_batch))
f.write(str(epoch+1)+', val_acc: '+str(val_acc)+'\n')
if val_acc>max_acc:
max_acc=val_acc
saver.save(sess,'ckpt1/faces.ckpt',global_step=epoch+1)
f.close()
sess.close()

本文发布于:2023-05-27 09:09:25,感谢您对本站的认可!

本文链接:https://patent.en369.cn/patent/3/115782.html

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

标签:训练   代码   对应   识别   参数   迭代   拟合
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 369专利查询检索平台 豫ICP备2021025688号-20 网站地图