机器学习工程师Udacity项目:实现一个狗品种识别算法Apppaulonetwo

在下方的代码单元(cell)中,我们导入了一个狗图像的数据集。我们使用scikit-learn库中的load_files函数来获取一些变量:

importrandomrandom.seed(8675309)#加载打乱后的人脸数据集的文件名human_files=np.array(glob("/data/lfw/*/*"))random.shuffle(human_files)#打印数据集的数据量print('Thereare%dtotalhumanimages.'%len(human_files))Thereare13233totalhumanimages.

在如下代码单元中,我们将演示如何使用这个检测模型在样本图像中找到人脸。

在上方的代码中,faces以numpy数组的形式,保存了识别到的面部信息。它其中每一行表示一个被检测到的脸,该数据包括如下四个信息:前两个元素x、y代表识别框左上角的x和y坐标(参照上图,注意y坐标的方向和我们默认的方向不同);后两个元素代表识别框在x和y轴两个方向延伸的长度w和d。

我们可以将这个程序封装为一个函数。该函数的输入为人脸图像的路径,当图像中包含人脸时,该函数返回True,反之返回False。该函数定义如下所示。

#如果img_path路径表示的图像检测到了脸,返回"True"defface_detector(img_path):img=cv2.imread(img_path)gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)faces=face_cascade.detectMultiScale(gray)returnlen(faces)>0【练习】评估人脸检测模型问题1:在下方的代码块中,使用face_detector函数,计算:

理想情况下,人图像中检测到人脸的概率应当为100%,而狗图像中检测到人脸的概率应该为0%。你会发现我们的算法并非完美,但结果仍然是可以接受的。我们从每个数据集中提取前100个图像的文件路径,并将它们存储在human_files_short和dog_files_short中。

human_files_short=human_files[:100]dog_files_short=train_files[:100]##请不要修改上方代码##TODO:基于human_files_short和dog_files_short##中的图像测试face_detector的表现print(np.mean([face_detector(human)forhumaninhuman_files_short]))print(np.mean([face_detector(dog)fordogindog_files_short]))1.00.11问题2:就算法而言,该算法成功与否的关键在于,用户能否提供含有清晰面部特征的人脸图像。那么你认为,这样的要求在实际使用中对用户合理吗?如果你觉得不合理,你能否想到一个方法,即使图像中并没有清晰的面部特征,也能够检测到人脸?

回答:不合理;使用CNN;

Tips:

补充阅读材料:

我们建议在你的算法中使用opencv的人脸检测模型去检测人类图像,不过你可以自由地探索其他的方法,尤其是尝试使用深度学习来解决它:)。请用下方的代码单元来设计和测试你的面部监测算法。如果你决定完成这个选做任务,你需要报告算法在每一个数据集上的表现。

##(选做)TODO:报告另一个面部检测算法在LFW数据集上的表现###你可以随意使用所需的代码单元数

在实现了图像处理的部分之后,我们就可以使用模型来进行预测。这一步通过predict方法来实现,它返回一个向量,向量的第i个元素表示该图像属于第i个ImageNet类别的概率。这通过如下的ResNet50_predict_labels函数实现。

fromkeras.applications.resnet50importpreprocess_input,decode_predictionsdefResNet50_predict_labels(img_path):#返回img_path路径的图像的预测向量img=preprocess_input(path_to_tensor(img_path))returnnp.argmax(ResNet50_model.predict(img))完成狗检测模型

我们通过这些想法来完成下方的dog_detector函数,如果从图像中检测到狗就返回True,否则返回False。

defdog_detector(img_path):prediction=ResNet50_predict_labels(img_path)return((prediction<=268)&(prediction>=151))【作业】评估狗狗检测模型

问题3:

在下方的代码块中,使用dog_detector函数,计算:

###TODO:测试dog_detector函数在human_files_short和dog_files_short的表现print(np.mean([dog_detector(human)forhumaninhuman_files_short]))print(np.mean([dog_detector(dog)fordogindog_files_short]))0.01.0步骤3:从头开始创建一个CNN来分类狗品种

