机器学习工程师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.现代狗的品种分类始于维多利亚时代,既非纯...来自界面文化现代狗的品种分类始于维多利亚时代,既非纯粹也不古老( 来自 @界面 )约克夏、斗牛、萨摩耶……如今我们熟知的各类狗狗品种分类仅有150余年历史。http://t.cn/EXdreNs https://weibo.com/6031682587/HqkFbo1eo
1.犬类多样性探究宠物狗的种类及其视觉特征分析在深入讨论宠物狗的种类之前,我们需要了解犬科(Canidae)作为一个生物分类群体,它包含了包括狼、狐狸、猎豹等在内的大量动物。现代科学将犬科分为两个主要亚科,分别是短吻虎亚科和真犬亚科。其中,真犬亚科又进一步细分成了两大支——家犬属(Canis)和其他野生动物。 https://www.gurotsr.cn/chong-wu-gou/466347.html
2.狗狗品种分类大全世界狗狗品种大全名字狗狗品种分类大全-世界狗狗品种大全名字 世界狗狗品种大全名字 狗狗有很多品种,每个品种都有属于自己种族的特点,比如说金毛这个品种的狗狗就很温顺很友好。那么,世界狗狗的品种有哪些?大型犬宠物怎么起名好听呢? 世界狗狗品种大全名字 金毛寻回犬 是最常见的家犬之一,它属于匀称、有力、活泼的一个大型犬。金毛的独特之处...http://m.boqii.com/article/442442.html
3.狗狗品种的分类你都了解吗?狗狗品种的分类你都了解吗? 世界各地对于犬的分发各有不同,美国的分类法是较为广为接受的一种。它是将狗以它们最初被人们所用于的领域而分为七大类: 1、猎犬Hounds 此类犬都有一个古老的狩猎特性,它们都有很强的嗅觉能力去追踪猎物,而且它们都拥有很快的奔跑速度。 https://www.unjs.com/z/1299007.html
4.178種狗狗品種大全,按體型分類,你都知道哪些?點擊箭頭處大愛狗狗控,國內最大狗狗微信平台 根據美國AKC標準,純種狗狗共178個品種,它們按體型分為:超小型、小型、中型、大型、超大型。來看看各種體型的都有哪些? 1.超小型犬:(共4種,標準身高25cm,體重4kg以下) 2.小型犬:(共50種,標準身高25-40cm,體重4-10kg) ...http://petonea.com/9230/
5.python狗狗品种基于pytorch的猫狗分类python 狗狗品种 基于pytorch的猫狗分类 Pytorch物体识别分类实战案例(上) 前面更新了很多关于pytorch中的函数和模块,但理论学得再好不如实战来得更快,不停地敲敲敲敲代码,你终会变强! 这期的物体识别案例是个人纯手写,主要是用于熟悉pytorch搭建一个完整深度学习项目的所有过程,顺带熟悉pytorch的代码结构,其中包括...https://blog.51cto.com/u_16213584/10993199
6.深度学习图像识别课程毕业项目:狗狗种类识别(4)代码实现六、自己实现狗狗分类整体流程 实现一个算法,它的输入为图像的路径,它能够区分图像是否包含一个人、狗或两者都不包含,然后: 如果从图像中检测到一只狗,返回被预测的品种。 如果从图像中检测到人,返回最相像的狗品种。 如果两者都不能在图像中检测到,输出错误提示。 https://blog.csdn.net/weixin_41770169/article/details/80498138
7.世界狗狗分类世界狗狗分类-可卡 是世界狗狗中的一种犬种,也被称为卡迪根威尔士柯基犬。可卡犬可分为两个不同的品种:彭布洛克威尔士柯基犬和卡迪根威尔士柯基犬。以下是关于可卡犬的一些特征和特点: 体型:可卡犬的体型中等,属于中小型犬种。成年可卡犬的体重大约在12-15公斤之间。https://www.51buydog.com/46474.html
8.工作犬种类有哪些工作犬和宠物犬的区别→MAIGOO知识像导盲犬、缉毒犬等工作犬,对狗狗的要求都比较高,也有一些固定、专门的品种,普通的宠物狗是不会导盲、缉毒的,而且也很难学会。 part 02 工作犬证怎么办理 注册程序 1、 犬主填写犬籍注册登记申报表,表格可向工作犬协会直接索取或从工作犬协会网站下载。 2、 注册机构受理犬籍注册申请后,应对申请注册登记...https://m.maigoo.com/goomai/242161.html
9.从Chandler和Joey家的那条大白狗说起三. 按犬的品种分类 1. 灵缇犬(greyhound),也就是Chandler和Joey家的那条白色大陶瓷狗的品种,一种身纤细、腿瘦长、善奔跑的狗。 2. 贵宾犬(poodle) 例句:《老友记》第一季第13集 Gloria Tribbiani: Ever since that poodle-stuffer came along, he's been so ashamed of himself that he's been more att...https://www.douban.com/note/652809812/
10.动物百科狗狗动物百科狗狗分类动物百科解释:(1)(~儿)狗的一个品种,体小,毛长,腿短。供玩赏。也叫狮子狗或巴儿狗。(2)比喻驯顺的奴才。 5、狗熊 造句:前一阵子,我和我小舅子一起搞了一个固定门口垃圾桶的小玩意儿。有了这个,夜里就不怕狗熊还是浣熊啥的把垃圾桶搞翻,在撒的满地的垃圾里捡吃的 ...https://www.njdsmedia.com/liuxuezhishi/2682.html
11.苏格兰猎鹿犬狗狗品种介绍狗狗百科苏格兰猎鹿犬_狗狗品种介绍 导语:本文介绍苏格兰猎鹿犬的品种、生活习性和狗狗的血统,提供苏格兰猎鹿犬的照片分享,饲养和繁殖苏格兰猎鹿犬的注意事项,让广大铲屎官能够养好苏格兰猎鹿犬。 基本信息栏 英文名:ScottishDeerhound 性格:安静、高贵、敏锐、警觉 祖籍:苏格兰...https://www.ibabubu.com/ziran/14604.html
12.狗狗的品种有哪些?狗狗的品种可以说是非常多的,如果要把目前世界上300多个狗狗的品种进行确切的分类,似有较大的难度。 如果是按照体型来分类的话可以分为超小型犬、小型犬、中型犬、大型犬、超大型犬。 超小型犬标准: 体重<4kg,身高<25cm 这种犬类体型非常的小巧,像吉娃娃、约克夏、小鹿犬、马耳他犬都属于超小型犬。 https://www.518000pet.com/news/126.html
13.你知道你的爱犬属于哪一类吗?最全的狗狗分类都在这最全的狗狗分类都在这 每种狗狗都有独特的习性和性格,在选择自己的爱宠前,需要对狗狗做一番了解,以判断是否符合自己,是喜欢安静的狗狗还是好动的狗狗,是要找玩伴还是工作犬。以下狗狗的分类标准,沿用了英国养犬协会(The Kennel Club)的狗狗分类标准。 英国养犬协会成立于 1876年(严格说应为1873年4月4日在伦敦...https://www.jianshu.com/p/ed559742d9d2