无法弄清楚为什么我只从预测函数中获取一个值?



我已经使用keras层构建并训练了一个序列二进制分类模型。在我开始使用predict方法之前,一切似乎都很好。这个函数开始给我一个奇怪的指数值,而不是两个类的概率。这是我在训练后得到的,并在模型上使用预测方法

这个分类模型有两类,比如猫或狗,所以我预计结果会是[999.999900001],表明它是猫。我不知道如何解释我所得到的价值。

这是我的代码:

# Get the data.
(train_texts, train_labels), (val_texts, val_labels) = data
train_labels = np.asarray(train_labels).astype('float32')
val_labels = np.asarray(val_labels).astype('float32')
# Vectorizing data
train_texts,val_texts, word_index = vectorize_data.sequence_vectorize(
train_texts, val_texts)
# Building the model architecture( adding layers to the model)
model = build_model.simple_model_layers(train_texts.shape[1:])
# Setting and compiling with the features like the optimizer, loss and metrics functions
model = build_model.simple_model_compile(model=model)
# This is when the learning happens
history = model.fit(train_texts,
train_labels,
epochs=EPOCHS,
validation_data=(val_texts, val_labels),
verbose=VERBOSE_OFF, batch_size=BATCH_SIZE)
print('Validation accuracy: {acc}, loss: {loss}'.format(
acc=history['val_acc'][-1], loss=history['val_loss'][-1]))
# loading data to predict on
test_text = any
with open('text_req.pickle', 'rb') as pickle_file:
test_text = pickle.load(pickle_file)

print('Lets make a prediction of this requirement:')
prediction = model.predict(test_text, batch_size=None, verbose=0, steps=None)
print(prediction)

以下是简单模型函数的样子:

model = models.Sequential()
model.add(Dense(26, activation='relu', input_shape=input_shape))
model.add(Dense(16, activation='relu'))
model.add(Dense(10, activation='relu'))
model.add(Dense(1, activation='sigmoid'))
return model

渐变取消扫描功能:优化器="dam",损失="二进制交叉熵">

示例数据是字符串类型的,我使用填充和all将其转换为1和0的常量大小矩阵。这些特性有两个类,因此标签仅为1和0。以上都是数据。在我看来,数据似乎不是问题——它可能是比我忽视和未能认识到的更琐碎的事情。

谢谢大家,最后一个问题已经解决,但我需要更好地理解这一点:

我读到sigmoid返回所有可能类的概率,所有概率加起来应该是1。我得到的价值观是:

Validation accuracy: 0.792168688343232, loss: 2.8360600299145804
Let's make a prediction of this requirement:
[[2.7182817, 1.       ]
[2.7182817, 1.       ]
[1.,        2.7182817]
[1. ,       2.7182817]]

它们加起来不等于1,看这些值1或其他值不够直观

您的模型只有一个输出。如果您的训练标签为cat设置为0,为dog设置为1,则意味着如果输出为[[2.977094e-12]],则网络认为它是cat。如果你想要两个类的概率,就像你所期望的那样,那么你需要改变你的模型的输出,如下所示:

model = models.Sequential()
model.add(Dense(26, activation='relu', input_shape=input_shape))
model.add(Dense(16, activation='relu'))
model.add(Dense(10, activation='relu')
model.add(Dense(2, activation='softmax'))

您的标签还需要更改为猫和狗的[1, 0][0, 1]

我想澄清的是,你不会得到一个奇怪的指数值,你只会得到一个怪异的值。E是x10的科学表示法,所以你基本上得到2.7 x 10^-12。我很乐意帮忙,但我无法检查您的数据和模型。我试着用谷歌搜索你代码的一些部分,希望能找到一些澄清,但我似乎找不到这两行代码背后的内容:

model = build_model.simple_model_layers(train_texts.shape[1:])
model = build_model.simple_model_compile(model=model)

我不知道已经建立了什么网络,我想知道至少损失函数和完整的最后一层,这已经有很多了。你也确定你的数据是正确的吗?

编辑:

sigmoid并没有按照你的描述去做,softmax就是这么做的。Sigmoid通常被用作多标签分类,因为它可以检测多个标签为True。Sigmoid输出可以看起来像[0.99,0.3],它可以单独查看每个标签。而Softmax则不然,Softmax可能看起来像[0.99,0.01],并且所有概率的总和总是1。

这解决了这个困惑,现在关于你的输出,我不知道那是什么,它应该在1和0之间,除非我在这里遗漏了什么。

为了回答您向K.Streutker提出的数据问题:神经网络的目标是在新数据上创建你提供给它的标签。如果你想要一个概率分布,那么你也需要提供一个。每个图像都应该有一个标签[1,0]和狗[0,1],或者反转,无论你喜欢什么。然后,一旦模型经过训练,它将能够为您提供两个有意义的输出。损失函数,很可能是交叉熵,采用这些标签和模型的输出,并试图随着时间的推移将差异最小化。这正是你所需要的:

图像(狗(-->模型->损失->更新权重的优化器

标签([0,1](------------------┘

那么预测将看起来像这个

图像->模型->标签

希望我能帮上一点忙!

最新更新