我正在使用Keras Sequential模型来训练多个多类分类器。
在评估时,Keras输出置信度向量,我可以使用argmax推断出正确的类ID。然后我可以使用查找表来接收实际的类标签(例如字符串)。
到目前为止,解决方案是加载训练的模型,然后单独加载查找表。由于我有很多分类器,我宁愿将两个结构保存在一个文件中。
所以我正在寻找的是一种将实际标签查找向量集成到Keras模型中的方法。这将允许我有一个分类器文件,它能够获取一些输入数据并返回该数据的正确类标签。
解决这个问题的一种方法是将模型和查找表存储在元组中,并将该元组写入pickle中,但这看起来并不优雅。
答案 0 :(得分:6)
所以我自己尝试了一个解决方案,这似乎有效。我希望有更简单的东西。
我认为第二次打开模型文件并不是最佳选择。如果有人能做得更好,那么就做。
import h5py
from keras.models import load_model
from keras.models import save_model
def load_model_ext(filepath, custom_objects=None):
model = load_model(filepath, custom_objects=None)
f = h5py.File(filepath, mode='r')
meta_data = None
if 'my_meta_data' in f.attrs:
meta_data = f.attrs.get('my_meta_data')
f.close()
return model, meta_data
def save_model_ext(model, filepath, overwrite=True, meta_data=None):
save_model(model, filepath, overwrite)
if meta_data is not None:
f = h5py.File(filepath, mode='a')
f.attrs['my_meta_data'] = meta_data
f.close()
答案 1 :(得分:1)
可以在keras模型中直接保存标签的“列表”。您需要使用lambda。您只需将lambda的输出替换为包含标签的字符串张量即可。这是一个虚拟的示例,说明如何执行标签的“注入”
# assume we get labels as list
labels = ["cat","dog","horse","tomato"]
# here we start building our model with input image 299x299 and one output layer
xx = Input(shape=(299,299,3))
flat = Flatten()(xx)
output = Dense(shape=(4))(flat)
# here we perform injection of labels
tf_labels = tf.constant([labels],dtype="string")
# adding ? dimension to tf tensor
tf_labels = tf.tile(labels,[tf.shape(xx)[0],1])
output_labels = Lambda(lambda x: tf_labels,name="label_injection")(xx)
#and finaly creating a model
model=tf.keras.Model(xx,[output,output_labels])
此模型现在存储标签并返回它们。 tf.tile的所有这些混乱都是必要的,因为形状(N)的角膜层实际上是形状(?,N)的tf张量,我们加上这个?标签张量的尺寸。