[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:各位敲代码的一定要考虑维护问题,不要即兴发挥,能封装起来就封装起来,不然将来自己维护会吃亏的(如果你是要给别人维护就当我没说,不过要保护好自己

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