[2020/05/12 更新] Django調用Keras的模型

導入模型

from keras.models import load_model
model = load_model('xx.h5')

使用Django調用Keras模型的接口,首先第一步是導入Keras模型,作爲一個全局變量,注意是全局變量,很多教程教的都是,每調用一次接口都導入一次模型,自己試了就知道,導入模型是一個很耗時的過程,不利於高速計算。
這裏有個大坑,當Django導入或者創建模型後,使用模型進行第一次預測,會出現漫長的初始化,正常來說,我們單線程運行時,會在生成模型的時候進行初始化,這是TensorFlow的一個坑。雖然之後再預測都不會出現長時間的初始化,但是還是要符合現實邏輯,在創建模型的時候進行初始化。

方法一:

import Keras
keras.backend.clear_session()

這個方法是網上的,我沒試過

方法二:

model.predict(data_temp)

直接在創建模型後,立即進行一次數據預測,這個方法我感覺也簡單粗暴。

在這裏插入圖片描述

模型調用

這個纔是Django結合Keras最坑人的地方。
爲了預測方便,往往會把預測封裝成接口,當點擊選擇文件後就會去調用接口進行計算,邏輯上沒有任何問題,但是這裏Keras會報錯。

不同版本的Keras會有不同的報錯,這裏不放具體什麼報錯,都沒有用。像是線程報錯,什麼tensor報錯,一堆問題,其實就只是很簡單的版本問題。

Keras更新後會有各種衝突,只要換回2.2.5版本即可。

pip uninstall keras
pip install keras==2.2.5

換完可能還是報錯,但是不用怕,運行後看TensorFlow的初始化輸出,有很多的警告(Warning),按照警告的提示的方法,把TensorFlow源碼的方法替換成新版本的,替換完就可以放心地多次調用predict。
網上的解決方法是每次調用predict前重新導入模型,其實只要繼續挖掘就能發現是版本更新的問題。

PS:舊版本的Keras的save和load存在區別,如果換回舊版,記得重新保存一次模型。


2020/04/04 更新


方法三:
今天發現了一個新的操作,特地更新一波,只要把模型放在線程裏面就可以了,方法一和二都是把模型放在全局變量區進行調用。

如果是把模型放在線程中,模型只生存在線程中,那麼操作就變成了監聽隊列,當我們有數據進來,就可以把數據插入到隊列中,線程是個while(flag){ if (queue.havesomething){ … } }的結構,當監聽到隊列有數據,就可以獲取數據,然後進行預測,那麼也是實現了從程序運行開始只使用一個模型。

from keras.models import load_model
class MyThread(Thread):
    def __init__(self, input_queue, output_queue ):
        super().__init__()
        self.input_queue = input_queue # 輸入隊列
        self.output_queue = output_queue # 輸出隊列
		self.model = load_model('xx.h5') # 導入模型
		self.flag = True # 用於線程中斷

    def run(self):
        while flag:
        	# 判斷隊列是否有數據
        	if not self.input_queue.empty():
	            data = self.input_queue.get()
	            result = self.model.predict(data)
	            self.output_queue.put(result)

這個方法可以避免重複初始化模型,有個大bug要考慮的就是線程初始化,有可能線程初始化很慢,然後你的電腦CPU又很快,就會出現主線程調用thread.run()時,線程還沒初始化完全,就會炸程序,主線程可以加個sleep來延遲,給線程初始化一點時間。


2020/04/13 更新


很久沒有用TensorFlow,電腦更新了好幾次顯卡驅動,今天運行了一下以前的代碼,發現全部GG,一開始以爲是CUDA和CUDNN變得不兼容,然後測了mxnet,發現還是可以運行,最後查到就是Keras這噁心的配置把GPU內存全部拿了==
報錯:

Failed to get convolution algorithm. This is probably because cuDNN failed to initialize

解決代碼:
在開頭加上Keras配置

import tensorflow as tf
config = tf.compat.v1.ConfigProto(allow_soft_placement=True)
config.gpu_options.per_process_gpu_memory_fraction = 0.3
tf.compat.v1.keras.backend.set_session(tf.compat.v1.Session(config=config))

2020/05/12 補充

有人問我關於Django調用Keras的目錄結構,首先按照原始的結構就行,Keras算法部分我是封裝成一個keras_class類在model.py的文件裏,然後我在model.py全局變量區域實體了一個model = keras_class(),另外在這個文件中又用一個predict函數封裝了預測的部分,最後再全局變量區調用一次predict函數(原因看方法二)。

以上準備工作完成,接着在view.py中

from model import predict
# 注意model.py的文件位置,如果在某個xxx文件夾裏面要補上‘xxx.model’

一般來說只會把你的模型當做黑匣子,你給它輸入數據,它給你輸出結果,所以view.py中只會用到predict這個封裝好的函數

只要前面各種庫兼容不衝突,你的算法沒問題,理論上這些用這個方法不會出事

PS:各位敲代碼的一定要考慮維護問題,不要即興發揮,能封裝起來就封裝起來,不然將來自己維護會喫虧的(如果你是要給別人維護就當我沒說,不過要保護好自己

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章