使用TensorFlow 2.8.4时损失函数出现类型错误的原因排查
问题分析:TensorFlow模型训练类型错误原因
使用TensorFlow 2.8.4构建了如下简化模型,意图将输入直接作为输出,但训练时触发类型错误:
features = { 'prop1': ['BT', 'BT', 'BT'], 'prop2': [1000,1000,1000], 'prop3': [1, 1, 0], } labels = [1, 1, 0] inputs = { 'prop1': tf.keras.Input(shape=(), dtype='string'), 'prop2': tf.keras.Input(shape=(), dtype='int64'), 'prop3': tf.keras.Input(shape=(), dtype='int64'), } example_model = tf.keras.Model(inputs, inputs) dataset = tf.data.Dataset.from_tensor_slices((features, labels)) example_model.compile( optimizer=tf.keras.optimizers.SGD(), loss=tf.keras.losses.BinaryCrossentropy(), metrics=tf.keras.metrics.BinaryAccuracy() ) example_model.fit(dataset, epochs=1)
训练时出现的错误日志:
File "/home/benfranklin/.pyenv/versions/train28/lib/python3.7/site-packages/keras/engine/training.py", line 1021, in train_function * return step_function(self, iterator) File "/home/benfranklin/.pyenv/versions/train28/lib/python3.7/site-packages/keras/engine/training.py", line 1010, in step_function ** outputs = model.distribute_strategy.run(run_step, args=(data,)) File "/home/benfranklin/.pyenv/versions/train28/lib/python3.7/site-packages/keras/engine/training.py", line 1000, in run_step ** outputs = model.train_step(data) File "/home/benfranklin/.pyenv/versions/train28/lib/python3.7/site-packages/keras/engine/training.py", line 860, in train_step loss = self.compute_loss(x, y, y_pred, sample_weight) File "/home/benfranklin/.pyenv/versions/train28/lib/python3.7/site-packages/keras/engine/training.py", line 919, in compute_loss y, y_pred, sample_weight, regularization_losses=self.losses) File "/home/benfranklin/.pyenv/versions/train28/lib/python3.7/site-packages/keras/engine/compile_utils.py", line 201, in __call__ loss_value = loss_obj(y_t, y_p, sample_weight=sw) File "/home/benfranklin/.pyenv/versions/train28/lib/python3.7/site-packages/keras/losses.py", line 141, in __call__ losses = call_fn(y_true, y_pred) File "/home/benfranklin/.pyenv/versions/train28/lib/python3.7/site-packages/keras/losses.py", line 245, in call ** return ag_fn(y_true, y_pred, **self._fn_kwargs) File "/home/benfranklin/.pyenv/versions/train28/lib/python3.7/site-packages/keras/losses.py", line 1923, in binary_crossentropy label_smoothing = tf.convert_to_tensor(label_smoothing, dtype=y_pred.dtype) TypeError: Expected string, but got 0.0 of type 'float'.
错误原因
- 模型定义时
example_model = tf.keras.Model(inputs, inputs)将输出设置为输入字典,其中包含string类型的prop1张量。 - 二分类损失函数
BinaryCrossentropy要求模型输出必须是数值型张量(对应概率或logits),用于和数值型标签(0/1)计算损失。 - 损失函数内部尝试将
label_smoothing转换为与模型输出相同的类型,但模型输出中存在string类型张量,导致无法将float类型的0.0转换为string类型,触发类型错误。
解决方案
如果是为了测试模型流程,需将输出调整为数值型张量,示例修改方式:
- 直接使用与标签匹配的数值型输入作为输出:
# 修改模型定义,仅输出prop3(数值型,与标签类型匹配) example_model = tf.keras.Model(inputs, inputs['prop3'])
- 如果需要使用所有特征,需先对string类型特征做编码处理(如
StringLookup+Embedding),再将所有特征拼接为数值型输出张量,确保与标签类型一致后再计算损失。
内容的提问来源于stack exchange,提问作者Ben Franklin
相关产品推荐
相关产品推荐

