北京中科崔永玲 http://m.39.net/disease/a_6690366.html
全文共字,预计学习时长20分钟或更长
本文将演示如何使用keras和tensorflow来构建、训练、测试能够识别特定图像中犬种的卷积神经网络。验证及测试的高准确率则表明测试成功,并以不同的精确率和召回率来区分准确率相近的模型。
这是一个监督学习问题,尤指多类别分类问题,因此可以通过以下步骤予以解决:
1.收集标签数据。在本文案例中即指用已知犬种编译图像库。
2.构建模型。该模型能从训练图像中提取数据并输出可以辨别的犬种数据。
3.在训练数据上训练模型;在验证数据上验证性能。
4.评价性能指标。该步骤可能返回步骤2重新进行建模以提高性能。
5.在测试数据上测试模型。
每步都有许多子步骤,具体详情将在下文予以说明。
前言
从计算成本来看,训练神经网络非常昂贵,哪怕是相对简单的神经网络也绝不便宜。许多公司使用专门处理此类任务的专用图形处理器(GPU);本文则使用配备GTX显卡(专门为该实验而装配)的本地个人计算机进行测试。要在本地计算机上执行此任务,必须执行以下几个步骤才能定义正确的编程环境,我将在此处予以详细的说明。如若对后端设置不感兴趣,请略过该部分。
首先,在Anaconda中创建新环境,并安装以下软件包:
tensorflow-gpu
jupyter
glob2
scikit-learn
keras
matplotlib
opencv(用于图像或视频流的人脸识别技术——并非必备,但在某些应用中非常实用)
tqdm
pillow
seaborn
接下来,更新显卡驱动;这极其重要,因为驱动程序会定期推出更新,即使对于已经推出3年之久的显卡也是如此,如果使用的tensorflow是最新版本,则需要配备最新驱动以实现兼容。
最后,从新环境的anacondaprompt中打开JupyterNotebook,以便执行工作,并确保Jupyter正在为内核使用的环境是正确的。如果不这样做,Tensorflow可能会遇到问题。
发布模块导入,调用以下命令来显示可用的CPU和GPU以作为完整性检查。
fromtensorflow.python.clientimportdevice_libprint(device_lib.list_local_devices())
GTX相关配置安装完成!
最后,执行以下代码块,用来编辑tensorflow后端的一些配置参数,并防止运行错误。
#tensorflowlocalGPUconfigurationgpu_options=tf.GPUOptions(per_process_gpu_memory_fraction=0.8)config=tf.ConfigProto()config.gpu_options.allow_growth=Truesession=tf.Session(config=config)
第1步:编译数据
在本文实验中,这一步无足轻重,因为Udacity已经提供了囊括个品种的1.08Gb的犬类图像,并且将这些犬类图像放置于适当的文件结构之中。对于使用keras构建的分类卷积神经网络而言,适当的文件结构指文件根据训练、验证和测试进行划分并根据犬种进一步细分至文件夹。每个文件夹的名称都与计划识别的类别名称保持一致。
显然易见,世界上犬种远超种;美国养狗协会(AKC)列出了种,而世界犬类联盟(FCI)则列出了种。如果想要增加训练数据集的容量以囊括更多犬种,或者囊括每个品种的更多图像,可以通过安装pythonFlickrAPI实现,而且还可以查询任何标记犬种名称的图像。但是就本实验目的而言,基础数据集已经完全足够。
首先,将所有文件名加载到内存中便于处理。
#definefunctiontoloadtrain,test,andvalidationdatasets
defload_dataset(path):
data=load_files(path)
dog_files=np.array(data[filenames])
dog_targets=np_utils.to_categorical(np.array(data[target]))#,)
returndog_files,dog_targets
#loadtrain,test,andvalidationdatasets
train_files,train_targets=load_dataset(dogImages/train)
valid_files,valid_targets=load_dataset(dogImages/valid)
test_files,test_targets=load_dataset(dogImages/test)
#loadlistofdognames
#the[20:-1]portionsimplyremovesthefilepathandfoldernumber
dog_names=[item[20:-1]foriteminsorted(glob(dogImages/train/*/))]
#printstatisticsaboutthedataset
print(Thereare%dtotaldogcategories.%len(dog_names))print(Thereare%stotaldogimages.%len(np.hstack([train_files,valid_files,test_files])))
print(Thereare%dtrainingdogimages.%len(train_files))
print(Thereare%dvalidationdogimages.%len(valid_files))
print(Thereare%dtestdogimages.%len(test_files)
输出以下统计数据:
Therearetotaldogcategories.
Therearetotaldogimages.
Therearetrainingdogimages.
Therearevalidationdogimages.
Therearetestdogimages.
接下来,将图像的每个像素除以来执行数据标准化步骤,并将输出格式化为张量(可以由keras使用的向量)。注意:以下代码将成千上万个文件作为张量加载到内存中。尽管使用相对较小的数据集就可以实现,但是最好还是使用一次仅能加载少量张量的批量加载系统。至于最后一个设计模型,将在后面的步骤中予以执行。
#definefunctionsforreadinginimagefilesastensors
defpath_to_tensor(img_path,target_size=(,)):
#loadsRGBimageasPIL.Image.Imagetype
#isforxception,fortheothermodels
img=image.load_img(img_path,target_size=target_size)
#convertPIL.Image.Imagetypeto3Dtensorwithshape(,,3)
x=image.img_to_array(img)
#convert3Dtensorto4Dtensorwithshape(1,(target_size,)3)andreturn4Dtensor
returnnp.expand_dims(x,axis=0)
defpaths_to_tensor(img_paths,target_size=(,)):
list_of_tensors=[path_to_tensor(img_path,target_size)forimg_pathintqdm(img_paths)]
returnnp.vstack(list_of_tensors)
#runabovefunctions
fromPILimportImageFile
ImageFile.LOAD_TRUNCATED_IMAGES=True
#pre-processthedataforKeras
train_tensors=paths_to_tensor(train_files).astype(float32)/
valid_tensors=paths_to_tensor(valid_files).astype(float32)/
test_tensors=paths_to_tensor(test_files).astype(float32)/
构建、训练、测试、评估
这一步可以采取许多种办法,其中一些要比另外一些效果更好。本文使用3种特殊的方法,并按照这三种方法进行构建、测试与评估。采取的方法如下:
1.平凡解。在数据集上构建并训练一个非常简单的卷积神经网络,对其性能进行评估。
2.进行迁移学习。利用经大规模图像库训练过的现有卷积神经网络将输入图像转换为“瓶颈特征”(表示图像的抽象特征)以适应应用程序。
3.通过图像增强进行迁移学习。该方法类似于瓶颈特征方法,但是将尝试为应用程序创建模型来获得更优的模型泛化能力;创建的模型是一个预先训练且具有瓶颈特征并携带自定义输出层的卷积神经网络堆叠,其输入为经过象形转换随机增强的图像。
首先,将演示创建基本卷积神经网络以及在数据集上进行训练的简单方法。
步骤2a:构建平凡模型
使用带有tensorflow后端的keras创建一个带有以下代码的简易卷积神经网络。
fromkeras.layersimportConv2D,MaxPooling2D,GlobalAveragePooling2D
fromkeras.layersimportDropout,Flatten,Dense
fromkeras.modelsimportSequential
model=Sequential()
#Definemodelarchitecture.
model.add(Conv2D(16,kernel_size=2,activation=relu,input_shape=(,,3)))
#activationnonlinearitytypicallyperformedbeforepooling
model.add(MaxPooling2D())#defaultstopool_size=(2,2),stride=None=pool_size
model.add(Conv2D(32,kernel_size=2,activation=relu))
model.add(MaxPooling2D())
model.add(Conv2D(64,kernel_size=2,activation=relu))
model.add(MaxPooling2D())
model.add(GlobalAveragePooling2D())
model.add(Dense(,activation=softmax))
model.summary()
使用model.summary()方法打印输出以下模型结构:
此处,利用3个与最大池化配对并终止与个节点全连接层的卷积层创建一个8层顺序神经网络,其每一层对应一种预测类别。注意:密集层使用了归一化指数激活函数;原因是它的范围是0-1而且强制输出层中所有节点的总和为1。这就可以将单个节点的输出解释为模型预测概率,即输入是该节点所对应的类别。换句话说,如果图层中的第二个节点对于特定图像来说具有0.8的激活值,就可以说模型预测输入来自第二类的概率是80%。注意:19,个模型参数指的是网络将尝试优化的权重、偏差以及卷积核(卷积滤波器)。现在应该明白为什么这个过程就计算方面来说要求非常高。
最后,对该模型进行编译以便于训练。注意:这一步可以使用多种损失函数和优化器,但目前对多类别图像标签预测通常使用Adam作为优化器,使用分类交叉熵作为损失函数。我对Adam与SGD和RMSProp进行测试比较,发现Adam训练速度更快。
model.
转载请注明地址:http://www.1xbbk.net/jwbjj/1295.html