如何将Keras预测输出转换为所需的二进制值



我有一个包含32个输入节点、20个隐藏节点和65个输出节点的网络。我的网络输入实际上是一个长度为32的散列码,输出是单词。

输入是哈希中每个字符的ascii值除以256。网络的输出是我制作的二进制表示。例如,假设a等于00000,b等于00001,依此类推。它只包括字母表和空格,这就是为什么每个字符只有5位的原因。我的训练输入最多只能包含13个字符。所以我的输出节点是13*5=65。我期待一个类似10101010101010101010101010101010101010101010101010101010101001011的二进制输出。给定32长度的哈希码作为输入,比特序列最多可以预测16个字符的单词。

model = Sequential([
Dense(32, input_shape=(32,), activation = 'relu'),
Dense(20, activation='relu'),
Dense(65, input_shape=(65,), activation='softmax')
])
model.summary()
model.compile(Adam(lr=.001), loss='binary_crossentropy', metrics=  ['accuracy'])
model.fit(train_samples, train_labels, batch_size=1000, epochs=10000,shuffle = True, verbose=2)

当我尝试使用以下代码进行预测时:

clf.predict(X)

它总是输出小于0.5的小十进制值。

[[8.95109400e-03 1.11340620e-02 1.27389077e-02 1.90807953e-02
1.56925414e-02 7.47500360e-03 1.30378362e-02 1.67052317e-02
1.07944654e-02 9.68935993e-03 9.82633699e-03 1.29385451e-02
1.56633276e-02 1.38113154e-02 1.50949452e-02 8.81231762e-03
1.26177669e-02 1.46279763e-02 1.42763760e-02 1.31389238e-02
8.32264405e-03 1.52036361e-02 1.52883027e-02 1.47563582e-02
1.19247697e-02 1.16073946e-02 1.72672570e-02 1.35995271e-02
1.77132934e-02 1.33292647e-02 1.41840307e-02 1.78522542e-02
9.77656059e-03 1.82192177e-02 9.86329466e-03 1.62205566e-02
1.95278302e-02 9.18696448e-03 2.06225738e-02 1.01496875e-02
2.08229423e-02 2.36334335e-02 6.02523983e-03 2.36746706e-02
6.56269025e-03 2.44314633e-02 2.70614270e-02 4.14136378e-03
2.72923186e-02 3.86772421e-03 2.90246904e-02 2.92722285e-02
3.06371972e-03 2.97660977e-02 1.89558265e-03 3.17853205e-02
3.13901827e-02 1.13886443e-03 3.24600078e-02 1.15508994e-03
3.36604454e-02 3.36041413e-02 4.59054590e-08 3.35478485e-02
4.63940282e-08]]

我期待一个二进制输出。如何获得所需的二进制值?当它接近0时,我试着将其近似为0,当它接近1时,我也试着将它近似为1。对吗?如果是这样,那么我的输出总是0,因为所有输出都接近0。我认为这是不对的。请帮忙。

激活函数中可能存在误解。

softmax是为"一个正确的类"设计的,而不是为65个可能正确的类设计的
softmax结果的总和将始终为1,因此您可能不会有(m(以上的任何东西。5确实如此。

使用sigmoid激活。

您对最后一层的激活导致了问题。当使用softmax激活时,模型输出的方式是模型的输出总和为1。这不是你想要的行为。二进制激活有两个选项。第一个选择是sigmoid激活(它输出0到1之间的值(。第二个选项是tanh函数(它输出介于-1和1之间的值(。要转换为二进制值,对于sigmoid函数使用greather than or equals to 0.5谓词,对于tanhgreather than or equals to 0谓词。

对神经网络来说,编码字符的方式不是一种有效的方式。对输入使用嵌入向量或一个热编码,也可以考虑对输出节点使用一个热编码器。

我的建议:

带嵌入

model = Sequential([
Embedding(input_dim, output_dim, input_length=input_length),
Dense(32, activation = 'relu'),
Dense(20, activation='relu'),
Dense(num_of_classes, activation='softmax')
])

使用一个热编码

model = Sequential([
Dense(32,input_shape=(32, number_of_classes), activation = 'relu'),
Dense(20, activation='relu'),
Dense(num_of_classes, activation='softmax')
])
def classify_local(sentence):
ERROR_THRESHOLD = 0.15
input_data = pd.DataFrame([bow(sentence, words)], dtype=float, index=['input'])
results = model.predict([input_data])[0]
results = [[i,r] for i,r in enumerate(results) if r > ERROR_THRESHOLD]
results.sort(key=lambda x: x[1], reverse=True)
return_list = []
for r in results:
return_list.append((classes[r[0]], str(r[1])))
return return_list

最新更新