本实验是大三上机器学习课程中的实习二,现将报告内容转至CSDN。本实验中我按照开源代码,只用VGG网络实现了人脸颜值打分,对于DNN网络和ResNet50方法尚未完全实现,但在本文章中也有呈现,可进行选择性忽略或参考。
项目源地址:你的颜值能打多少分?让飞桨来告诉你
数据中包含500张女生图片,分别由70人进行打分,最终取平均值即为该图片的打分情况。
我们在实践中将图片分值设定为1-5。
500张图片中,450张用于训练,50张用于验证。
在进行处理之前,先要对指定的包进行解压,来知道当前数据集名称。
按照以下代码,对压缩包进行处理:
我们可以知道,此项目的数据包名称为data17941。
解压完毕后,便可以进行对指定库的导入。本项目中主要用到的库有以下几类:
(1)paddle自带的库。飞桨paddlepaddle集成了python支持的机器学习模型的库,并予以提供了详细(2)python所支持的可视化图表库。因为本次实验需要绘制曲线、混淆矩阵等图表以支持模型拟合,(3)python所支持的基本库和第三方处理库。
本次实验还需要用到像超参数学习率、分类数、训练轮数等一系列的参数,所以我们可以在开始的时候就定义一个train_parameters对这些参数进行封装。在本项目中,我们将图片大小input_size、分类数class_dim、原始数据集路径src_path、要解压的路径target_path、训练轮数num_epochs、训练时每个批次的大小train_batch_size、超参数学习率定义lr在了train_parameters中,以便后续进行使用。
在对数据包进行解压、相关库的导入以及参数的定义之后,我们便可以开始对数据集进行预处理。
在这一部分,我们会定义一个数据集类MyDataset,并对训练集和验证集进行划分。
在定义数据集类的时候,我们需要对image和label进行标识,喂入数据。在解压的数据集中我们可以发现,图片是以“图片得分-编号”的方式来进行命名的,所以我们读取图片,并对名称进行分割,取第一个数字,按照训练集和验证集分开的方式,存入label里。
定义完数据集后,可以构造训练、测试数据提供器。
在这一部分,选择了三个神经网络模型,分别是:VGG网络模型、DNN网络模型和ResNet50网络模型,但是我想要着重讲一下VGG网络模型(包括后面的一系列过程,具体缘由我会在最后进行阐述)。
VGG模型在AlexNet的基础上使用3*3小卷积核,增加网络深度,具有很好的泛化能力。在2014年ImageNet比赛中,获得了定位第1,分类第2的好成绩。VGG的核心是五组卷积操作,每两组之间做Max-Pooling空间降维。同一组内采用多次连续的3X3卷积,卷积核的数目由较浅组的64增多到最深组的512,同一组内的卷积核数目是一样的。卷积之后接两层全连接层,之后是分类层。由于每组内卷积层的不同,有11、13、16、19层这几种模型,下图展示一个16层的网络结构。
在定义VGG模型时,我们先用fluid.nets.img_conv_group()函数定义一个卷积模块conv_block(),从而通过配置卷积模块组件VGG-16网络结构。卷积模块conv_block()主要用来设定该模块中的输入、池化、卷积、激活函数、以及dropout和bacthnorm。获得了卷积模块后,通过多个卷积模块的组合以及三个全连接层就可以轻松获得一个VGG-16模型。
之后对数据层进行定义。由于数据是224x224的三通道彩色图像,所以输入层image的维度为[None,3,224,224],label代表图片的颜值得分标签。此处可能会出现一个错误:
AssertionError:In PaddlePaddle 2.x, we turn on dynamic graph mode by default, and ‘data()’ is only supported in static graph mode. So if you want to use this api, please call ‘paddle.enable_static()’ before this api to enter static graph mode.
PaddlePaddle 2.X时,我们默认打开动态图形模式,而’data()‘仅支持静态图形模式。 # 所以如果你想使用这个api,请在这个api进入静态图形模式之前调用’paddle.enable_static()’。
定义好VGG网络结构以后,我们可以使用其来获取分类器predict,然后定义损失函数和准确率函数。定义损失函数时,我们使用的是交叉熵损失函数,原因是该函数在分类任务上比较常用。因为定义的是一个Batch的损失值,所以在定义了一个损失函数之后,还要对它求平均值。这里定义一个准确率函数,可以在训练的时候输出分类的准确率,也方便后面可视化分析使用。
定义好VGG网络结构以后,我们便可以开始进行模型的训练。
飞桨paddlepaddle是一个很强大的平台,在部署环境时可以自行选择使用CPU还是GPU进行操作。但是在选择之后,需要在代码里进行说明。
我们可以根据fluid库来创建一个实例exe,并在进行网络训练前,对执行参数初始化。定义好以后,执行训练之前,我们需要告知网络传入的数据分为两部分,即我们最开始提到的image、label。
之后就可以进行正式的训练了,本实践中设置训练轮数60。
在Executor的run方法中,feed代表以字典的形式定义了数据传入网络的顺序,feeder在上述代码中已经进行了定义,将data[0]、data[1]分别传给image、label。fetch_list定义了网络的输出。
在每轮训练中,每10个batch,打印一次训练平均误差和准确率。每轮训练完成后,使用验证集进行一次验证。 每轮训练完成后,对模型进行一次保存,使用飞桨提供的函数:fluid.io.save_inference_model()进行模型保存,如果保存路径不存在就自动创建。
在对模型进行评估时,我最终选择的是绘制准确率、损失率曲线。但其实最开始的时候是使用的训练数据和测试数据的图表输出,比如:
但是后来认为此曲线不能满足我的特定要求,于是代码改正过程为:
最终生成的图像为:
前面已经进行了模型训练,并保存了训练好的模型。接下来就可以使用训练好的模型对手写数字图片进行识别了。预测之前必须要对预测的图像进行预处理,首先对输入的图片进行灰度化,然后压缩图像大小为224x224(其实应该是100*100,但是我发现处理与否不影响结果),接着将图像转换成一维向量,最后对一维向量进行归一化处理。
在加载模型进行预测时,我们首先从指定目录中加载训练好的模型,然后喂入要预测的图片向量,返回模型的输出结果,即为预测概率,这些概率的总和为1。得到各个标签的概率值后,获取概率最大的标签,即为颜值的预测结果。
在本次实验中,我所撰写的报告是基于VGG模型的神经网络方法对人脸颜值进行打分,但是在我所给出的源代码一栏内,还包含另外两种模型,以及其他处理曲线的方法。实际上,VGG、DNN、ResNet网络的方法大同小异,所以我只是在使用之后进行了简单对比,但是在总结的时候只选取了一种进行使用。除此之外,在我代码的注释栏内还有绘制混淆矩阵和ROC曲线的方法,在混淆矩阵的过程中,由于我使用VGG网络时读入数据和使用数据方法不当,所呈现出来的矩阵为空,但是使用其他网络则可以,遂没有采取,而ROC曲线是我在阅读他人技术文档的时候所发现的一种可视化方法,由于本实验不太需要ROC曲线,遂也没有采取。
在可视化图表中,我们很容易看出,随着数据量的逐步增加,准确率趋近于1,但是在数据量为某个值的时候,损失率达到了最高值,我猜测是模型的偶然情况。总的来说模型拟合的情况较好,没有出现过拟合的情况。
其实在进行数据预测的时候,我发现预测的准确率不是很理想,一方面是数据集较少,未能达到验证的效果,另一方面是选择的模型问题,没有进行进一步的优化。和其他同学对比之后,发现SVN、随机森林等方法在预测图片分数时效果略优于我目前所建立出来的模型,但是限于时间,我没有继续尝试。
本次实习我是基于百度某一版开源代码上进行的修改,在我改完之后,和另外的开源代码所对比,发现我的代码封装程度不够。
3.1 VGG Network Model
3.2 DNN Network Model
3.3 ResNet50 Network Model
4.1 VGG
4.2 DNN
4.3 ResNet50
本次实习的缺陷我在上述已经提及,我需要改进的几个方面大致如下:
1.优化模型,并进行多次训练;
2.采用其他分类器对数据进行分类;
3.查看VGG网络的模型的使用问题,正确运用数据并查看混淆矩阵的输出情况;
本次实习是我第一次接触百度飞桨paddlepaddle平台,这个平台与kaggle类似,但又不同,不同之处在于此平台结合国内的项目及数据集较多,且自行封装python中的一些函数,通过改进和优化,封装为自己的paddle库,方便用户进行使用。总的来说,此平台较为完善,可使用性高,开源代码参考性强。
以上就是本篇文章【【机器学习】百度飞桨AI Studio平台项目:基于卷积神经网络分类方法的人脸颜值打分】的全部内容了,欢迎阅览 ! 文章地址:http://dfvalve.xrbh.cn/quote/3773.html 行业 资讯 企业新闻 行情 企业黄页 同类资讯 网站地图 返回首页 迅博思语资讯移动站 http://keant.xrbh.cn/ , 查看更多