You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多分类任务损失函数选择及输出格式转换技术咨询

文本分类器损失函数相关问题

我在大学作业中需编写简单文本数据集分类器,共5个类别:['0', '1', '2', '3', '4']。参考网络代码后遇到两个问题:

  • 使用categorical_crossentropy时报错:
    Arguments 'target and 'output' must have the same rank (ndim). Received: target. shape=(None,), output.shape=(None,6)
    
  • 使用sparse_categorical_crossentropy时,模型输出为二维数组。

我的代码如下:

x_train, x_test, y_train, y_test = train_test_split(X_scaled, y_encoded, test_size=0.2, random_state=42)

x_train = x_train / 255
x_test = x_test / 255

def b_m(hp):
    model = Sequential()
    activation_choice = hp.Choice('activation', values=['relu', 'sigmoid', 'tanh', 'elu', 'selu'])
    model.add(Dense(units=hp.Int('units_input',
                                   min_value=512,
                                   max_value=1024,
                                   step=32),
                    input_dim=2,
                    activation=activation_choice))
    model.add(Dense(units=hp.Int('units_hidden',
                                   min_value=128,
                                   max_value=600,
                                   step=32),
                    activation=activation_choice))
    model.add(Dense(5, activation='softmax'))
    model.compile(
        optimizer=hp.Choice('optimizer', values=['adam','rmsprop','SGD']),
        loss='sparse_categorical_crossentropy',
        #loss='categorical_crossentropy',
        metrics=['accuracy'])
    return model

tuner = kt.Hyperband(b_m,
                     objective='val_accuracy',
                     max_epochs=10,
                     factor=3,
                     directory='test_dir')

stop_early = tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience=5)

tuner.search(x_train, y_train, epochs=50, validation_split=0.2, callbacks=[stop_early])

best_hps=tuner.get_best_hyperparameters(num_trials=1)[0]

model = tuner.hypermodel.build(best_hps)
history = model.fit(x_train, y_train, epochs=50, validation_split=0.2)

val_acc_per_epoch = history.history['val_accuracy']
best_epoch = val_acc_per_epoch.index(max(val_acc_per_epoch)) + 1

hypermodel = tuner.hypermodel.build(best_hps)

hypermodel.fit(x_train, y_train, epochs=best_epoch, validation_split=0.2)

eval_result = hypermodel.evaluate(x_test, y_test)
print("[loss, test]:", eval_result)

y_pred = hypermodel.predict(x_test)

我有三个问题:

  1. 该场景下最适合使用哪种损失函数?
  2. 若选择categorical_crossentropy,如何修复报错?
  3. 若选择sparse_categorical_crossentropy,如何将二维输出转为一维类别数组?

问题解答

1. 最适合的损失函数

两种损失函数都适用,选哪种看标签格式:

  • 若标签是整数形式(比如y_train形状为(None,),每个值是0-4的整数),优先用sparse_categorical_crossentropy,无需额外处理标签,还能节省内存。
  • 若标签是one-hot编码形式(比如y_train形状为(None,5),每个样本对应5维数组,仅对应类别位置为1),用categorical_crossentropy。

你的场景中y_encoded是整数形式(报错显示target.shape=(None,)),所以sparse_categorical_crossentropy更合适,代码改动最少。

2. 修复categorical_crossentropy的报错

报错根源是目标标签和模型输出维度不匹配:模型输出是(None,5)的二维数组(5类softmax输出),但标签是(None,)的一维整数数组。需要把标签转为one-hot编码:

在分割数据集后,对标签做如下处理:

from tensorflow.keras.utils import to_categorical

# 假设y_encoded是0-4的整数数组
y_train_onehot = to_categorical(y_train, num_classes=5)
y_test_onehot = to_categorical(y_test, num_classes=5)

然后修改模型编译和训练代码:

# 模型编译时启用categorical_crossentropy
model.compile(
    optimizer=hp.Choice('optimizer', values=['adam','rmsprop','SGD']),
    loss='categorical_crossentropy',
    metrics=['accuracy'])

# 训练时传入one-hot后的标签
tuner.search(x_train, y_train_onehot, epochs=50, validation_split=0.2, callbacks=[stop_early])
model.fit(x_train, y_train_onehot, epochs=50, validation_split=0.2)
hypermodel.fit(x_train, y_train_onehot, epochs=best_epoch, validation_split=0.2)
eval_result = hypermodel.evaluate(x_test, y_test_onehot)

3. 把sparse_categorical_crossentropy的二维输出转一维类别数组

模型softmax输出的是每个类别的概率(形状(样本数,5)),取每个样本概率最大的索引即可得到一维类别数组:

y_pred = hypermodel.predict(x_test)
# 取每个样本概率最大的类别索引
y_pred_classes = y_pred.argmax(axis=1)

y_pred_classes形状为(样本数,),每个值对应0-4的类别编号,和y_test格式一致,可直接用于计算准确率、混淆矩阵等指标。


内容的提问来源于stack exchange,提问作者randomname

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 21:47:03