前言
项目需要,使用tensorflow和keras混合编程。因为不熟悉tensorflow和keras,导致报错BUG,修复两天,没有好的解决方法。
修改过程
其实在早期,有修复过类似问题(1个TF模型加1个KERAS),在keras外包一层tf.Graph()完美解决冲突。但是这次更加复杂。需要调用N个TF模型,N个KERAS模型。如果我new多次keras模型,导致graph无法画出。
后来在stackoverflow上找到较好的版本。地址:名字为Andrew Louw的小哥
旧代码:
class model(object):
graph = None
def __init__(self, model_path=modepath):
# config = tf.ConfigProto()
# config.gpu_options.allow_growth = True
# session = tf.Session(config=config)
# KTF.set_session(session)
self.graph = tf.Graph()
sess = tf.Session(graph=self.graph)
K.set_session(sess)
新代码:
import os
from keras import backend as K
import tensorflow as tf
import logging
from keras.models import load_model
import cv2
import numpy as np
import matplotlib.image as mpimg
import keras.backend.tensorflow_backend as KTF
#如果前面是tf代码不需要加上这几句。防止keras占用全部显卡
config = tf.ConfigProto()
config.gpu_options.allow_growth = True
session = tf.Session(config=config)
KTF.set_session(session)
class Keras_Model:
def __init__(self,file_name):
self.session = tf.Session()
self.graph = tf.get_default_graph()
self.model = None
with self.graph.as_default():
with self.session.as_default():
logging.info("neural network initialised")
#self.model = load_model(file_name, custom_objects={'R': self.R, 'P': self.P, 'F': self.F})
self.model = load_model(file_name)
def R(self,y_true, y_pred):
true_positives = K.sum(K.cast(K.greater(K.clip(y_true * y_pred, 0, 1), 0.20), 'float32'))
poss_positives = K.sum(K.cast(K.greater(K.clip(y_true, 0, 1), 0.20), 'float32'))
recall = true_positives / (poss_positives + K.epsilon())
return recall
# precision
def P(self,y_true, y_pred):
true_positives = K.sum(K.cast(K.greater(K.clip(y_true * y_pred, 0, 1), 0.20), 'float32'))
pred_positives = K.sum(K.cast(K.greater(K.clip(y_pred, 0, 1), 0.20), 'float32'))
precision = true_positives / (pred_positives + K.epsilon())
return precision
def F(self,y_true, y_pred):
p_val = self.P(y_true, y_pred)
r_val = self.R(y_true, y_pred)
f_val = 2 * p_val * r_val / (p_val + r_val)
return f_val
def detect_img(self, path):
def pre_process_img(path, length=300, width=300, channel=3):
#img = cv2.imread(path)
img = path
img = cv2.resize(img, (length, width), interpolation=cv2.INTER_CUBIC)
img = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
img = img.reshape([1, length, width, 1])
return img
with self.graph.as_default():
with self.session.as_default():
y = self.model.predict(pre_process_img(path))
y = y[0].argmax()
#data = np.where(y[:, :1] > y[:, 1:], 0, 1)#输出标签。flag可改。0是ok,1是ng
return y
if __name__ == '__main__':
a = Keras_Model('_v1.h5')
pic = '24.bmp'
print(a.predict(pic))