现在我们已经实现了一个函数,能够在图像中识别人类及狗狗。但我们需要更进一步的方法,来对狗的类别进行识别。在这一步中,你需要实现一个卷积神经网络来对狗的品种进行分类。你需要从头实现你的卷积神经网络(在这一阶段,你还不能使用迁移学习),并且你需要达到超过1%的测试集准确率。在本项目的步骤五种,你还有机会使用迁移学习来实现一个准确率大大提高的模型。

值得注意的是,对狗的图像进行分类是一项极具挑战性的任务。因为即便是一个正常人,也很难区分布列塔尼犬和威尔士史宾格犬。

不难发现其他的狗品种会有很小的类间差别(比如金毛寻回犬和美国水猎犬)。

同样,拉布拉多犬(labradors)有黄色、棕色和黑色这三种。那么你设计的基于视觉的算法将不得不克服这种较高的类间差别,以达到能够将这些不同颜色的同类狗分到同一个品种中。

黄色拉布拉多犬(YellowLabrador)|棕色拉布拉多犬(ChocolateLabrador)|黑色拉布拉多犬(BlackLabrador)

我们也提到了随机分类将得到一个非常低的结果:不考虑品种略有失衡的影响,随机猜测到正确品种的概率是1/133,相对应的准确率是低于1%的。

请记住,在深度学习领域,实践远远高于理论。大量尝试不同的框架吧,相信你的直觉!当然,玩得开心!

数据预处理

通过对每张图像的像素值除以255,我们对图像实现了归一化处理。

fromPILimportImageFileImageFile.LOAD_TRUNCATED_IMAGES=True#Keras中的数据预处理过程train_tensors=paths_to_tensor(train_files).astype('float32')/255valid_tensors=paths_to_tensor(valid_files).astype('float32')/255test_tensors=paths_to_tensor(test_files).astype('float32')/255100%|██████████|6680/6680[01:14<00:00,89.11it/s]100%|██████████|835/835[00:08<00:00,100.40it/s]100%|██████████|836/836[00:08<00:00,101.04it/s]【练习】模型架构

创建一个卷积神经网络来对狗品种进行分类。在你代码块的最后,执行model.summary()来输出你模型的总结信息。

我们已经帮你导入了一些所需的Python库,如有需要你可以自行导入。如果你在过程中遇到了困难,如下是给你的一点小提示——该模型能够在5个epoch内取得超过1%的测试准确率,并且能在CPU上很快地训练。

问题4:

回答:我使用上图提示的步骤搭建卷积网络,该架构能取得很好表现的原因有:1)卷积层对图片中的特征进行局部感知,以便后续从更高层次对局部进行综合操作,从而得到全局信息;2)池化层用于特征降维,压缩数据和参数的数量,减小过拟合,同时提高模型的容错性;MaxPooling能够保留最强的特征,抛弃其他弱的此类特征。GlobalAveragePooling将最后一层的特征进行均值池化,形成一个特征点,将这些特征点组成最后的特征向量以进行softmax计算;3)密集层里是高度提纯的特征,它将进行最后的分类;sigmoid的梯度在饱和区域非常平缓,接近于0,很容易造成梯度消失的问题。而Relu的梯度大多数情况下是常数,有助于解决深层网络的收敛问题。

更进一步,可以尝试不同的模型结构,如更多的卷积层和全连接层、更多的节点数、使用不同类型的正则化层(Dropout、BatchNormalization等)、使用不同的权值初始化方案(truncated_normal、xavier等)、使用不同的激活函数(LeakyReLU、eLU等)、抉择使用Flatten还是GlobalAveragePooling2D等。在实际应用中,你需要根据场景的不同来设计不同的模型架构、使用不同的超参数。对比各类结构和超参数给模型带来的影响,有助于你更好的理解模型的结构。

