解决同时加载多个Keras Model发生异常的问题

因为工作需要,同一个进程会使用到两个Keras Model, 我是通过写了一个KerasUtil类,然后创建了多个此类对象,以加载不同的Model:

kerasutil_merge = KerasUtil(rawtextpath=r'va_new/model/rawcontent/vamergebinary.csv',
                            lstmmodelpath=r'va_new/model/vamergebinarybilstm.h5',
                            modeltype='bilstm')
kerasutil_added = KerasUtil(rawtextpath=r'va_new/model/rawcontent/vaaddedbinary.csv',
                      lstmmodelpath=r'va_new/model/vaaddedbinarybilstm.h5',
                      modeltype='bilstm')

但是在运行的时候遇到问题了,如果两个model同时加载,并做predict的尝试,那么就发生疑似多model加载导致的issue:

Tensor embedding_2_input:0, specified in either feed_devices or fetch_devices was not found in the Graph
Exception ignored in: <bound method BaseSession._Callable.del of <tensorflow.python.client.session.BaseSession._Callable object at 0x000001B47CA91240>>
Traceback (most recent call last):
File “D:\python36\lib\site-packages\tensorflow\python\client\session.py”, line 1398, in del
self._session._session, self._handle, status)
File “D:\python36\lib\site-packages\tensorflow\python\framework\errors_impl.py”, line 519, in exit
c_api.TF_GetCode(self.status.status))
tensorflow.python.framework.errors_impl.InvalidArgumentError: No such callable handle: 1875572934464

一开始看到这个是慌张的,因为之前仅仅使用一个model的时候,是没有问题的,只是Flask提供Web API加载遇到了一些问题(请见我另一篇简书)
仔细想了想,应该是底层的Tensorflow在处理多Model切换时,懵逼了,是否每次predict的时候,遇到异常就尝试重新load呢?
代码修复的尝试如下:

    def predictcategory(self, sentence, threshold=0.5):
        self.initialforlstm()
        cleantext = gensimutil.cleardatafordoc2vector(sentence)
        twt = [cleantext]
        twt = self.tokenizer.texts_to_sequences(twt)
        # padding the tweet to have exactly the same shape as `embedding_2` input
        twt = pad_sequences(twt, maxlen=80, dtype='int32', value=0)
        # To avoid below exception:Tensor embedding_1_input:0,
        # specified in either feed_devices or fetch_devices was not found in the Graph
        try:
            categoryresult = self.lstmmodel.predict(twt, batch_size=1, verbose=2)[0]
        except Exception as e:
            logger.info(e)
            keras.backend.clear_session()
            self.lstmmodel = load_model(self.modelpath)
            categoryresult = self.lstmmodel.predict(twt, batch_size=1, verbose=2)[0]
        logger.info('raw sentence: {0}'.format(sentence))
        boolDict = {0: 'Negative', 1: 'Positive'}
        if len(categoryresult) > 2:
            logger.info('category is {0}, similarity: {1}'.format(self.categorydict[np.argmax(categoryresult)+1],
                                                            categoryresult[np.argmax(categoryresult)]))
            result = {'categorycode': np.argmax(categoryresult) + 1,
                      'categoryname': self.categorydict[np.argmax(categoryresult)+1],
                      'similarity': categoryresult[np.argmax(categoryresult)]}
        else:
                result = 0
                if np.argmax(categoryresult) == 1 and categoryresult[np.argmax(categoryresult)] > threshold:
                    result = 1
                logger.info('category is {0}, similarity: {1}'.format(boolDict[result],
                                                                      categoryresult[result]))
                result = {'categorycode': result,
                          'categoryname': boolDict[result],
                          'similarity': categoryresult[result]}

        return result

其中,这个是关键,即蒙圈了,就重新加载模型,效率或许低了些,但能够让程序run下去

        try:
            categoryresult = self.lstmmodel.predict(twt, batch_size=1, verbose=2)[0]
        except Exception as e:
            logger.info(e)
            keras.backend.clear_session()
            self.lstmmodel = load_model(self.modelpath)
            categoryresult = self.lstmmodel.predict(twt, batch_size=1, verbose=2)[0]
    原文作者:blade_he
    原文地址: https://www.jianshu.com/p/2ae3d63a377c
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