如何确定Keras卷积神经网络预测的二分类类别?

我正在使用Keras构建一个卷积神经网络(CNN)来进行情感分析。一切运行良好,模型已经训练完成并准备投入生产使用。

然而,当我尝试使用model.predict()方法对新的未标记数据进行预测时,它只输出相关的概率。我尝试使用np.argmax()方法,但它总是输出0,即使在测试集上我的模型达到了80%的准确率,输出应该为1。

以下是我预处理数据的代码:

# 预处理数据
x = df[df.Sentiment != 3].Headlines
y = df[df.Sentiment != 3].Sentiment
# 分割训练、验证、测试数据集
x_train, x_validation_and_test, y_train, y_validation_and_test = train_test_split(x, y, test_size=.3,                                                                                      random_state=SEED)
x_validation, x_test, y_validation, y_test = train_test_split(x_validation_and_test, y_validation_and_test,                                                                  test_size=.5, random_state=SEED)
tokenizer = Tokenizer(num_words=NUM_WORDS)
tokenizer.fit_on_texts(x_train)
sequences = tokenizer.texts_to_sequences(x_train)
x_train_seq = pad_sequences(sequences, maxlen=MAXLEN)
sequences_val = tokenizer.texts_to_sequences(x_validation)
x_val_seq = pad_sequences(sequences_val, maxlen=MAXLEN)
sequences_test = tokenizer.texts_to_sequences(x_test)
x_test_seq = pad_sequences(sequences_test, maxlen=MAXLEN)

以下是我的模型:

MAXLEN = 25
NUM_WORDS = 5000
VECTOR_DIMENSION = 100
tweet_input = Input(shape=(MAXLEN,), dtype='int32')
tweet_encoder = Embedding(NUM_WORDS, VECTOR_DIMENSION, input_length=MAXLEN)(tweet_input)
# 组合n-gram以优化结果
bigram_branch = Conv1D(filters=100, kernel_size=2, padding='valid', activation="relu", strides=1)(tweet_encoder)
bigram_branch = GlobalMaxPooling1D()(bigram_branch)
trigram_branch = Conv1D(filters=100, kernel_size=3, padding='valid', activation="relu", strides=1)(tweet_encoder)
trigram_branch = GlobalMaxPooling1D()(trigram_branch)
fourgram_branch = Conv1D(filters=100, kernel_size=4, padding='valid', activation="relu", strides=1)(tweet_encoder)
fourgram_branch = GlobalMaxPooling1D()(fourgram_branch)
merged = concatenate([bigram_branch, trigram_branch, fourgram_branch], axis=1)
merged = Dense(256, activation="relu")(merged)
merged = Dropout(0.25)(merged)
output = Dense(1, activation="sigmoid")(merged)
optimizer = optimizers.adam(0.01)
model = Model(inputs=[tweet_input], outputs=[output])
model.compile(loss="binary_crossentropy", optimizer=optimizer, metrics=['accuracy'])
model.summary()
# 训练模型
history = model.fit(x_train_seq, y_train, batch_size=32, epochs=5, validation_data=(x_val_seq, y_validation))

我还尝试将最终Dense层的激活数从1改为2,但得到一个错误:

Error when checking target: expected dense_12 to have shape (2,) but got array with shape (1,)

回答:

您在进行二分类。因此,您的Dense层包含一个使用sigmoid激活函数的单元。Sigmoid函数输出一个在[0,1]范围内的值,这对应于给定样本属于正类(即类别1)的概率。所有低于0.5的值被标记为0(即负类),所有高于0.5的值被标记为1。因此,要找到预测的类别,您可以执行以下操作:

preds = model.predict(data)
class_one = preds > 0.5

class_one中的真元素对应于标记为1的样本(即正类)。

附加信息:要找到您的预测的准确率,您可以轻松地将class_one与真实标签进行比较:

acc = np.mean(class_one == true_labels)

请注意,我假设true_labels包含0和1。


此外,如果您的模型是使用Sequential类定义的,那么您可以轻松使用predict_classes方法:

pred_labels = model.predict_classes(data)

然而,由于您使用Keras的函数式API构建模型(在我看来,这是一个非常好的做法),您无法使用predict_classes方法,因为对于这种模型它是未定义的。

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注