##编译模型model.compile(optimizer='rmsprop',loss='categorical_crossentropy',metrics=['accuracy'])Tips:

提高准确率有很多小技巧~

通常模型的大小取决于数据的量和复杂度,但是如果你使用max-pooling,你需要增加向上的每一层的神经元(比如你可以double一下)。通常在denselayer之前有2-5层,kernelsize3-5就差不多。你也可以用gridsearch找一组比较满意的参数~

常用的正则化方法:

更多的阅读资料:

【练习】训练模型

问题5:

在下方代码单元训练模型。使用模型检查点(modelcheckpointing)来储存具有最低验证集loss的模型。

keras.callbacks.ModelCheckpoint(filepath,monitor='val_loss',verbose=0,save_best_only=False,save_weights_only=False,mode='auto',period=1)或者你也可以把epoch&modelaccuracy和epoch&modelloss的关系图打印出来,然后找一个比较满意的epoch,参考代码如下:

#Fitthemodelhistory=model.fit(X,Y,validation_split=0.33,epochs=150,batch_size=10,verbose=0)#listalldatainhistoryprint(history.history.keys())#summarizehistoryforaccuracyplt.plot(history.history['acc'])plt.plot(history.history['val_acc'])plt.title('modelaccuracy')plt.ylabel('accuracy')plt.xlabel('epoch')plt.legend(['train','test'],loc='upperleft')plt.show()#summarizehistoryforlossplt.plot(history.history['loss'])plt.plot(history.history['val_loss'])plt.title('modelloss')plt.ylabel('loss')plt.xlabel('epoch')plt.legend(['train','test'],loc='upperleft')plt.show()Tips:

更多阅读材料:

测试模型

在狗图像的测试数据集上试用你的模型。确保测试准确率大于1%。

#获取测试数据集中每一个图像所预测的狗品种的indexdog_breed_predictions=[np.argmax(model.predict(np.expand_dims(tensor,axis=0)))fortensorintest_tensors]#报告测试准确率test_accuracy=100*np.sum(np.array(dog_breed_predictions)==np.argmax(test_targets,axis=1))/len(dog_breed_predictions)print('Testaccuracy:%.4f%%'%test_accuracy)Testaccuracy:2.2727%步骤4:使用一个CNN来区分狗的品种

得到从图像中提取的特征向量(BottleneckFeatures)

bottleneck_features=np.load('/data/bottleneck_features/DogVGG16Data.npz')train_VGG16=bottleneck_features['train']valid_VGG16=bottleneck_features['valid']test_VGG16=bottleneck_features['test']模型架构

该模型使用预训练的VGG-16模型作为固定的图像特征提取器,其中VGG-16最后一层卷积层的输出被直接输入到我们的模型。我们只需要添加一个全局平均池化层以及一个全连接层,其中全连接层使用softmax激活函数,对每一个狗的种类都包含一个节点。

VGG16_model=Sequential()VGG16_model.add(GlobalAveragePooling2D(input_shape=train_VGG16.shape[1:]))VGG16_model.add(Dense(133,activation='softmax'))VGG16_model.summary()_________________________________________________________________Layer(type)OutputShapeParam#=================================================================global_average_pooling2d_2((None,512)0_________________________________________________________________dense_2(Dense)(None,133)68229=================================================================Totalparams:68,229Trainableparams:68,229Non-trainableparams:0_________________________________________________________________Tips:迁移学习的思路就是将一个预训练的模型,通过新的训练集进行二次训练。分为三种形式:

现在,我们可以测试此CNN在狗图像测试数据集中识别品种的效果如何。我们在下方打印出测试准确率。

#获取测试数据集中每一个图像所预测的狗品种的indexVGG16_predictions=[np.argmax(VGG16_model.predict(np.expand_dims(feature,axis=0)))forfeatureintest_VGG16]#报告测试准确率test_accuracy=100*np.sum(np.array(VGG16_predictions)==np.argmax(test_targets,axis=1))/len(VGG16_predictions)print('Testaccuracy:%.4f%%'%test_accuracy)Testaccuracy:41.5072%使用模型预测狗的品种

