如何从含多标签的Pandas DataFrame创建TensorFlow Dataset并完成模型训练
核心问题排查
你遇到的报错来自两个错误配置:
- labels列是字符串格式的列表,未转换为TensorFlow可识别的数值型数组
- 损失函数与标签格式不匹配
修复步骤
1. 修正labels列类型转换逻辑
你之前用apply返回的每行数组会被pandas存为object类型列,TensorFlow无法直接识别,需要先统一转换为二维numpy数组:
from ast import literal_eval import numpy as np import tensorflow as tf def df_to_dataset(dataframe, shuffle=True, batch_size=32): dataframe = dataframe.copy() # 转换字符串列表为数值型二维数组 labels = dataframe.pop('labels').apply(literal_eval).to_list() labels = np.array(labels, dtype=np.float32) # 构造数据集,与输入层匹配直接传入text列即可 ds = tf.data.Dataset.from_tensor_slices((dataframe['text'].values, labels)) if shuffle: ds = ds.shuffle(buffer_size=len(dataframe)) ds = ds.batch(batch_size).prefetch(tf.data.AUTOTUNE) return ds
你可以用以下代码验证数据集格式是否正确:
for text, label in train_ds.take(1): print("文本形状:", text.shape) print("标签形状:", label.shape) print("标签类型:", label.dtype)
正常输出应为:文本形状(32,),标签形状(32, 17),标签类型float32。
2. 修正损失函数配置
根据你的标签格式调整损失函数和输出层配置:
- 如果是多标签分类(单样本可同时命中多个类别,标签为多热编码):
修改输出层激活函数为sigmoid,损失函数替换为二分类交叉熵:# 输出层修改 net = tf.keras.layers.Dense(17, activation='sigmoid', name='classifier')(net) # 编译参数修改 loss = tf.keras.losses.BinaryCrossentropy() metrics = [tf.keras.metrics.BinaryAccuracy(name='accuracy')] - 如果是单标签分类(单样本仅命中一个类别,标签为独热编码):
仅替换损失函数为分类交叉熵即可:loss = tf.keras.losses.CategoricalCrossentropy()
你之前使用的sparse_categorical_crossentropy仅适用于标签为整数的场景,和你当前17维数组的标签格式不匹配,所以会触发类型转换报错。
修改完成后即可正常调用model.fit()完成训练。
内容的提问来源于stack exchange,提问作者Yossi
相关产品推荐
相关产品推荐

