[英]Tensorflow 2.0 how to export predictions and training-mode from Keras model
I have a model sub-classed from tf.keras.model .我有一个从 tf.keras.model 分类的模型。 I have write a call -and predict methods.
我写了一个调用 - 并预测方法。 when I export the model it seems that only the output from call method is serialized.
当我导出模型时,似乎只有 call 方法的输出被序列化。 The simple code to illustrate the problem is below
说明问题的简单代码如下
class SimpleModel(tf.keras.Model):
def __init__(self):
super(SimpleModel, self).__init__()
self.layer1 = keras.layers.Flatten(input_shape=(28, 28))
self.layer2 = keras.layers.Dense(128, activation='relu')
self.dropout = keras.layers.Dropout(0.5)
self.layer3 = keras.layers.Dense(10, activation='softmax')
def call(self, x, training=False):
x = self.layer1(x)
x = self.layer2(x)
if training:
x = self.dropout(x)
return self.layer3(x)
def predict(self, x):
return tf.argmax(self(x))
fashion_mnist = keras.datasets.fashion_mnist
(train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()
class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat',
'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']
model = SimpleModel()
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
model.fit(train_images, train_labels, epochs=10)
model.save('tf_test', save_format='tf')
When I inspect the saved model using the saved-model-cli the output is as below当我使用saved-model-cli检查保存的模型时,输出如下
The given SavedModel SignatureDef contains the following input(s):
inputs['input_1'] tensor_info:
dtype: DT_UINT8
shape: (-1, 28, 28)
name: serving_default_input_1:0
The given SavedModel SignatureDef contains the following output(s):
outputs['output_1'] tensor_info:
dtype: DT_FLOAT
shape: (-1, 10)
name: StatefulPartitionedCall:0
Method name is: tensorflow/serving/predict
The output is exactly same without the predict method.如果没有预测方法,输出完全相同。 So how can I get the prediction tensor included in the serialization and does the training mode need to be serialized.
那么如何获取序列化中包含的预测张量,以及训练模式是否需要序列化。 In tensorflow 1.x I can simply save the prediction tensor and training mode tensor using the following line of code
在 tensorflow 1.x 中,我可以使用以下代码行简单地保存预测张量和训练模式张量
tf.saved_model.simple_save(sess, 'tf_test', inputs={"x": x, "mode": training_mode}, outputs={"predictions": predictions})
I think I find the solution to the export problem from the tensorflow documentation Using save model format section Exporting custom models .我想我从 tensorflow 文档Using save model format section Exporting custom models 中找到了导出问题的解决方案。 The solution is to use tf.Module instead tf.keras.Model and use the tf.function annotation at the top of the function one wants to import.
解决方案是使用 tf.Module 代替 tf.keras.Model 并在要导入的函数顶部使用 tf.function 注释。 The working code is illustrated below
工作代码如下图所示
class SimpleModel(tf.Module):
def __init__(self):
super(SimpleModel, self).__init__()
self.layer1 = keras.layers.Flatten(input_shape=(28, 28))
self.layer2 = keras.layers.Dense(128, activation='relu')
self.dropout = keras.layers.Dropout(0.5)
self.layer3 = keras.layers.Dense(10, activation='softmax')
def __call__(self, x, training=False):
x = self.layer1(x)
x = self.layer2(x)
# if training:
# x = self.dropout(x)
x = self.layer3(x)
return x
@tf.function(input_signature=[tf.TensorSpec([None, 28, 28], tf.float32)])
def predict(self, x):
return tf.argmax(self(x), axis=1)
def loss(m, x, y):
logits = m(x, True)
return tf.keras.losses.categorical_crossentropy(tf.reshape(tf.one_hot(y, 10), (y.size, 10)), logits)
def grad(m, x, y):
with tf.GradientTape() as tape:
lv = loss(m, x, y)
return lv, tape.gradient(lv, m.trainable_variables)
fashion_mnist = keras.datasets.fashion_mnist
(train_images, train_labels), (test_images, test_labels) =
fashion_mnist.load_data()
class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat',
'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']
model = SimpleModel()
# model.compile(optimizer='adam',
# loss='sparse_categorical_crossentropy',
# metrics=['accuracy'])
#
# model.fit(train_images, train_labels, epochs=10)
epochs = 100
batch_size = 1000
optimizer = tf.keras.optimizers.SGD(learning_rate=1e-5)
for epoch in range(epochs):
costs = []
for k in range(int(train_images.shape[0] / batch_size)):
start_index = k * batch_size
end_index = (k + 1) * batch_size
batch_x, batch_y = train_images[start_index:end_index, :, :],
train_labels[start_index:end_index]
loss_value, grads = grad(model, batch_x, np.reshape(batch_y, (1000, 1)))
optimizer.apply_gradients(zip(grads, model.trainable_variables))
costs.append(loss_value.numpy())
print("epoch %d of %d, cost %f" % (epoch, 10, np.mean(costs)))
signatures = {"serving_default": model.predict}
tf.saved_model.save(model, 'tf_test', signatures)
No the output of the saved_model_cli is不,saved_model_cli 的输出是
The given SavedModel SignatureDef contains the following input(s):
inputs['x'] tensor_info:
dtype: DT_FLOAT
shape: (-1, 28, 28)
name: serving_default_x:0
The given SavedModel SignatureDef contains the following output(s):
outputs['output_0'] tensor_info:
dtype: DT_INT64
shape: (-1)
name: StatefulPartitionedCall:0
Method name is: tensorflow/serving/predict
which corresponds to the output of predict method outputting single label对应输出单标签的 predict 方法的输出
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.