在将Keras模型(keras_model_fn)转换为TF模型(model_fn)以用于Sagemaker时遇到了一些问题。
模型如下所示:
Keras
def keras_model_fn(hyperparameters): model = tf.keras.Sequential() # 随着词汇量的增加,增加input_dim(当前为2500) model.add(tf.keras.layers.InputLayer(input_shape=[8], name='main_input')) model.add(tf.keras.layers.Embedding(2500, 128, input_length=8)) model.add(tf.keras.layers.Flatten()) model.add(tf.keras.layers.Dense(NUM_CLASSES, activation='softmax')) model.compile( optimizer='adam', loss='categorical_crossentropy', metrics=['acc'] ) return model
Tensorflow
def model_fn(features, labels, mode, params): input_layer = tf.keras.layers.InputLayer( input_shape=(8,))(features[INPUT_TENSOR_NAME]) embedding_layer = tf.keras.layers.Embedding( 2500, 128, input_length=8)(input_layer) flattened = tf.keras.layers.Flatten()(embedding_layer) predictions = tf.keras.layers.Dense( NUM_CLASSES, activation='softmax')(flattened) if mode == tf.estimator.ModeKeys.PREDICT: return tf.estimator.EstimatorSpec( mode=mode, predictions={"output": predictions}) loss = tf.losses.softmax_cross_entropy(labels, predictions) train_op = tf.contrib.layers.optimize_loss( loss=loss, global_step=tf.train.get_global_step(), learning_rate=0.001, optimizer="Adam") predictions_dict = {"output": predictions} eval_metric_ops = { "accuracy": tf.metrics.accuracy( tf.cast(labels,tf.int32), predictions) } return tf.estimator.EstimatorSpec( mode=mode, loss=loss, train_op=train_op, eval_metric_ops=eval_metric_ops)
训练和评估数据是相同的。输入的是填充后的文本序列数组(长度为8),预期输出为5个标签中的一个。
损失值
我假设问题出在损失函数上。我无法完全弄清楚顺序模型在幕后做了什么,以及我的TensorFlow模型做了什么。
在Keras模型中,我得到了以下损失值。
INFO:tensorflow:global_step/sec: 170.783INFO:tensorflow:loss = 0.0018957269, step = 1701 (0.586 sec)INFO:tensorflow:global_step/sec: 164.419INFO:tensorflow:loss = 0.029586311, step = 1801 (0.608 sec)INFO:tensorflow:global_step/sec: 155.381INFO:tensorflow:loss = 0.0019212833, step = 1901 (0.644 sec)INFO:tensorflow:Loss for final step: 0.0023477676.
在转换后的模型中,我得到了以下结果。
INFO:tensorflow:loss = 1.232958, step = 1701 (0.354 sec)INFO:tensorflow:global_step/sec: 280.328INFO:tensorflow:loss = 1.0923336, step = 1801 (0.357 sec)INFO:tensorflow:global_step/sec: 291.823INFO:tensorflow:loss = 1.4360821, step = 1901 (0.343 sec)INFO:tensorflow:Loss for final step: 1.0532712.
正如预期的那样,转换后的模型(对于它所训练的数据)准确率约为60%。Keras模型的准确率为100%。
我的问题是转换过程是否看起来正确?我在转换后的模型中可以做些什么来获得相似的性能?
我已经开始研究Keras的源代码,看看模型编译函数对目标/输出的处理,但也想在这里寻求建议,看看是否有人有建议/之前遇到过这个问题。
回答:
问题可能是你在TensorFlow版本中应用了两次softmax激活。请注意,tf.losses.softmax_cross_entropy期望未缩放的logits。你可以这样做:
logits = tf.keras.layers.Dense( NUM_CLASSES)(flattened)predictions = tf.keras.layers.Activation( 'softmax')(logits)loss = tf.losses.softmax_cross_entropy(labels, logits)