首页 > 解决方案 > Keras 自定义 softmax 层:是否可以在基于零的 softmax 层的输出中将输出神经元设置为 0 作为输入层中的数据?

问题描述

我有一个神经网络,在最后一层使用 softmax 激活有 10 个输出神经元。我也确切地知道,根据输入值,输出层中的某些神经元应该有 0 值。所以我有一个由 10 个神经元组成的特殊输入层,每个神经元不是 0 就是 1。

是否有可能强制让我们说输出神经元没有。如果输入神经元 3 也为 0,则 3 的值 = 0?

action_input = Input(shape=(10,), name='action_input')
...

x = Dense(10,  kernel_initializer = RandomNormal(),bias_initializer = RandomNormal() )(x)
x = Activation('softmax')(x)

我知道有一种方法可以屏蔽掉神经网络外部的输出层的结果,并对所有非零相关的输出进行重新整形(以便总和为 1)。但我想在网络内解决这个问题,并在网络训练期间也使用它。我应该为此使用自定义图层吗?

标签: pythonmachine-learningkerasneural-networksoftmax

解决方案


您可以使用Lambda图层并K.switch检查输入中的零值并在输出中屏蔽它们:

from keras import backend as K

inp = Input((5,))
soft_out = Dense(5, activation='softmax')(inp)
out = Lambda(lambda x: K.switch(x[0], x[1], K.zeros_like(x[1])))([inp, soft_out])

model = Model(inp, out)

model.predict(np.array([[0, 3, 0, 2, 0]]))
# array([[0., 0.35963967, 0., 0.47805876, 0.]], dtype=float32)

但是,如您所见,输出的总和不再是一。如果您希望总和为 1,则可以重新调整这些值:

def mask_output(x):
    inp, soft_out = x
    y = K.switch(inp, soft_out, K.zeros_like(inp))
    y /= K.sum(y, axis=-1)
    return y

# ...
out = Lambda(mask_output)([inp, soft_out])

推荐阅读