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

时间:2018-11-26 13:33:01

标签: python machine-learning keras neural-network

我有一个包含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。我认为这是不对的。请帮忙。

3 个答案:

答案 0 :(得分:1)

您的激活功能可能存在误解。

softmax设计用于“一个正确的类别”,而不是65个可能的正确类别。
softmax结果的总和将始终为1,因此您可能实际上没有.5以上的任何事物。

使用sigmoid激活。

答案 1 :(得分:1)

您激活的最后一层导致了问题。使用softmax激活时,模型以模型输出总和为1的方式输出。这不是您想要的行为。二进制激活有两个选项。第一个选择是S形激活(输出0到1之间的值)。第二个选项是tanh函数(输出值介于-1和1之间)。要转换为二进制值,对于S形函数,请使用greather than or equals to 0.5谓词,对于tanh greather 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')
    ])

答案 2 :(得分:1)

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