fromextract_bottleneck_featuresimport*defVGG16_predict_breed(img_path):#提取bottleneck特征bottleneck_feature=extract_VGG16(path_to_tensor(img_path))#获取预测向量predicted_vector=VGG16_model.predict(bottleneck_feature)#返回此模型预测的狗的品种returndog_names[np.argmax(predicted_vector)]

步骤5:建立一个CNN来分类狗的品种(使用迁移学习)

现在你将使用迁移学习来建立一个CNN,从而可以从图像中识别狗的品种。你的CNN在测试集上的准确率必须至少达到60%。

在步骤4中,我们使用了迁移学习来创建一个使用基于VGG-16提取的特征向量来搭建一个CNN。在本部分内容中,你必须使用另一个预训练模型来搭建一个CNN。为了让这个任务更易实现,我们已经预先对目前keras中可用的几种网络进行了预训练:

这些文件被命名为为:

Dog{network}Data.npz其中{network}可以是VGG19、Resnet50、InceptionV3或Xception中的一个。选择上方网络架构中的一个,他们已经保存在目录/data/bottleneck_features/中。

【练习】获取模型的特征向量

在下方代码块中,通过运行下方代码提取训练、测试与验证集相对应的bottleneck特征。

bottleneck_features=np.load('/data/bottleneck_features/Dog{network}Data.npz')train_{network}=bottleneck_features['train']valid_{network}=bottleneck_features['valid']test_{network}=bottleneck_features['test']###TODO:从另一个预训练的CNN获取bottleneck特征bottleneck_features=np.load('/data/bottleneck_features/DogXceptionData.npz')train_Xception=bottleneck_features['train']valid_Xception=bottleneck_features['valid']test_Xception=bottleneck_features['test']Tips:当下比较主流的架构非ResNet-50和Xception莫属~轻易就能达到80%以上的准确率~

【练习】模型架构

建立一个CNN来分类狗品种。在你的代码单元块的最后,通过运行如下代码输出网络的结构:

.summary()

问题6:

在下方的代码块中尝试使用Keras搭建最终的网络架构,并回答你实现最终CNN架构的步骤与每一步的作用,并描述你在迁移学习过程中,使用该网络架构的原因。

回答:1)将Xception最后一层的输出作为全局平均池化层的输入;2)增加一个全连接层,使用softmax激活函数,节点数设置为狗的种类数133。选用Xception是因为该模型在狗狗分类中准确率较高;这一架构会在这一分类任务中成功的原因:1)利用迁移学习获取了优良的模型和参数;2)训练次数提高到了20次;早期(第三步)尝试不成功的原因:1)模型相对来说没有迁移学习中的好;2)训练次数只有5次,太少了。

问题7:

在下方代码单元中训练你的模型。使用模型检查点(modelcheckpointing)来储存具有最低验证集loss的模型。

训练过程中,注意到第2次epoch之后验证误差就几乎没有提升了,同时因为你保存了最优模型,意味着你后面的训练都是在浪费计算资源;同时也观察到,第20次epoch时,验证误差远大于训练误差,这说明模型出现了过拟合。思考并尝试尽量减轻这种过拟合现象吧~

提示:

【练习】测试模型

问题8:

在狗图像的测试数据集上试用你的模型。确保测试准确率大于60%。

###TODO:在测试集上计算分类准确率Xception_predictions=[np.argmax(Xception_model.predict(np.expand_dims(feature,axis=0)))forfeatureintest_Xception]test_accuracy=100*np.sum(np.array(Xception_predictions)==np.argmax(test_targets,axis=1))/len(Xception_predictions)print('Testaccuracy:%.4f%%'%test_accuracy)Testaccuracy:83.9713%【练习】使用模型测试狗的品种

