第八屆中國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」
若是以爲本文有用
能夠分享給更多小夥伴