文章目录
- 0 前言
- 1 项目运行效果
- 2 设计概要
- 3 设计原理
- 3.1 数据集
- 3.2 任务描述
- 3.3 demo实现
- 准备数据
- 构建网络
- 开始训练
- 模型评估
- demo识别效果
- 4 最后
0 前言
🔥这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。并且很难找到完整的毕设参考学习资料。
为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目提供大家参考学习,今天要分享的是
🚩毕业设计 深度学习手势识别系统(源码+论文)
🥇学长这里给一个题目综合评分(每项满分5分)
难度系数:3分
工作量:3分
创新点:4分
🧿 项目分享:见文末!
1 项目运行效果
视频效果:
毕业设计 深度学习手势识别系统
2 设计概要
课题主要目标:
本课题计划研究基于YOLO系列算法,使用公开的手势图像书籍及,对手势检测展开研究,并尝试提高手势检测识别的精度,助力智能手语识别系统的发展。
方案细化:
- 实现实时视频流的采集
- 选择具体YOLO-tiny系列网络,训练目标检测器
- 测试手势目标检测模型的最终结果
- 设计GUI交互模块,可对静态图片于动态视频中的手势进行有效识别检测
拟解决的主要问题:
- (1) 轻量级快速的交通标志检测,由于手势往往变化很快,所以要求不能使用过于复杂冗余的网络。
- (2) 小目标检测优化,手势目标往往属于图像目标检测中的小目标,对小目标的识别和检测具有一定的挑战性。
- (3) 对遮挡目标检测优化,目标检测识别往往伴随遮挡,需要对遮挡下的手势进行识别。
研究的基本思路:
本文将深度学习的系列方法引入到手语识别的研究中,具体的在静态手语识别方面本文结合深度卷积神经网络提出了手语识别模型。利用模型验证了深度卷积神经网络在手语识别上的可行性。接着利用模型进一步提高了静态手语识别的准确率,本文将均值化引入到手语识别模型中,极大的降低了参数数量,防止过拟合现象的发生。通过大量实验验证了深度卷积神经网络可以自动的学习到有用的手语特征,且深度卷积神经网络能学习到手语的细微变换,从而可以有效的对手语进行识别。
3 设计原理
这里用一个简单的卷积神经网络作为原理进行讲解,实际工程要比这个复杂!
3.1 数据集
手势识别在深度学习项目是算是比较简单的。这里为了给大家会更好的训练。其中的数据集如下:
3.2 任务描述
图像分类是根据图像的语义信息将不同类别图像区分开来,是计算机视觉中重要的基本问题。手势识别属于图像分类中的一个细分类问题。虽然与NLP的内容其实没有多大的关系,但是作为深度学习,DNN是一个最为简单的深度学习的算法,它是学习后序CNN、RNN、Lstm以及其他算法深度学习算法的基础。
实践环境:Python3.7,PaddlePaddle1.7.0。
用的仍然是前面多次提到的jupyter notebook,当然我们也可以用本地的pycharm。不过这里需要提醒大家,如果用的是jupyter notebook作为试验训练,在实验中会占用很大的内存,jupyter notebook默认路径在c盘,时间久了,我们的c盘会内存爆满,希望我们将其默认路径修改为其他的路径,网上有很多的修改方式,这里限于篇幅就不做说明了。这里需要给大家简要说明:paddlepaddle是百度 AI Studio的一个开源框架,类似于我们以前接触到的tensorflow、keras、caffe、pytorch等深度学习的框架。
3.3 demo实现
准备数据
首先我们导入必要的第三方库。
importosimporttimeimportrandomimportnumpyasnpfromPILimportImageimportmatplotlib.pyplotaspltimportpaddleimportpaddle.fluidasfluidimportpaddle.fluid.layersaslayersfrommultiprocessingimportcpu_countfrompaddle.fluid.dygraphimportPool2D,Conv2Dfrompaddle.fluid.dygraphimportLinear该数据集是学长自己收集标注的数据集(目前较小):包含0-9共就种数字手势,共2073张手势图片。
图片一共有3100100张,格式均为RGB格式文件。在本次实验中,我们选择其中的10%作为测试集,90%作为训练集。通过遍历图片,根据文件夹名称,生成label。
我按照1:9比例划分测试集和训练集,生成train_list 和 test_list,具体实现如下:
data_path='/home/aistudio/data/data23668/Dataset'# 这里填写自己的数据集的路径,windows的默认路径是\,要将其路径改为/。character_folders=os.listdir(data_path)print(character_folders)if(os.path.exists('./train_data.list')):os.remove('./train_data.list')if(os.path.exists('./test_data.list')):os.remove('./test_data.list')forcharacter_folderincharacter_folders:withopen('./train_data.list','a')asf_train:withopen('./test_data.list','a')asf_test:ifcharacter_folder=='.DS_Store':continuecharacter_imgs=os.listdir(os.path.join(data_path,character_folder))count=0forimgincharacter_imgs:ifimg=='.DS_Store':continueifcount%10==0:f_test.write(os.path.join(data_path,character_folder,img)+'\t'+character_folder+'\n')else:f_train.write(os.path.join(data_path,character_folder,img)+'\t'+character_folder+'\n')count+=1print('列表已生成')其效果图如图所示:
这里需要简单的处理图片。需要说明一些函数:
- data_mapper(): 读取图片,对图片进行归一化处理,返回图片和 标签。
- data_reader(): 按照train_list和test_list批量化读取图片。
- train_reader(): 用于训练的数据提供器,乱序、按批次提供数据
- test_reader():用于测试的数据提供器
具体的实现如下:
defdata_mapper(sample):img,label=sample img=Image.open(img)img=img.resize((32,32),Image.ANTIALIAS)img=np.array(img).astype('float32')img=img.transpose((2,0,1))img=img/255.0returnimg,labeldefdata_reader(data_list_path):defreader():withopen(data_list_path,'r')asf:lines=f.readlines()forlineinlines:img,label=line.split('\t')yieldimg,int(label)returnpaddle.reader.xmap_readers(data_mapper,reader,cpu_count(),512)构建网络
在深度学习中有一个关键的环节就是参数的配置,这些参数设置的恰当程度直接影响这我们的模型训练的效果。
因此,也有特别的一个岗位就叫调参岗,专门用来调参的,这里是通过自己积累的经验来调参数,没有一定的理论支撑,因此,这一块是最耗时间的,当然也是深度学习的瓶颈。
接下来进行参数的设置。
train_parameters={"epoch":1,#训练轮数"batch_size":16,#批次大小"lr":0.002,#学习率"skip_steps":10,#每10个批次输出一次结果"save_steps":30,#每10个批次保存一次结果"checkpoints":"data/"}train_reader=paddle.batch(reader=paddle.reader.shuffle(reader=data_reader('./train_data.list'),buf_size=256),batch_size=32)test_reader=paddle.batch(reader=data_reader('./test_data.list'),batch_size=32)前面也提到深度神经网络(Deep Neural Networks, 简称DNN)是深度学习的基础。DNN网络图如图所示:
首先定义一个神经网络,具体如下
classMyLeNet(fluid.dygraph.Layer):def__init__(self):super(MyLeNet,self).__init__()self.c1=Conv2D(3,6,5,1)self.s2=Pool2D(pool_size=2,pool_type='max',pool_stride=2)self.c3=Conv2D(6,16,5,1)self.s4=Pool2D(pool_size=2,pool_type='max',pool_stride=2)self.c5=Conv2D(16,120,5,1)self.f6=Linear(120,84,act='relu')self.f7=Linear(84,10,act='softmax')defforward(self,input):# print(input.shape)x=self.c1(input)# print(x.shape)x=self.s2(x)# print(x.shape)x=self.c3(x)# print(x.shape)x=self.s4(x)# print(x.shape)x=self.c5(x)# print(x.shape)x=fluid.layers.reshape(x,shape=[-1,120])# print(x.shape)x=self.f6(x)y=self.f7(x)returny这里需要说明的是,在forward方法中,我们在每一步都给出了打印的print()函数,就是为了方便大家如果不理解其中的步骤,可以在实验中进行打印,通过结果来帮助我们进一步理解DNN的每一步网络构成。
开始训练
接下来就是训练网络。
为了方便我观察实验中训练的结果,学长引入了matplotlib第三方库,直观的通过图来观察我们的训练结果,具体训练网络代码实现如下:
importmatplotlib.pyplotasplt Iter=0Iters=[]all_train_loss=[]all_train_accs=[]defdraw_train_process(iters,train_loss,train_accs):title='training loss/training accs'plt.title(title,fontsize=24)plt.xlabel('iter',fontsize=14)plt.ylabel('loss/acc',fontsize=14)plt.plot(iters,train_loss,color='red',label='training loss')plt.plot(iters,train_accs,color='green',label='training accs')plt.legend()plt.grid()plt.show()withfluid.dygraph.guard():model=MyLeNet()# 模型实例化model.train()# 训练模式opt=fluid.optimizer.SGDOptimizer(learning_rate=0.01,parameter_list=model.parameters())# 优化器选用SGD随机梯度下降,学习率为0.001.epochs_num=250# 迭代次数forpass_numinrange(epochs_num):forbatch_id,datainenumerate(train_reader()):images=np.array([x[0].reshape(3,32,32)forxindata],np.float32)labels=np.array([x[1]forxindata]).astype('int64')labels=labels[:,np.newaxis]# print(images.shape)image=fluid.dygraph.to_variable(images)label=fluid.dygraph.to_variable(labels)predict=model(image)# 预测# print(predict)loss=fluid.layers.cross_entropy(predict,label)avg_loss=fluid.layers.mean(loss)# 获取loss值acc=fluid.layers.accuracy(predict,label)# 计算精度Iter+=32Iters.append(Iter)all_train_loss.append(loss.numpy()[0])all_train_accs.append(acc.numpy()[0])ifbatch_id!=0andbatch_id%50==0:print("train_pass:{},batch_id:{},train_loss:{},train_acc:{}".format(pass_num,batch_id,avg_loss.numpy(),acc.numpy()))avg_loss.backward()opt.minimize(avg_loss)model.clear_gradients()fluid.save_dygraph(model.state_dict(),'MyLeNet')# 保存模型draw_train_process(Iters,all_train_loss,all_train_accs)训练过程以及结果如下:
前面提到强烈建议大家安装gpu版的paddle框架,因为就是在训练过程中,paddle框架会利用英伟达的GP加速,训练的速度会很快的,而CPU则特别的慢。因此,CPU的paddle框架只是在学习的时候还可以,一旦进行训练,根本不行。
可能GPU需要几秒的训练在CPU可能需要十几分钟甚至高达半个小时。其实不只是paddlepaddle框架建议大家安装GPU版本,其他的类似tensorflow、keras、caffe等框架也是建议大家按安装GPU版本。不过安装起来比较麻烦,还需要大家认真安装。
withfluid.dygraph.guard():accs=[]model_dict,_=fluid.load_dygraph('MyLeNet')model=MyLeNet()model.load_dict(model_dict)# 加载模型参数model.eval()# 训练模式forbatch_id,datainenumerate(test_reader()):# 测试集images=np.array([x[0].reshape(3,32,32)forxindata],np.float32)labels=np.array([x[1]forxindata]).astype('int64')labels=labels[:,np.newaxis]image=fluid.dygraph.to_variable(images)label=fluid.dygraph.to_variable(labels)predict=model(image)acc=fluid.layers.accuracy(predict,label)accs.append(acc.numpy()[0])avg_acc=np.mean(accs)print(avg_acc)模型评估
配置好了网络,并且进行了一定的训练,接下来就是对我们训练的模型进行评估,具体实现如下:
结果还可以,这里说明的是,刚开始我们的模型训练评估不可能这么好,可能存在过拟合或者欠拟合的问题,不过更常见的是过拟合,这就需要我们调整我们的epoch、batchsize、激活函数的选择以及优化器、学习率等各种参数,通过不断的调试、训练最好可以得到不错的结果,但是,如果还要更好的模型效果,其实可以将DNN换为更为合适的CNN神经网络模型,效果就会好很多,关于CNN的相关知识以及实验,我们下篇文章在为大家介绍。最后就是我们的模型的预测。
demo识别效果
4 最后
项目包含内容
🧿 项目分享:见文末!