1. 程式人生 > 程式設計 >使用Keras訓練好的.h5模型來測試一個例項

使用Keras訓練好的.h5模型來測試一個例項

環境:python 3.6 +opencv3+Keras

訓練集:MNIST

下面劃重點:因為MNIST使用的是黑底白字的圖片,所以你自己手寫數字的時候一定要注意把得到的圖片也改成黑底白字的,否則會識別錯(至少我得到的結論是這樣的 ,之前用白底黑字的圖總是識別出錯)

注意:需要測試圖片需要為與訓練模時相同大小的圖片,RGB影象需轉為gray

程式碼:

import cv2
import numpy as np
from keras.models import load_model

model = load_model('fm_cnn_BN.h5') #選取自己的.h模型名稱
image = cv2.imread('6_b.png')
img = cv2.cvtColor(image,cv2.COLOR_RGB2GRAY) # RGB影象轉為gray

#需要用reshape定義出例子的個數,圖片的 通道數,圖片的長與寬。具體的參加keras文件
img = (img.reshape(1,1,28,28)).astype('int32')/255 
predict = model.predict_classes(img)
print ('識別為:')
print (predict)

cv2.imshow("Image1",image)
cv2.waitKey(0)


補充知識:keras轉tf並加速(1)Keras轉TensorFlow,並呼叫轉換後模型進行預測

由於方便快捷,所以先使用Keras來搭建網路並進行訓練,得到比較好的模型後,這時候就該考慮做成服務使用的問題了,TensorFlow的serving就很合適,所以需要把Keras儲存的模型轉為TensorFlow格式來使用。

Keras模型轉TensorFlow

其實由於TensorFlow本身以及把Keras作為其高層簡化API,且也是建議由淺入深地來研究應用,TensorFlow本身就對Keras的模型格式轉化有支援,所以核心的程式碼很少。這裡給出一份程式碼:https://github.com/amir-abdi/keras_to_tensorflow,作者提供了一份很好的工具,能夠滿足絕大多數人的需求了。原理很簡單:原理很簡單,首先用 Keras 讀取 .h5 模型檔案,然後用 tensorflow 的 convert_variables_to_constants 函式將所有變數轉換成常量,最後再 write_graph 就是一個包含了網路以及引數值的 .pb 檔案了。

如果你的Keras模型是一個包含了網路結構和權重的h5檔案,那麼使用下面的命令就可以了:

python keras_to_tensorflow.py 
 --input_model="path/to/keras/model.h5" 
 --output_model="path/to/save/model.pb"

兩個引數,一個輸入路徑,一個輸出路徑。輸出路徑即使你沒建立好,程式碼也會幫你建立。建議使用絕對地址。此外作者還做了很多選項,比如如果你的keras模型檔案分為網路結構和權重兩個檔案也可以支援,或者你想給轉化後的網路節點編號,或者想在TensorFlow下繼續訓練等等,這份程式碼都是支援的,只是使用上需要輸入不同的引數來設定。

如果轉換成功則輸出如下:

begin====================================================
I1229 14:29:44.819010 140709034264384 keras_to_tf.py:119] Input nodes names are: [u'input_1']
I1229 14:29:44.819385 140709034264384 keras_to_tf.py:137] Converted output node names are: [u'dense_2/Sigmoid']
INFO:tensorflow:Froze 322 variables.
I1229 14:29:47.091161 140709034264384 tf_logging.py:82] Froze 322 variables.
Converted 322 variables to const ops.
I1229 14:29:48.504235 140709034264384 keras_to_tf.py:170] Saved the freezed graph at /path/to/save/model.pb

這裡首先把輸入的層和輸出的層名字給出來了,也就是“input_1”和“dense_2/Sigmoid”,這兩個下面會用到。另外還告訴你凍結了多少個變數,以及你輸出的模型路徑,pb檔案就是TensorFlow下的模型檔案。

使用TensorFlow模型

轉換後我們當然要使用一下看是否轉換成功,其實也就是TensorFlow的常見程式碼,如果只用過Keras的,可以參考一下:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import tensorflow as tf
import numpy as np
from tensorflow.python.platform import gfile
import cv2
import os
os.environ["CUDA_VISIBLE_DEVICES"] = "6"
 
# img = cv2.imread(os.path.expanduser('/test_imgs/img_1.png'))
# img = cv2.resize(img,dsize=(1000,1000),interpolation=cv2.INTER_LINEAR)
# img = img.astype(float)
# img /= 255
# img = np.array([img])
 
# 初始化TensorFlow的session
with tf.Session() as sess:
 # 讀取得到的pb檔案載入模型
 with gfile.FastGFile("/path/to/save/model.pb",'rb') as f:
 graph_def = tf.GraphDef()
 graph_def.ParseFromString(f.read())
 # 把圖加到session中
 tf.import_graph_def(graph_def,name='')
 
 # 獲取當前計算圖
 graph = tf.get_default_graph()
 
 # 從圖中獲輸出那一層
 pred = graph.get_tensor_by_name("dense_2/Sigmoid:0")
 
 # 執行並預測輸入的img
 res = sess.run(pred,feed_dict={"input_1:0": img})
 
 # 執行得到結果
 pred_index = res[0][0]
 print('Predict:',pred_index)

在程式碼中可以看到,我們用到了上面得到的輸入層和輸出層的名稱,但是在後面加了一個“:0”,也就是索引,因為名稱只是指定了一個層,大部分層的輸出都是一個tensor,但依然有輸出多個tensor的層,所以需要制定是第幾個輸出,對於一個輸出的情況,那就是索引0了。輸入同理。

如果你輸出res,會得到這樣的結果:

('Predict:',array([[0.9998584]],dtype=float32))

這也就是為什麼我們要取res[0][0]了,這個輸出其實取決於具體的需求,因為這裡我是對一張圖做二分類預測,所以會得到這樣一個結果

執行的結果如果和使用Keras模型時一樣,那就說明轉換成功了!

以上這篇使用Keras訓練好的.h5模型來測試一個例項就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支援我們。