毕业实习实验报告.docx
《毕业实习实验报告.docx》由会员分享,可在线阅读,更多相关《毕业实习实验报告.docx(62页珍藏版)》请在冰豆网上搜索。
![毕业实习实验报告.docx](https://file1.bdocx.com/fileroot1/2023-3/18/481bb719-7a67-4711-a499-081d9361b643/481bb719-7a67-4711-a499-081d9361b6431.gif)
毕业实习实验报告
《毕业设计实验报告》
2019年2月
实验一使用DIGITS实现图像分类
一.实验目的
本实验将在DIGITS中通过以下方式训练深度神经网络以识别手写数字:
●将图像数据加载到训练环境
●选择和训练一个神经元网络
●用新数据进行测试并迭代以提高性能
二.实验原理
a)DIGITS
DIGITS是英伟达为普及深度学习开发的图形化操作界面,简单易用,旨在帮助初学者跨越入门障碍,迅速上手。
因此,DLI的入门培训均要求学员从DIGITS起步。
b)深度学习概念
深度学习(DeepLearning,DL)由Hinton等人于2006年提出,是机器学习(MachineLearning,ML)的一个新领域。
深度学习被引入机器学习使其更接近于最初的目标----人工智能(AI,ArtificialIntelligence)。
深度学习是学习样本数据的内在规律和表示层次,这些学习过程中获得的信息对诸如文字、图像和声音等数据的解释有很大的帮助。
它的最终目标是让机器能够像人一样具有分析学习能力,能够识别文字、图像和声音等数据。
深度学习的概念最早由多伦多大学的G.E.Hinton等于2006年提出,基于样本数据通过一定的训练方法得到包含多个层级的深度网络结构的机器学习过程。
传统的神经网络随机初始化网络中的权值,导致网络很容易收敛到局部最小值,为解决这一问题,Hinton提出使用无监督预训练方法优化网络权值的初值,再进行权值微调的方法,拉开了深度学习的序幕。
深度学习所得到的深度网络结构包含大量的单一元素(神经元),每个神经元与大量其他神经元相连接,神经元间的连接强度(权值)在学习过程中修改并决定网络的功能。
通过深度学习得到的深度网络结构符合神经网络的特征,因此深度网络就是深层次的神经网络,即深度神经网络(deepneuralnetworks,DNN)。
三.实验步骤
训练网络识别手写数字
由于计算机将图像看作是像素值的集合,所以除非它学到像素代表什么,否则它不能对视觉数据做任何事情。
我们要训练一个深层神经网络识别手写体数字0-9。
这个挑战性问题被称为“图像分类”,我们的网络将能够决定哪一个图像属于哪个类或群体。
例如:
下面的图片应该属于“4”这一类:
下一副图像将属于“2”这一类:
(一)加载和整理数据
使用DIGITS时,可以在主屏幕创建新的数据集或新的模型。
首先选择左边的 Datasets 选项卡。
因为我们希望网络告诉我们每一个图像属于哪个“类”,因此需要DIGITS从右边的“Images”菜单中选择“Classification”来加载一个“Classification”图像数据集。
创建完毕后,输入用户名。
如下图所示:
在加载数据集的页面,有很多选项。
填写两个域。
复制并粘贴以下文件路径到"TrainingImages"域:
/dli/data/image_class/train_small
给数据集命名以便能找到它。
选择:
DefaultOptionsSmallDigitsDataset。
请注意此时数据集已经下载到正在运行DIGITS的计算机。
然后点击"Create"
此时DIGITS正在从目录中创建您的数据集,在 train_small 目录中有10个子目录,(0,1,2,3,...,9)各一个目录.在所有手写的训练图片中,'0'放在'0'目录,'1'放在'1'目录,等等。
选择"Explorethedb"来查看加载的数据
显示数据结果如下图:
(二)从数据中学习-训练神经网络
接下来,将使用我们的数据来训练一个人工神经网络。
就像生物的灵感一样,人脑、人工神经网络就是学习机器。
和大脑一样,这些“网络”只能够解决有经验的问题,在这种情况下,可以与数据交互。
在整个实验中,我们将把“网络”作为未经训练的人工神经网络,把“模型”作为经过训练的网络(通过接触数据)。
在DIGITS中创建一个新的模型很像创建一个新的数据集。
从主屏幕上,"Models"选项卡需要预先选定。
在“NewModel”下点击“Images”,选择“Classification”,我们正在创建一个图像分类模型来匹配我们的图像分类数据集和图像分类任务。
设置训练网络
1.我们需要选择我们刚刚创建的数据集。
选择 DefaultOptionsSmallDigitsDataset 数据集。
2.我们需要告诉网络我们需要多长时间训练它。
一个 epoch 是整个培训数据集的一次训练。
将 TrainingEpochs 设置为5,让我们的网络有足够的时间去学习一些东西,但不要花一整天的时间。
这是一个非常好的实验设置。
3.我们需要定义哪一个网络将从我们的数据中进行学习。
因为我们在创建我们的数据集时采用缺省设置,我们的数据库是全彩色256x256图像。
如果只期待256x256的彩色图像分类,那么选择网络为 AlexNet。
4.我们需要给模型命名,由于我们可能会做很多这样的工作,因此我们选择 chenhong来命名。
设置了所有这些选项时,按“Create”按钮。
得到训练图表如下图所示:
我们将把这个图作为改进的工具,但是最重要的一点是经过5分钟的训练,我们已经建立了一个模型,它可以将手写数字的图像映射到它们所代表的数字,准确率大约为87%!
(三)推理
既然我们的神经网络已经学会了一些东西,那么推理(inference)就是基于所学知识做出决定的过程。
训练得到的模型的能力在于它现在可以对未标签图像进行分类。
我们将用DIGITS来测试训练得到的模型。
在模型窗口的底部,您可以测试单个图像或一组图像。
在左边,在ImagePath文本框中键入路径 /dli/data/image_class/test_small/2/img_4415.png。
选择 ClassifyOne 按钮。
几秒钟后,将显示一个新窗口,显示其试图对图像进行分类的图像和信息。
四.实验结果
训练网络识别手写数字实验结果,如下图所示。
五.实验改进
(一)验证训练时长和模型准确性的关系
通过点击屏幕左上角的DIGITS图标进入DIGITS主屏幕。
选择所创建的第一个模型"chenhong."DIGITS将显示在模型被训练时生成的图表。
上图包含三个量:
训练损失、验证损失和准确性。
训练和验证损失的值应该从一个epoch降低到另一个epoch,尽管它们可能会跳来跳去。
准确度是模型对验证数据进行正确分类的能力的度量。
如果将鼠标悬停在任何数据点上,就会看到其精确值。
在这种情况下,最后一个epoch的准确率大约是87%。
由于最初的网络是随机生成的,所以结果可能与这里显示的稍有不同。
分析这个图表可得:
准确性随着时间的推移而增加,而损失正在减少。
一个自然而然的问题可能是:
“如果我们让它训练的时间更长,模型会不会继续改进?
”这是我们将要首先涉及的实验和探讨。
回到DIGITS和滚动到模型页面的底部,并点击标记:
"MakePretrainedModel."的绿色大按钮。
这将节省两件事:
1."networkarchitecture"选择"AlexNet.
2.这个模型以在网络中通过前5个epoch的数据以调整参数的形式得到了“学习”。
现在我们可以此为起点创建一个新模型。
回到DIGITS主屏幕,并像前面那样创建一个图像分类模型。
NewModel(Images)->Classification
数据集设置如下
∙选择相同的数据集(DefaultOptionsSmallDataset)
∙设置epoch次数为4。
∙这次,不选择"StandardNetwork,"而是选择"PretrainedNetworks."
∙选择刚刚创建的pretrained模型"chenhong".
∙给您的模型命名-我们选择"studymore"
∙点击Create
如下图:
在创建模型后,将得到以下图表.
观察图表可知:
1.正如预期的那样,精度开始接近我们的第一个模型留下的86%。
2.准确度确实在不断提高(最终为92%),这表明增加epoch数通常会提高性能。
3.准确率的提高速度减慢了,表明通过相同数据进行更多的训练并不是提高性能的唯一途径。
①用一个图像测试改进模型
让我们用以前的图像来测试我们的新的和改进的模型。
在我们模型页面的底部.我们将测试相同的“2”来比较性能。
测试结果如下图所示:
可见,其准确度达到97%,比上个模型明显提升,这显然是一个更好的模型。
②用一组图像测试改进模型
试着用一组图像来测试这个模型。
它们如下所示。
如果把多个文件放在列表中,我们就可以对它们进行分类。
在下面的链接,执行代码块和链接的文件将出现an_image.list。
右键单击an_image.list并且保存到本地计算机上的文件(右键单击“另存为”)。
在DIGITS模型页面的右侧,有一个选项“testalistofimages”。
按下按钮 Browse 并选择您刚下载的 an_image.list 文件。
然后按ClassifyMany 按钮。
结果如下图所示:
这里展示的是该模型预测图像分到某一类的概率。
结果从最高概率到最低程度排序。
我们的模型没有做到那么好。
虽然该模型的准确率为92%,但它不能正确地对我们测试的任何图像进行分类。
在我们成功地训练一个模型之后,接下来要做的是理解和实验。
为了更好地理解这个项目,应该从我们的数据开始。
为了建立更好地理解,应该从最初始来源着手。
这个数据集是我们从MNIST数据集学习的一个子集。
我们要采用的一个关键理念是,图像是始于28x28的灰度级图像。
当我们加载数据集,我们强制设置缺省值是256x256的彩色图片。
(二)探讨数据与正确的模型相匹配的益处
把数据作为28x28灰度图像,选择一个建立在可以接受这种数据类型的模型---LeNet。
创建数据集的图像设置如下:
●ImageType中选择“Grayscale”。
●ImageSize中输入28*28
●复制并粘贴以下文件路径到"TrainingImages"域:
/dli/data/image_class/train_small
●给数据集命名以便能找到它。
选择:
mnistsmall。
再次选择"explorethedb",图像不再模糊了,如下图所示。
接下来,创建一个模型,模型设置如下图所示。
●选择 mnistsmall 数据集。
●将 TrainingEpochs 设置为8。
●选择网络为 Lenet,Lenet模型的适用于28x28灰度图像。
●模型命名为therightmodelforthedata
模型性能如下图所示:
如上图,可以发现:
●模型改进了性能。
此处的模型的精确到96%以上。
●模型训练得更快了。
在不到两分钟的时间里,模型训练了8个epoch。
们没有做任何事情来解决更多不同数据的问题,但是如果我们能训练的更快,我们就可以做更多的实验。
(三)训练更多的数据
在我们训练的最后一次尝试中,我们只使用全MNIST数据集10%。
现在我们尝试使用完整的数据集进行训练,看看它是如何提高我们的训练的。
我们可以使用DIGITS中的克隆选项来简化创建一个与旧工作具有类似属性的新作业。
让我们通过单击左上角的 DIGITS 返回主页。
然后从页面左侧选择Dataset 查看所创建的所有数据集。
选择MNIST小数据集。
点击一个按钮:
CloneJob.
与全MNIST数据创建一个数据库,更改以下设置:
∙TrainingImages-/dli/data/image_class/train_full
∙DatasetName-MNISTfull
按 Create 按钮.这个数据集要比其它数据集大十倍,因此需要几分钟的时间处理。
接着创建模型,模型设置如下图所示。
●选择 mnistfull 数据集。
●将 TrainingEpochs 设置为8。
●选择网络为 Lenet,Lenet模型的适用于28x28灰度图像。
●模型命名为moredata
结果如下图所示。
但从图中可知,训练和验证损失函数值都小很多。
此外,该模型的准确率在99%左右,可能更大。
也就是说,该模型正确地识别了其验证集中的每一个图像。
这是一个很大的改进。
用上面的步骤对我们的测试图像进行分类,下面是新的结果:
(四)改进模型结果-数据增强
我们的七个测试图像背景不均匀。
此外,大多数背景颜色浅,而我们的训练数据都有黑色背景。
通过上个实验,我们知道,增加数据量有助于对手写字符进行分类,那么如果我们包含更多的数据来处理对比度差异呢?
我们尝试通过反转原始图像来增强我们的数据。
我们把白色像素变成黑色,反之亦然。
然后,我们将使用原始图像和反转图像来训练网络,并查看是否改进了分类。
按照上面的步骤克隆并创建一个新的数据集。
数据集设置如下:
●增强数据的目录如下:
TrainingImages-/dli/data/image_class/train_invert
●DatasetName–dataenhancement
当新数据集就绪后,仔细查看数据库。
可以看到黑色背景和白色数字,还有白色背景和黑色数字的图像。
现在训练一种新的模型。
克隆一个以前的模型结果,并将数据集转换为刚才用反转的图像创建的数据集dataenhancement。
设置模型的名称为newdata并创建一个新模型。
使用增强的数据集,是否有助于我们更好地对图像进行分类?
这里是结果:
如上图,当训练完成时,并没有真正超过非增强图像集的精度。
事实上,准确率可能略有下降。
我们已经99%了,所以我们不太可能提高我们的准确性。
继续用原来的一组图形测试,如下是测试结果:
通过增加我们的数据集与反转的图像,我们能够识别七个图像中的五个。
虽然我们的结果并不完美,但我们对图像的小修改增加了数据集的大小,使得差异很大。
(五)高级阶段-通过修改网络(可选)来改进模型结果
增强数据集虽然提高了我们的结果,但我们没有识别所有的测试图像。
让我们试着直接修改Lenet网络。
我们可以创建自定义网络来修改现有的网络,使用来自外部源的不同网络,或者创建自己的网络。
我们选择Network对话框的右侧的Customize链接来修改网络。
如下图:
这里将打开一个编辑器查看Lenet模型配置。
滚动窗口并查看代码。
网络被定义为一系列的层。
每个层都有一个名称,它是函数的描述符。
每个层都有一个顶部和底部,或者每层可能有多个,指示各层是如何连接的。
Type用变量形式定义这个层的类型。
通常包括Convolution,Pool,和ReLU.所有Caffe语言模型的选项在Caffe教程CaffeTutorial中都可以找到.
在编辑器的顶部有一个Visualize按钮。
按下这个按钮将可视化模型的所有层,以及它们是如何连接的。
在这个窗口中,您可以看到数据,这里有两组Convolution(卷积)层和Pooling(池化)层和两层InnerProduct层,并且通过一个直线单元(ReLU)连接首个的InnerProduct层(caffe中的InnerProduct(IP)层即fully_connected(fc)layer-全连接层)。
输出函数返回通过网络计算得出的精度和损失值。
我们将对网络进行两次更改。
首先,我们要连接一个ReLU函数到首个池化层。
其次,我们要改变num_output值为第一卷积75(conv1)和100(第二卷积conv2)。
该层定义应该ReLU函数定义应在pool1定义之下,如下:
卷积层应改变如下:
进行这些更改后,可视化新模型,可以看到类似于下图所示的ReLU函数:
现在,更改模型的名称并按Create按钮。
下表为测试结果图。
完成后,再次测试数据。
结果应该类似于下图:
完成后,再次测试数据。
结果如下图:
六.实验心得
通过这次实验,我了解到了深度学习的详细介绍和所有必要步骤,包括数据处理、训练、测试来对图像进行分类,并通过数据增强和网络修改来提高网络性能。
在训练阶段,我学习了可以确定网络训练性能的参数。
通过训练MNIST数据子集以及集,我了解到数据越多越好。
在测试我的模型时,我发现虽然测试图像与训练数据有很大的不同,但是我们仍然可以正确地对它们分类。
实验二使用DIGITS实现图像分类
一.实验目的
通过检测航空图像中鲸鱼的面部,来学习如何应用深度学习进行目标检测。
通过实验,将学习如何:
∙将传统的计算机视觉与深度学习相结合
∙基于深度学习框架Caffe对现有神经网络结构进行修改
∙通过使用专门构建的网络和端到端标记的数据来掌握深度学习相关知识
二.实验步骤
(一)目标检测方法1:
滑动窗口
1)原理
有多种方法可以用卷积神经网络(CNN)来检测和定位图像中的物体。
最简单的方法是首先在可以区分目标和非目标实体的图像块上训练CNN分类器。
图2显示了一个CNN的架构,其能够从背景图块中区分出鲸鱼的斑块。
通过使用这种类型的分类器,我们可以在较大的图像中检查每个图像块,还可以使用重叠的图像块,以确定是否有鲸鱼存在。
让我们按照这个方法往下做。
在这个实验中我们有两个数据集可用。
第一种是包含鲸鱼的广阔海域的图集。
这个图集位于data_336x224。
第二个数据集是大约4500个鲸鱼面部的局部图,另外4500个来自同一个图像的随机局部图。
这个数据集在data/train/faces和data/train/background目录下。
我们将在DIGITS中使用第二个数据集训练我们的分类器。
2)验证
首先,我们需要将数据集导入到DIGITS中。
使用Datasets->Images下拉菜单,选择“classification”。
输入用户名chenhong。
当“NewImageClassificationDataset”面板打开,使用下面的预处理选项:
∙复制并粘贴以下文件路径到"TrainingImages"域:
/dli/data/whale/data/train/
∙给数据集命名以便能找到它。
选择:
whale_faces
程序将导入这个256x256像素的face/not-face数据集并分出25%作为验证数据集-DIGITS会自动从图像文件夹结构中区分这两个类别的名字。
DIGITS需要几分钟来完成数据导入,一旦导入完成,如果返回到DIGITS主屏幕,然后重新进入whale_faces数据集,点击"Explorethedb"按钮查看每个类中的图像示例。
结果如下图所示:
现在我们将在这个数据集上训练一个简单的两级分类CNN分类器。
返回到DIGITS主屏幕并使用Models->Images下拉菜单并选择“classification”模型。
在打开的“NewImageClassificationModel”面板上,自定义以下内容:
∙选择刚刚创建的whale_faces数据集
∙选择标准的网络“AlexNet”
∙将训练时长设为5个epoch
∙给模型起一个名字,取名叫“whale_faces_baseline”
面板如下图:
点击"Create"按钮开始训练模型。
可以看到一个实时更新图表,显示模型训练损失值和验证集的损失值以及准确度。
随着训练的进行损失值将减小,准确度将提高。
训练需要几分钟时间才能完成。
最后,可以看到验证的准确率在98%左右-我们得到了一个非常好的whaleface/non-face模型。
如下图所示:
把URL/dli/data/whale/data/train/face/w_2606.jpg以文本的方式输入,并点击"ClassifyOne"按钮,以此来测试针对单个图像的分类。
点选"Showvisualizationsandstatistics"框,可以查看CNN是如何对图像响应来进行分类的。
下图是测试结果:
下图是CNN对图像响应进行分类的部分操作:
现在我们有了这个模型,我们将在这个实验中使用它,在广阔的航拍图像上用一个滑动窗口来检测鲸鱼面部。
我们需要用DIGITS训练出的模型的作业编号。
在后面的代码中我们将用参考模型的作业编号设置MODEL_JOB_NUM,用数据集的作业编号设置DATASET_JOB_NUM。
我的参考模型的作业编号20190301-012911-2b5e,数据集的作业编号20190301-012156-da62。
执行以下程序。
这个程序大概需要30秒时间来执行,输出结果将显示从测试图片中随机选择的一个区域以及一个预测结果数组,这个数组包含了针对每一个256*256大小的非重叠栅格的预测结果。
下图是程序运行结果:
当多次运行上面的代码时,我发现,在某些情况下,使用这个基准模型和滑动窗口法能够找到鲸鱼的面部——多数情况下,它会发现大量的鲸鱼。
但此模型很容易被海浪或从海面反射出来的阳光所迷惑。
3)思考题
1.从背景数据集中使用随机局部图可能会有什么问题?
答:
随机图像块可能最终也包含着鲸鱼的面部。
这是不可能的,因为鲸鱼面部通常只是图像的一小部分,我们拥有的大量的随机背景图块,几乎完全不包含鲸鱼脸。
我们也可以在我们的背景中找到鲸鱼的身体和尾巴,但这是我们对鲸鱼面部定位感兴趣的地方。
2.有哪些方法可以提高该模型的分类精度?
答:
尝试将使用大量的随机选择的非面部的图块,并通过随机旋转,翻转和缩放来增强现有的面部图块,以达到数据集均衡的效果。
还可以用大量的带有训练参数的模型,如GoogleNet。
3.我们怎样才能抵消掉重叠栅格所需增加的计算时间呢?
答:
我们可以一次批出多个栅格,作为批处理送入网络,这样我们就可以进一步利用并行,并从GPU获得计算加速。
4)练习
●栅格大小为256*256,修改代码,增加栅格之间的重叠并获得更细的分类图。
●将代码修改为批处理多个栅格,以便传入网络进行预测。
代码如下:
%matplotlibinline
importnumpyasnp
importmatplotlib.pyplotasplt
importcaffe
importtime
MODEL_JOB_NUM='20190301-012911-2b5e'##Remembertosetthistobethejobnumberforyourmodel
DATASET_JOB_NUM='20190301-012156-da62'##Remembertosetthistobethejobnumberforyourdataset
MODEL_FILE='/dli/data/digits/'+MODEL_JOB_NUM+'/deploy.prototxt'#Donotchange
PRETRAINED='/dli/data/digits/'+MODEL_JOB_NUM+'/snapshot_iter