Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/356.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Keras自定义softmax层:是否可以在softmax层的输出中将输出神经元设置为0,并将零作为输入层中的数据?_Python_Machine Learning_Keras_Neural Network_Softmax - Fatal编程技术网

Python Keras自定义softmax层:是否可以在softmax层的输出中将输出神经元设置为0,并将零作为输入层中的数据?

Python Keras自定义softmax层:是否可以在softmax层的输出中将输出神经元设置为0,并将零作为输入层中的数据?,python,machine-learning,keras,neural-network,softmax,Python,Machine Learning,Keras,Neural Network,Softmax,我有一个神经网络,最后一层有10个输出神经元,使用softmax激活。我还确切地知道,基于输入值,输出层中的某些神经元应该有0个值。所以我有一个由10个神经元组成的特殊输入层,每个神经元要么是0,要么是1 如果输入神经元3也为0,是否有可能强迫输出神经元3的值=0 action_input = Input(shape=(10,), name='action_input') ... x = Dense(10, kernel_initializer = RandomNormal(),bias_i

我有一个神经网络,最后一层有10个输出神经元,使用softmax激活。我还确切地知道,基于输入值,输出层中的某些神经元应该有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)。但我想在网络中解决这个问题,并在网络培训中使用它。我应该为此使用自定义层吗?

您可以使用
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])

最后,我想出了以下代码:

from keras import backend as K
import tensorflow as tf
def mask_output2(x):
    inp, soft_out = x
    # add a very small value in order to avoid having 0 everywhere
    c = K.constant(0.0000001, dtype='float32', shape=(32, 13))
    y = soft_out + c

    y = Lambda(lambda x: K.switch(K.equal(x[0],0), x[1], K.zeros_like(x[1])))([inp, soft_out])
    y_sum =  K.sum(y, axis=-1)

    y_sum_corrected = Lambda(lambda x: K.switch(K.equal(x[0],0), K.ones_like(x[0]), x[0] ))([y_sum])

    y_sum_corrected = tf.divide(1,y_sum_corrected)

    y = tf.einsum('ij,i->ij', y, y_sum_corrected)
    return y

所以你想让一些输出神经元为零,同时也重新缩放其他神经元,使它们的和为1?嗨,我试着让它工作,但有一个错误:在“y/=K.sum(y,axis=-1)”行中,因为y张量是(batch_size,5)的形状,K.sum返回(5)的形状,python在第一次运行时报告了一个错误。最重要的是,情况有点复杂,因为我们必须避免被零除,如果K.sum返回零,我们不仅需要将其更正为1,而且我们还必须以某种方式将inp行数据设置为与零不同的值,以便在最后对其进行整形,并使输出之和等于1。你能帮忙吗?@user898160它在我的机器上工作。总和的结果将被广播。你有什么错误?编辑您的问题并添加您得到的错误。至于零和,它只在输入都为零时发生,否则它永远不会发生,因为Softmax的输出根本不是零。