本文介绍了如何确定Keras上的卷积神经网络预测的二进制类?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在建立一个CNN,以便对Keras进行情感分析。
一切运行正常,模型已经过训练,可以投入生产。

I'm building a CNN to perform sentiment analysis on Keras.Everything is working perfectly, the model is trained and ready to be launched to production.

但是,当我尝试通过使用方法 model.predict()仅输出关联的概率。我尝试使用方法 np.argmax(),但是即使它应该为1,它也会始终输出0,尽管它应该为1(在测试集上,我的模型已实现精度的80%)。

However, when I try to predict on new unlabelled data by using the method model.predict() it only outputs the associated probability. I tried to use the method np.argmax() but it always outputs 0 even when it should be 1 (on test set, my model achieved 80% of accuracy).

这是我用于预处理数据的代码:

Here is my code to pre-process the data:

# Pre-processing data
x = df[df.Sentiment != 3].Headlines
y = df[df.Sentiment != 3].Sentiment

# Splitting training, validation, testing dataset
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)

# Combinating n-gram to optimize results
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()

# Training the model
history = model.fit(x_train_seq, y_train, batch_size=32, epochs=5, validation_data=(x_val_seq, y_validation))

我还尝试将最终Dense层上的激活次数从1更改为2,但是我出现错误:

I also tried to change the number of activations on the final Dense layer from 1 to 2, but I get an error:

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


推荐答案

您正在执行二进制classi功能。因此,您有一个由一个单元组成的密集层,其激活功能为 sigmoid 。 Sigmoid函数输出范围为[0,1]的值,该值对应于给定样本属于肯定类别(即类别1)的概率。低于0.5的所有内容都标记为零(即否定类别),高于0.5的所有内容都标记为1。因此,要找到预测的类,您可以执行以下操作:

You are doing binary classification. So you have a Dense layer consisting of one unit with an activation function of sigmoid. Sigmoid function outputs a value in range [0,1] which corresponds to the probability of the given sample belonging to positive class (i.e. class one). Everything below 0.5 is labeled with zero (i.e. negative class) and everything above 0.5 is labeled with one. So to find the predicted class you can do the following:

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

class_one 的真实元素对应于

奖金::要查找预测的准确性,您可以轻松地比较具有真实标签的class_one

Bonus: to find the accuracy of your predictions you can easily compare class_one with the true labels:

acc = np.mean(class_one == true_labels)

请注意,我假设 true_labels

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

Further, if your model were defined using Sequential class, then you could easily use predict_classes method:

pred_labels = model.predict_classes(data)

但是,由于您使用Keras功能API来构建模型(在我看来,这样做是非常好的事情),您不能使用 predict_classes 方法,因为此类模型的定义不明确。

However, since you are using Keras functional API to construct your model (which is a very good thing to do so, in my opinion), you can't use predict_classes method since it is ill-defined for such models.

这篇关于如何确定Keras上的卷积神经网络预测的二进制类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-18 04:42