如何在TensorFlow多分类任务中使用Precision或F1-Score指标
多分类任务中TensorFlow精度/F1-Score指标的形状不兼容问题
我复现了一个基于鸢尾花数据集的3分类任务代码:
import tensorflow as tf from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split # 加载鸢尾花数据集 iris = load_iris() # 划分训练集和测试集 X_train, X_test, y_train, y_test = train_test_split( iris.data, iris.target, test_size=0.2, random_state=42) # 定义模型 model = tf.keras.Sequential([ tf.keras.layers.Dense(10, activation='relu', input_shape=(4,)), tf.keras.layers.Dense(3, activation='softmax') ]) # 编译模型 model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy']) # 训练模型 history = model.fit(X_train, y_train, epochs=50, validation_split=0.2)
当将model.compile中的metrics=['accuracy']改为metrics=[tf.keras.metrics.Precision()],或添加Precision作为额外指标时,出现形状不兼容错误:
ValueError: Shapes (32, 3) and (32, 1) are incompatible
使用TensorFlow Addons的F1Score时也报错:
import tensorflow_addons as tfa metrics= [tfa.metrics.F1Score(average="macro",num_classes = 3,threshold=None,name='f1_score', dtype=None)]
ValueError: Dimension 0 in both shapes must be equal, but are 3 and 1. Shapes are [3] and [1].
请问如何在TensorFlow中正确使用Precision或F1-Score指标进行多分类任务的优化?
解决方案
问题核心是:当前标签为稀疏整数格式(形状(batch_size,)),但多分类指标默认期望接收one-hot编码标签(形状(batch_size, num_classes)),需通过两种思路适配:
思路1:将标签转换为one-hot编码
把整数标签转为one-hot格式,同时将损失函数改为categorical_crossentropy,让指标与输入形状匹配:
import tensorflow as tf from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split import tensorflow_addons as tfa # 加载并划分数据 iris = load_iris() X_train, X_test, y_train, y_test = train_test_split( iris.data, iris.target, test_size=0.2, random_state=42) # 转换标签为one-hot编码 y_train_onehot = tf.keras.utils.to_categorical(y_train, num_classes=3) y_test_onehot = tf.keras.utils.to_categorical(y_test, num_classes=3) # 定义模型 model = tf.keras.Sequential([ tf.keras.layers.Dense(10, activation='relu', input_shape=(4,)), tf.keras.layers.Dense(3, activation='softmax') ]) # 编译模型:搭配one-hot标签对应的损失和指标 model.compile( optimizer='adam', loss='categorical_crossentropy', metrics=[ tf.keras.metrics.Precision(name='precision'), tfa.metrics.F1Score(average="macro", num_classes=3, name='f1_score') ] ) # 传入one-hot标签训练 history = model.fit(X_train, y_train_onehot, epochs=50, validation_split=0.2)
思路2:使用适配稀疏标签的指标类
若不想修改标签格式(继续使用sparse_categorical_crossentropy),可使用TensorFlow提供的稀疏标签专属指标:
适配Precision
使用SparsePrecision指标,专门匹配稀疏整数标签:
model.compile( optimizer='adam', loss='sparse_categorical_crossentropy', metrics=[tf.keras.metrics.SparsePrecision(name='sparse_precision')] )
适配F1-Score(TensorFlow Addons)
使用SparseCategoricalF1Score(需TF Addons版本≥0.16.0),直接适配稀疏标签:
metrics = [tfa.metrics.SparseCategoricalF1Score(average="macro", num_classes=3, name='sparse_f1_score')] model.compile( optimizer='adam', loss='sparse_categorical_crossentropy', metrics=metrics )
内容的提问来源于stack exchange,提问作者Bluetail
相关产品推荐
相关产品推荐

