第八届中国Python开发者大会PyConChina2018,由PyChina.org发起,由来自CPyUG/TopGeek等社区的30位组织者,近150位志愿者在北京、上海、深圳、杭州、成都等城市举办。致力于推进各种Python相关的技术在互联网、企业应用等领域的研发和应用。
代码医生工做室有幸接受邀请,参加了此次会议的北京站专场。在会上主要分享了《人工智能实战案例分享-图像处理与数值分析》。
会上分享的一些案例主要是来源于《python带我起飞——入门、进阶、商业实战》一书与《深度学习之TensorFlow:入门、原理与进阶实战》一书。另外,还扩充了若干其它案例。在本文做为补充,将会上分享的其它案例以详细的图文方式补充进来,并提供源码。共分为4期连载。
用slim调用PNASNet模型python
用slim微调PNASNet模型git
用对抗样本攻击PNASNet模型github
恶意域名检测实例api
使用AI模型来识别图像是桌子、猫、狗,仍是其余
数组
本章将演示一个应用AI模型进行图像识别的例子。经过该实例可以让读者真真切切的感觉到AI的强大,及使用模型的操做过程。
bash
案例描述
网络
经过代码载入现有模型,对任意图片进行分类识别,观察识别结果。
框架
本案使用的是在ImgNet数据集上训练好的PNASNet模型。PNASNet模型是目前最优秀的图片识别模型之一。该模型在ImgNet数据集上训练后,能够识别1000种类别的图片。要完成该案例,须要先下载TensorFlow中的models模块及对应的与训练模型。下面就来详细介绍。函数
代码环境及模型准备
学习
为了使读者可以快速完成该实例,直观上感觉到模型的识别能力,能够直接使用本书配套的资源。并将其放到代码的同级目录下便可。
若是想体验下从零开始手动搭建,也能够按照下面的方法准备代码环境及预编译模型。
1. 下载TensorFlow models模块
TensorFlow models模块中包含了使用TensorFlow框架完成的各类不一样模型,能够直接拿来使用。在TensorFlow models模块中进行二次开发,可使AI项目开发变得简单快捷。来到如下网址:
能够经过git 将代码clone下来,也能够手动下载(具体操做见《深度学习之TensorFlow:入门、原理与进阶实战》一书的8.5.2节)。
2. 部署TensorFlow slim模块
解压以后,将其中\models-master\research路径下的slim文件夹(如图1),复制到本地代码的同级路径下。
图1 slim代码库路径
slim库又叫作TF-slim,是TensorFlow 1.0以后推出的一个新的轻量级高级API接口。将不少常见TensorFlow函数作了二次封装,使代码变得更加简洁。
在TF-slim模块里面同时提供了大量用TF-slim写好的网络模型结构代码,以及用该代码训练出的模型文件。本例中就是使用TF-slim模块中训练好的PNASNet模型文件。
3. 下载PNASNet模型
访问以下网站,能够下载训练好的PNASNet模型:
该连接打开后,能够找到“pnasnet-5_large_2017_12_13.tar.gz”的下载地址,如图2。
图2 PNASNet模型下载页面
下载完后,将其解压,会获得以下图3中的文件结构。
图3 PNASNet模型文件
将整个pnasnet-5_large_2017_12_13文件夹放到本地代码的同级目录下。在使用时,只须要指定好模型的路径:“pnasnet-5_large_2017_12_13”,系统便会自动加载模型里面的文件及内容。
注意:
4. 准备ImgNet数据集标签
因为本例中使用的PNASNet预训练模型是在ImgNet数据集上训练好的模型,在使用该模型分类是,还须要有与其对应的标签文件。slim中已经将得到标签文件的操做直接封装到了代码里,直接调用便可。因为标签文件是英文分类,读起来不太直观。这里提供了一个翻译好的中文标签分类文件“中文标签.csv”。也在书籍同步的配套资源中。
前面4项都准备好后,总体的目录结构如图4所示。
图4 实例1文件结构
在图4中,会看到还有三个图片文件“72.jpg”、“hy.jpg”、“ps.jpg”,这三个文件是用于测试使用的图片,读者能够替换为本身所要识别的文件。
代码实现:初始化环境变量,并载入ImgNet标签
首先将本地的slim做为引用库载入到系统的环境变量里。接着将ImgNet标签载入并显示出来。
import sys #初始化环境变量
nets_path = r'slim'
if nets_path not in sys.path:
sys.path.insert(0,nets_path)
else:
print('already add slim')
import tensorflow as tf #引入头文件
from PIL import Image
from matplotlib import pyplot as plt
from nets.nasnet import pnasnet
import numpy as np
from datasets import imagenet
slim = tf.contrib.slim
tf.reset_default_graph()
image_size = pnasnet.build_pnasnet_large.default_image_size #得到图片输入尺寸
labels = imagenet.create_readable_names_for_imagenet_labels() #得到数据集标签
print(len(labels),labels) #显示输出标签
def getone(onestr):
return onestr.replace(',',' ')
with open('中文标签.csv','r+') as f: #打开文件
labels =list( map(getone,list(f)) )
print(len(labels),type(labels),labels[:5])
复制代码
使用AI模型来识别图像
代码中提供了英文与中文的两种标签。在实际应用中使用了中文的标签。程序运行后输出结果以下:
1001 {0: 'background', 1: 'tench, Tinca tinca', 2: 'goldfish, Carassius auratus', 3: 'great white shark, white shark, man-eater, man-eating shark, Carcharodon carcharias', 4: 'tiger shark, Galeocerdo cuvieri', 5: 'hammerhead, hammerhead shark',……,994: 'gyromitra', 995: 'stinkhorn, carrion fungus', 996: 'earthstar', 997: 'hen-of-the-woods, hen of the woods, Polyporus frondosus, Grifola frondosa', 998: 'bolete', 999: 'ear, spike, capitulum', 1000: 'toilet tissue, toilet paper, bathroom tissue'}
1001 <class 'list'> ['背景known \n', '丁鲷 \n', '金鱼 \n', '大白鲨 \n', '虎鲨 \n']
一共输出了两行,第一行为英文标签,第二行为中文标签。
代码实现:定义网络结构
经过代码,定义了占位符input_imgs,用于输入待识别的图片。接着定义网络节点end_points,对接预训练模型的输出节点。end_points是一个字典,里面Predictions对应的值就是最终的输出结果。该值中放置着1000个元素的数组,表明预测图片在这1000个分类中的几率。经过tf.argmax函数对最终结果进行转化,获得数组中最大的那个数的索引,即是该图片的分类。
sample_images = ['hy.jpg', 'ps.jpg','72.jpg'] #定义待测试图片路径
input_imgs = tf.placeholder(tf.float32, [None, image_size,image_size,3]) #定义占位符
x1 = 2 *( input_imgs / 255.0)-1.0 #归一化图片
arg_scope = pnasnet.pnasnet_large_arg_scope() #得到模型命名空间
with slim.arg_scope(arg_scope):
logits, end_points = pnasnet.build_pnasnet_large(x1,num_classes = 1001, is_training=False)
prob = end_points['Predictions']
y = tf.argmax(prob,axis = 1) #得到结果的输出节点
复制代码
使用AI模型来识别图像(续)
在34行代码中的arg_scope是命名空间的意思。在TensorFlow中相同名称的不一样张量是经过命名空间来划分的。关于命名空间的更多知识能够参考《深度学习之TensorFlow:入门、原理与进阶实战》一书的4.3节。
代码中第28行指定了待识别图片的名称。若是想识别本身的图片,直接修改该行代码中的图片名称便可。
代码实现:载入模型进行识别
指定好要加载的预训练模型,创建会话进行图片识别。
checkpoint_file = r'pnasnet-5_large_2017_12_13\model.ckpt' #定义模型路径
saver = tf.train.Saver() #定义saver,用于加载模型
with tf.Session() as sess: #创建会话
saver.restore(sess, checkpoint_file) #载入模型
def preimg(img): #定义图片预处理函数
ch = 3
if img.mode=='RGBA': #兼容RGBA图片
ch = 4
imgnp = np.asarray(img.resize((image_size,image_size)),
dtype=np.float32).reshape(image_size,image_size,ch)
return imgnp[:,:,:3]
#得到原始图片与预处理图片
batchImg = [ preimg( Image.open(imgfilename) ) for imgfilename in sample_images ]
orgImg = [ Image.open(imgfilename) for imgfilename in sample_images ]
yv,img_norm = sess.run([y,x1], feed_dict={input_imgs: batchImg}) #输入到模型
print(yv,np.shape(yv)) #显示输出结果
def showresult(yy,img_norm,img_org): #定义显示图片函数
plt.figure()
p1 = plt.subplot(121)
p2 = plt.subplot(122)
p1.imshow(img_org) #显示图片
p1.axis('off')
p1.set_title("organization image")
p2.imshow(img_norm) #显示图片
p2.axis('off')
p2.set_title("input image")
plt.show()
print(yy,labels[yy])
for yy,img1,img2 in zip(yv,batchImg,orgImg): #显示每条结果及图片
showresult(yy,img1,img2)
复制代码
使用AI模型来识别图像(续)
在TensorFlow中,模型运行时会有个图的概念。在本例中,原始的网络结构会在静态图中定义好,接着经过创建一个会话(代码41行)让当前代码与静态图链接起来。调用sess中的run函数将数据输入到静态图中,并返回结果,从而实现图片的识别。
在模型识别以前,全部的图片都要统一成固定大小的尺寸(代码49行),并进行归一化(代码32行)。这个过程叫作图片预处理。通过预处理后的图片放到模型中,才可以获得准确的结果。
代码运行后,输出结果以下:
结果一共显示了3幅图,3段文字。每幅图片下一行的文字,为模型识别出来的结果。在每幅图中,左侧为原始图片,右侧为预处理后的图片。
结尾
文内代码能够直接运行使用。若是不想手动搭建,还能够下载本文的配套代码。
【代码获取】:关注公众号:xiangyuejiqiren 公众号回复“pycon1”
若是以为本文有用
能够分享给更多小伙伴