有没有一种方法可以使用多标签分类,但当模型仅预测 keras 中的一个标签时认为是正确的?

Posted

技术标签:

【中文标题】有没有一种方法可以使用多标签分类,但当模型仅预测 keras 中的一个标签时认为是正确的?【英文标题】:Is there a way to use multilabel classification but take as correct when the model predicts only one label in keras? 【发布时间】:2020-11-02 02:10:27 【问题描述】:

我有一个天气预报数据集,我正在尝试建立一个模型来预测第二天哪个预报会更准确。

为此,我的 y 输出格式为 y=[1,0,1,0],因为我有 4 个不同组织的预测。 1 表示这是当前记录的最佳预测,更多的“1”表示多个预测具有相同的最佳预测。

我的问题是,我想创建一个模型来训练这些数据,但也知道只有正确预测 1 个值是 100% 正确的答案,因为我只需要因此得到最好和平等的预测之一。我相信我这样做的方式会从我的评估中“减少”准确性。有没有办法在 keras 中实现这一点?神经网络的架构完全是实验性的,我选择它没有具体原因。这是我写的代码。我的火车数据集由 6463 行 × 505 列组成。

model = Sequential()

model.add(LSTM(150, activation='relu',activity_regularizer=regularizers.l2(l=0.0001)))
model.add(Dense(100,  activation='relu'))
model.add(Dense(100,  activation='relu'))
model.add(Dense(100,  activation='relu'))
model.add(Dense(50,  activation='relu'))
model.add(Dense(50,  activation='relu'))
model.add(Dense(50,  activation='relu'))

model.add(Dense(24,  activation='relu'))
model.add(Dense(4, activation='softmax')) 


#LSTM
# reshape input to be 3D [samples, timesteps, features]
X_train_sc =X_train_sc.reshape((X_train_sc.shape[0], 1, X_train_sc.shape[1]))
X_test_sc = X_test_sc.reshape((X_test_sc.shape[0], 1,X_test_sc.shape[1]))
#validation set
x_val=X_train.iloc[-2000:-1300,0:505]
y_val=y_train[-2000:-1300]

x_val_sc=scaler.transform(x_val)

# reshape input to be 3D for LSTM[samples, timesteps, features]
x_val_sc =x_val_sc.reshape((x_val_sc.shape[0], 1, x_val_sc.shape[1]))
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['categorical_accuracy'])
history= model.fit(x=X_train_sc, y=y_train ,validation_data=(x_val_sc,y_val), epochs=300, batch_size=24)
print(model.evaluate(X_test_sc,y_test))
yhat= model.predict(X_test_sc)

我的准确率约为 44%

【问题讨论】:

【参考方案1】:

如果您想预测[1,0,1,0] 的形式,即。该模型应该预测属于 4 个类别中的每个类别的概率,然后称为多标签分类。您编码的是多类分类。

多标签分类

您的最后一层将是每个类的大小为 4 的密集层,并带有 sigmod 激活。您将使用binary_crossentropy 损失。

x = np.random.randn(100,10,1)
y = np.random.randint(0,2,(100,4))

model = keras.models.Sequential()

model.add(keras.layers.LSTM(16, activation='relu', input_shape=(10,1), return_sequences=False))
model.add(keras.layers.Dense(8,  activation='relu'))
model.add(keras.layers.Dense(4, activation='sigmoid')) 

model.compile(optimizer='adam', loss='binary_crossentropy')
model.fit(x,y)

检查

print (model.predict(x))

输出

array([[0.5196002 , 0.52978194, 0.5009601 , 0.5036485 ],
       [0.508756  , 0.5189857 , 0.5022978 , 0.50169533],
       [0.5213044 , 0.5254892 , 0.51159555, 0.49724004],
       [0.5144601 , 0.5264933 , 0.505496  , 0.5008205 ],
       [0.50524575, 0.5147699 , 0.50287664, 0.5021702 ],
       [0.521035  , 0.53326863, 0.49642274, 0.50102305],
.........

如您所见,每个预测的概率总和不等于 1,而是每个值是它属于相应类别的概率。所以如果概率 > 0.5 你可以说它属于这个类。

另一方面,如果您使用softmax,则概率总和为 1,即。它属于其值 > 0.5 的单个类。

【讨论】:

实际上我想在具有 [1,0,1,0] 形式的 y 上进行训练,但做出具有 [1,0,0,0] 形式的预测(即只返回一个正确的值) .你说的这些也适用于这个案子吗?如果是这样,我应该将分类准确度作为准确度指标吗? @orestisgiokas 从理论上讲,多标签训练和多类预测是错误的。然而,作为一个黑客,你为什么不对模型的多标签预测执行argmax 并将其分配给最高置信度的类? 我想到了,但我想知道在训练过程中是否有实现我需要的技巧,以便在模型训练时,如果它做出与 [1,0 ,0,0] 它不会降低训练的准确性。换句话说,我需要训练我的模型,在训练过程中考虑 [1,0,1,0] [1,0,0,0] 和 [0,0,1,0] 100% 正确

以上是关于有没有一种方法可以使用多标签分类,但当模型仅预测 keras 中的一个标签时认为是正确的?的主要内容,如果未能解决你的问题,请参考以下文章

TFJS 模型仅预测二元分类任务的相同值

机器不学习:一种提升预测能力的方法-机器学习模型

如何在 keras 中进行深度学习中的多标签分类?

收藏 | 多标签分类实用的经典方法

收藏 | 多标签分类实用的经典方法

R语言plotly可视化:使用plotly可视化数据划分后的训练集和测试集使用不同的形状标签表征训练集测试集以及数据集的分类标签整个数据空间的分类边界轮廓线(等高线)多分类模型的预测置信度