实现一个函数,它的输入为图像路径,功能为预测对应图像的类别,输出为你模型预测出的狗类别(Affenpinscher,Afghan_hound等)。

与步骤5中的模拟函数类似,你的函数应当包含如下三个步骤:

提取图像特征过程中使用到的函数可以在extract_bottleneck_features.py中找到。同时,他们应已在之前的代码块中被导入。根据你选定的CNN网络,你可以使用extract_{network}函数来获得对应的图像特征,其中{network}代表VGG19,Resnet50,InceptionV3,或Xception中的一个。

问题9:

###TODO:写一个函数,该函数将图像的路径作为输入###然后返回此模型所预测的狗的品种defXception_predict_breed(img_path):bottleneck_feature=extract_Xception(path_to_tensor(img_path))predicted_vector=Xception_model.predict(bottleneck_feature)returndog_names[np.argmax(predicted_vector)]

步骤6:完成你的算法

实现一个算法,它的输入为图像的路径,它能够区分图像是否包含一个人、狗或两者都不包含,然后:

我们非常欢迎你来自己编写检测图像中人类与狗的函数,你可以随意地使用上方完成的face_detector和dog_detector函数。你需要在步骤5使用你的CNN来预测狗品种。

下面提供了算法的示例输出,但你可以自由地设计自己的模型!

问题10:

在下方代码块中完成你的代码。

###TODO:设计你的算法###自由地使用所需的代码单元数吧defdog_check(img_path):ifdog_detector(img_path):print('It''sadog.Itlookslike')print(Xception_predict_breed(img_path))elifface_detector(img_path):print('It''shuman.Itlookslike')print(Xception_predict_breed(img_path))else:print('Error!')

