想象一个全连接神经网络,其最后两层结构如下:
[Dense]
units = 612
activation = softplus
[Dense]
units = 1
activation = sigmoid
网络的输出值为 1,但我想知道 sigmoidal 函数的输入 x 是什么(必须是一些高数,因为这里的 sigm(x) 是 1)。
正在关注 indraforyou's回答我设法检索了 Keras 层的输出和权重:
outputs = [layer.output for layer in model.layers[-2:]]
functors = [K.function( [model.input]+[K.learning_phase()], [out] ) for out in outputs]
test_input = np.array(...)
layer_outs = [func([test_input, 0.]) for func in functors]
print layer_outs[-1][0] # -> array([[ 1.]])
dense_0_out = layer_outs[-2][0] # shape (612, 1)
dense_1_weights = model.layers[-1].weights[0].get_value() # shape (1, 612)
dense_1_bias = model.layers[-1].weights[1].get_value()
x = np.dot(dense_0_out, dense_1_weights) + dense_1_bias
print x # -> -11.7
x怎么可能是负数呢?在这种情况下,最后一层输出应该是一个更接近 0.0 而不是 1.0 的数字。 dense_0_out
或 dense_1_weights
是错误的输出或权重吗?
最佳答案
由于您使用的是 get_value()
,我假设您使用的是 Theano 后端。要获取sigmoid激活前节点的值,可以traverse the computation graph .
The graph can be traversed starting from outputs (the result of some computation) down to its inputs using the owner field.
在你的例子中,你想要的是 sigmoid 激活操作的输入 x
。 sigmoid 运算的输出是 model.output
。将这些放在一起,变量 x
就是 model.output.owner.inputs[0]
。
如果你打印出这个值,你会看到 Elemwise{add,no_inplace}.0
,这是一个元素加法操作。从source code可以验证Dense.call()
:
def call(self, inputs):
output = K.dot(inputs, self.kernel)
if self.use_bias:
output = K.bias_add(output, self.bias)
if self.activation is not None:
output = self.activation(output)
return output
激活函数的输入是 K.bias_add()
的输出。
通过对您的代码进行少量修改,您可以在激活之前获取节点的值:
x = model.output.owner.inputs[0]
func = K.function([model.input] + [K.learning_phase()], [x])
print func([test_input, 0.])
对于任何使用 TensorFlow 后端的人:请改用 x = model.output.op.inputs[0]
。
关于python - Keras 在激活函数之前检索节点的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45492318/