⽤预训练好的深度神经⽹络Inceptionv3来进⾏图像分类
本教程主要参考并⼤部分(代码全参考)知乎作者活鱼眼的教程,接下来还会有更多参考该作者学的东西。很棒的作者,在他的Github上有源码,以及YouTube视频教程
这⾥会⽤到作者之前写的⼀些代码,所以去Github下载的时候建议全部下载,如果你⽐较懒,可以去我的CSDN所有包。
----------------------------------进⼊主题------------------------------------------------------------
⽬的:
这篇教程演⽰了如何⽤⼀个预训练好的深度神经⽹络Inception v3来进⾏图像分类。
Inception v3模型在⼀台配有 8 Tesla K40 GPUs,⼤概价值$30,000的野兽级计算机上训练了⼏个星期,因此不可能在⼀台普通的PC上训练。我们将会下载预训练好的Inception模型,然后⽤它来做图像分类。
Inception v3模型⼤约有2500万个参数,分类⼀张图像就⽤了50亿的乘加指令。在⼀台没有GPU的现代PC上,分类⼀张图像转眼就能完成。
这篇教程隐藏了TensorFlow代码,因此可能不要求很多的TensorFlow经验,当然从之前的教程中学到⼀些对TensorFlow的基本理解还是很有帮助的,特别是在你想学习inception.py⽂件中的实现细节时。
流程图:
下⾯的流程图显⽰了Inception v3模型中的数据流向,这是⼀个带有许多层的,有着复杂结构的卷积神经⽹络。这篇论⽂⾥有Inception模型如何构造,以及为什么这么设计的更多细节。但作者也承认他们并不完全明⽩模型的⼯作原理。具体的结构可以参考⽂章
注意,Inception模型有两个softmax输出。⼀个是在训练神经⽹络时使⽤(Mixed-6e阶段使⽤),另⼀个是训练结束之后,在图像分类时使⽤,即推断阶段(inference)。
显⽰⽹络结构:这是在Jupyter下写的代码,并且要在你下载的代码包的位置打开Jupyter,如图:
在下载的⽂件⾥,有⼀个images⽂件,⾥⾯07是改⽹络的结构图,把它显⽰出来
from IPython.display import Image, display
Image('images/07_inception_flowchart.png') #在同⼀个⽬录下才可以不写绝对路径,否则出错
导⼊包:
%matplotlib inline
import matplotlib.pyplot as plt
import tensorflow as tf
import numpy as np
import os
# Functions and classes for loading and using the Inception model.
import inception
#这个inception⽂件也在同⼀⽬录下
顺便检查⼀下tensorflow版本号
tf.__version__
#检查tensorflow版本号
下载Inception模型
从⽹上下载Inception模型。这是你保存数据⽂件的默认⽂件夹。如果⽂件夹不存在就⾃动创建inception.data_dir = 'inception/'
inception.maybe_download() # 下载V3模型包以及解压
#注意,这⾥如果下载出错,可以直接把⽂件复制进去(在其他地⽅已经下载好的)
Downloading Inception v3 Model ...
Data has apparently already been downloaded and unpacked.
载⼊Inception模型
载⼊模型,为图像分类做准备。注意这些warning信息,以后可能会导致程序运⾏失败
model = inception.Inception()
我们可以去看⼀下inception.py⽂件⾥有些什么功能。
----------------以下代码分析作者写的inception⽂件⾥的功能,算是插⼊,不要带进你⾃⼰的代码--------------
1.从⽹上获取Google 预训练好的Inception下载地址,将下载好的数据保存在data_dir⽂件夹⾥边
data_url = "/models/image/"
data_dir = "inception/"
# File containing the mappings between class-number and uid. (Downloaded)
# 包含类号和uid之间的映射的⽂件。
path_uid_to_cls = "imagenet_2012_challenge_label_map_proto.pbtxt"
# File containing the mappings between uid and string. (Downloaded)
# 包含⼈类标签和uid之间的映射的⽂件。
path_uid_to_name = "imagenet_synset_to_human_"
# File containing the TensorFlow graph definition. (Downloaded)
# 包含TensorFlow 图⽂件
path_graph_def = "classify_image_graph_def.pb"
2.有⼀个maybe_download()函数,会调⽤download.py⽂件的下载⽅法,从⽽把inception⽹络下载下来。读者需要分清我们这个inception.py⽂件和Inception⽹络的区别,后者才是我们要进⾏图像分类的。
3.⼀个NameLookup的类,这个类(class)主要作⽤是查每⼀类(共1000类)名字,因为⽂件⾥边将1000类都定义⼀个编号,我们需要输出的是名字⽽不是编号,最后得到3个映射关系:编码到类别、类别到编码、编码到名字之间的映射关系,
4.inception类
这⼀类主要就是调⽤原始模型进⾏分类,输出预测值等。其他的类暂不介绍。
------------------------------------------------继续---------------------------------------------------------
构造分类函数
# 分类以及绘制图像的帮助函数这,是⼀个简单的封装函数,它可以展⽰图像,然后⽤Inception模型进⾏分类,最终打印出分类评分。
def classify(image_path):
# Display the image.
display(Image(image_path))
# Use the Inception model to classify the image.
pred = model.classify(image_path=image_path)
# Print the scores and names for the top-10 predictions.
model.print_scores(pred=pred, k=10, only_first_name=True)
⽤⾃⼰的图去预测
# 对熊猫进⾏分类
#Inception数据⽂件中包含了这张熊猫图像。Inception模型相当确定这张图⽚上展⽰了熊猫,
#分类评分达到了89.23%,第⼆⾼的代表⼤狐猴的分数只有0.86%,这是另外⼀种外来动物。
image_path = os.path.join(inception.data_dir, 'cropped_panda.jpg')
classify(image_path)
分类评分的解释 Inception模型的输出是Softmax函数,这在之前教程中的神经⽹络中也有⽤到。
softmax输出有时也称为概率分布(probabilities),因为它介于零到⼀之间,然后相加为⼀,与概率分布相同。但它们并不是传统语义上的概率分布,因为并不是由重复试验得来。
将神经⽹络的输出值称为分类评分或排名可能会更好,因为结果显⽰了神经⽹络认为输⼊图像是每个可能分类的强度。
在上⾯的熊猫样本中, Inception模型给熊猫类型很⾼的分数—89.23%,同时其它999种类别的分数都在1%以下。这表⽰Inception模型⼗分确信图像展⽰了⼀只熊猫,⽽剩下1%以下的应该视为噪声。⽐如,
排名第⼗⾼的分数是0.05%,代表电⼦⼿表,但它更可能是由于神经⽹络的不精准⽽不是暗⽰着图像看起来有点像电⼦⼿表。
有时Inception模型不确定图像属于哪⼀个分类,因此结果中并没有⼀个特别⾼的分数。下⾯会展⽰这种样本
#鹦鹉(原始图像)
#Inception模型⼗分确定(评分97.30%)这张图像展⽰了⼀种叫⾦刚鹦鹉的鹦鹉。
classify(image_path="images/parrot.jpg")
#鹦鹉(调整图像)
#Inception使⽤于299 x 299像素的输⼊图像。上⾯的鹦鹉图像实际上是320像素宽、785像素⾼的,因此它将由Inception模型⾃动缩放。#现在我们想看看被Inception模型调整过的图像。
#⾸先我们实现⼀个帮助函数,⽤来从Inception模型内部获取调整过的图像。
def plot_resized_image(image_path):
# Get the resized image from the Inception model.
resized_image = _resized_image(image_path=image_path)
# Plot the image.
resizedplt.imshow(resized_image, interpolation='nearest')
# Ensure that the plot is shown.
plt.show()
现在画出调整过的鹦鹉图。这是Inception模型中神经⽹络的真正输⼊图像。我们可以看到它被压缩成正⽅形,并且分辨率降低了,因此图像看起来更像素化和锯齿状。这种情况下,图像仍然清晰地展⽰了⼀只鹦鹉,但⼀些图像经过(模型内)原⽣的调整后会变得扭曲,因此你可能会想⾃⼰调整图像⼤⼩,再输⼊到Inception模型。
plot_resized_image(image_path="images/parrot.jpg")
鹦鹉(裁剪图像,上⽅)鹦鹉图像被⼿动裁剪成299 x 299像素⼤⼩,然后输⼊到Inception模型中,这时(模型)还是很确信(评分97.52%)输⼊图展⽰了⼀只鹦鹉(⾦刚鹦鹉)
classify(image_path="images/parrot_cropped1.jpg")
鹦鹉(裁剪图像,中间)这是鹦鹉图的另⼀张裁剪图像,这次展⽰了鹦鹉的躯⼲,不包含头部和尾巴。Inception模型仍然很确定(评分94.22%)这是⼀只⾦刚鹦鹉。
classify(image_path="images/parrot_cropped2.jpg")
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论