THE END
1.白色狗狗种类大全宠物狗的种类按体型分,可以分为大型犬、中型犬、小型犬和玩具犬等;按毛发的长短分,可以分为长毛犬和短毛犬。常见的大型犬品种有大白熊犬、圣伯纳犬、苏格兰牧羊犬、阿拉斯加雪橇犬、藏獒、罗威纳犬等;常见的中型犬品种有拉布拉多、中华田园犬、柯基犬、萨摩耶、边境牧羊犬等。常见的小型犬品种有博美、贵宾犬、雪纳瑞、...https://www.isdpp.com/issue-13112.html
2.收藏?24种狗狗分类大全,你的狗狗属于哪一类按照功能的不同,狗勾主要分为⑥种类别 每种类别下包含哪些狗勾呢?先点赞再收藏 顺便分享给朋友一起涨姿势吧 伴侣犬 不参与工作,仅为人类做伴,常给老人、贵夫人等女性,还有小孩带来乐趣的犬这类犬中不同品种的体型和性格有很大差异有的形体小巧,有的高大健壮有的性格活泼,有的优雅精致 梗犬 是...https://m.dianping.com/ugcdetail/143783993?sceneType=0&bizType=29&msource=baiduappugc
3.土狗统称中华田园犬?其实这39种“土狗”……都是品种犬!因为根本叫不出它们的品种 但其实我国是历史悠久的产狗大国 只是因为长时间缺少犬种培育的习惯 导致一些狗狗的品种血统混杂 不过 至今仍保留下来40多种 纯正且古老的原产地品种犬 今天就带大家来认识一下它们 说不定这里就有你遇到的那只“大黄”呢! https://pets.sohu.com/a/568117493_100190938
1.狗狗品种的分类你都了解吗?狗狗品种的分类你都了解吗? 世界各地对于犬的分发各有不同,美国的分类法是较为广为接受的一种。它是将狗以它们最初被人们所用于的领域而分为七大类: 1、猎犬Hounds 此类犬都有一个古老的狩猎特性,它们都有很强的嗅觉能力去追踪猎物,而且它们都拥有很快的奔跑速度。 https://www.unjs.com/z/1299007.html
2.小狗都有什么品种常见小狗种类介绍网址: 小狗都有什么品种 常见小狗种类介绍 https://m.mcbbbk.com/newsview591210.html 所属分类:萌宠日常 上一篇: 小狗品种都有啥 小型宠物狗品种介 下一篇: 宠物狗介绍 最新分享 宠物月饼:节日新风尚,宠物的特殊礼物 宠物节日寄养“一笼难求”?热点...https://m.mcbbbk.com/newsview591210.html
3.狗狗的种类分别有哪些(狗狗的种类分别有哪些品种)知道大有可为答主 回答量11万 采纳率87% 帮助的人137万 我也去答题访问个人页 关注 展开全部 狗的品种一般分为三个种类 1,小型犬比熊,博美,吉娃娃,迷你雪纳瑞,柯基,***尖嘴,约克夏,巴哥,京巴,西高地白梗蝴蝶。 根据提醒而言可将狗狗分为大中小三类,按照被毛的特性分类可将分为丝毛犬刚毛犬长毛犬短毛犬等等...http://m.boqii.com/article/520715.html
4.狗的种类有哪些狗狗品种有哪些?暂无答案,快来添加答案吧 https://www.lovechongbang.com/dogbaike/10398.html
5.犬类学概述宠物狗狗品种分类与特性分析犬类学是研究各种野生及家养动物中的一门科学,它专注于对犬科动物(Canidae)的生物学、行为习惯以及它们在人类社会中的作用进行研究。对于我们来说,了解不同品种之间的差异及其适应环境能力,对于选择合适的宠物非常重要。 二、宠物狗dog品种大全 2.1 各国名犬 ...https://www.778sjdhfg.cn/geng-duo-chong-wu/53821.html
6.狗的品种大全常见宠物狗种类有哪些→MAIGOO知识摘要:现在好多人喜欢养狗,宠物狗的类型也多了起来,有的狗养起来非常复杂,有的狗没什么讲究。市面上常见的宠物狗品种有很多,包括哈士奇、藏獒、金毛、贵宾、萨摩耶、博美、雪纳瑞、苏牧、松狮犬、北京犬、吉娃娃、阿拉斯加雪橇犬、喜乐蒂牧羊犬等等,接下来就和小编一起来看看吧。 https://m.maigoo.com/goomai/182080.html
7.178種狗狗品種大全,按體型分類,你都知道哪些?點擊箭頭處大愛狗狗控,國內最大狗狗微信平台根據美國AKC標準,純種狗狗共178個品種,它們按體型分為:...http://petonea.com/9230/
8.178种狗狗品种大全,按体型分类,你都知道哪些?根据美国AKC标准,纯种狗狗共178个品种,它们按体型分为:超小型、小型、中型、大型、超大型。来看看各种体型的都有哪些? 1.超小型犬:(共4种,标准身高25cm,体重4kg以下) 2.小型犬:(共50种,标准身高25-40cm,体重4-10kg) 3.中型犬:(共54种,标准身高41-60cm,体重11-30kg) ...https://m.wang1314.com/doc/webapp/topic/21115852.html
9.土狗的品种和种类土狗,又称村犬、野狗、农狗,是生活在农村、小镇或城市里街头巷尾的一类狗,通常没有一个明确的犬种归属,是大杂烩的混合品种。由于缺乏统一的系统分类和命名规范,它们的品种和种类也是比较复杂的。本文将尝试从地域、形态、用途等方面,对土狗的品种和种类进行归纳和梳理。 https://www.chongwugo.cn/12157.html
10.152个品种的狗狗名字介绍大全,152个品种的狗狗名字介绍大全及图片...从我小时候家里开始养狗到我长大自己养狗,有近30年与狗狗打交道历史了,全球狗狗品种有至少400种,而根据我的梳理,较常见的狗狗品种有150种左右,还有很多不常见的,以及后期培育出来的新品种。金毛 属于匀称、有力、活泼的一个犬种,特征是稳固、身体各部位配合合理,腿既不太长也不笨拙,表情友善,个性热情、机警、...https://chagougou.com/47472.html