【问题标题】:Tensorflow: Predict 1 of 4 labels for text classificationTensorflow:预测 4 个标签中的 1 个用于文本分类
【发布时间】:2021-05-07 20:03:41
【问题描述】:

我目前正在处理一个文本分类问题,需要我们将文本分类为四个标签之一。编码后的 y 值应该是 [0,1,2,3] 之一,应该是预测的标签。

但是,这个模型所做的预测似乎在 (0,1) 范围内,我有点困惑?此外,任何人都可以澄清这是 ANN 还是 RNN? TensorFlow 经验为零,但仍在苦苦挣扎……

model = Sequential()
model.add(Dense(16, activation='relu'))
model.add(Dense(4, activation='softmax'))
model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])
              
from sklearn.preprocessing import LabelEncoder
#encode the label
label_encoder = LabelEncoder()
y_train=np.array(label_encoder.fit_transform(train_labels))
x_train=np.array(train_features)
y_true=np.array(label_encoder.fit_transform(dev_label))
#fit the model
model.fit(x_train,y_train,epochs=1)
y_pred=model.predict(dev_features)

和错误信息:Classification metrics can't handle a mix of multiclass and continuous-multioutput targets

【问题讨论】:

    标签: python tensorflow


    【解决方案1】:

    假设目标列有 4 个唯一值:red, blue, green, yellow,语料库被转换为 TF-IDF 值。前 3 行如下所示:

    word_1 word_2 target
    0.567 0.897 red
    0.098 0.238 blue
    0.66 0.786 green

    单热编码

    one-hot encoding目标之后,您的目标看起来像一个数组,形式如下:

    array[[1. 0. 0. 0.], <- category 'red'
    [0. 1. 0. 0.], <- category 'blue'
    [0. 0. 1. 0.]...] <- category 'green'
    

    这里,目标列的大小为 (n_samples, n_targets),即 (n,4)。在这种情况下,最终激活必须是sigmoidsoftmax,您将使用categorical_crossentropy 损失来训练您的模型。此处回答您问题的代码将是:

    model.add(Dense(4, activation='sigmoid'))
    model.compile(optimizer='adam',
                  loss='categorical_crossentropy',
                  metrics=['accuracy'])
    

    标签编码

    label-encoding目标之后,您的目标看起来像一个数组,形式如下:

    array([1, 2, 3 ...])
    

    具有大小为 (n_targets) 的一维数组。这里的代码是:

    model.add(Dense(4, activation='softmax'))
    model.compile(optimizer='adam',
                  loss='sparse_categorical_crossentropy',
                  metrics=['accuracy'])
    

    预测

    您看到的这些数字是给定输入样本的每个类别的概率。例如,[[0.4846592 0.5153408]] 表示给定样本属于类别 0 的概率约为 0.48,属于类别 1 的概率约为 0.51。因此,您希望选择概率最高的课程,因此您可以使用 np.argmax 来查找哪个索引(即 0 或 1)是最大的:

    import numpy as np
    
    pred_class = np.argmax(y_pred, axis=-1) 
    

    此外,这与模型的损失函数无关。这些概率由模型中的最后一层给出,很可能它使用 softmax 作为激活函数将输出归一化为概率分布。 Source

    结论

    • 您遇到的错误是因为使用了不正确的损失函数。
    • 如果你有一维整数编码或标签编码目标,你应该使用sparse_categorical_crossentropy作为损失函数。
    • 如果您对目标进行了一次性编码,以便获得 2D 形状(n_samples,n_class),您应该使用categorical_crossentropy

    【讨论】:

    • 您好,错误信息仍然与显示的问题详细信息相同
    • 你能展示一下你用来单热编码目标的代码吗?错误消息本质上意味着我们有形状差异。你得到一个一维数组,但你的最后一层有 4D 输出或类似的东西。更详细的代码将帮助我更好地理解形状差异所在。
    • 已经给出了具有 tfidf 值的训练集。所以它被直接读入train_features,我只是把它转换成np.array。编码器只是对标签进行编码
    • 我已经更新了答案。所以基本上有两种情况——a)单热编码目标和b)标签编码目标。两者的损失函数各不相同。您可以通过以下方式查看更多信息:medium.com/deep-learning-with-keras/…
    • 非常感谢您的详细回答!然而,预测似乎不在 (0,1,2,3) 之一。我已将预测和我的真实标签放在问题部分。
    【解决方案2】:

    密集层应该有一个维度 4 并且激活函数应该是“softmax”而不是“sigmoid”,因为我们正在执行多类(超过 2 个类)分类。 另外,将损失函数更改为“categorical_crossentropy”。

    您的代码示例将如下所示:

    model.add(Dense(16, activation='relu'))
    model.add(Dense(4, activation='softmax'))
    model.compile(optimizer='adam',
              loss='categorical_crossentropy',
              metrics=['accuracy'])
    

    【讨论】:

    • 我确实尝试过,但错误如下: ValueError: Shapes (None, 1) and (None, 4) are incompatible
    • 你能发布完整模型的代码吗?
    • 当我们使用softmax作为激活函数时,我们one-hot encode目标变量。你能试试吗?很抱歉,我错过了您对目标变量进行了标签编码。
    • 我的特征值(train_features 是一个 no_of_instance*no_of_vocab 大小列表。这些值是 tfdif 值,它们是我的 vocab.txt(给定字典)中每个单词的重要性。因为这里我只有一个热编码y 值,而不是 x(特征)值
    • 在最后一层,请确保将激活更改为“softmax”。我在代码中看到它仍然是“sigmoid”。
    猜你喜欢
    • 2016-12-10
    • 1970-01-01
    • 2021-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-25
    • 1970-01-01
    • 2014-03-12
    相关资源
    最近更新 更多