Keras中有几个与梯度计算过程有关的占位符:
所以,在你提供的例子,为了计算梯度,你需要饲料x
,y
并sample_weights
进入图形。这就是错误的根本原因。
内部Model._make_train_function()
有以下几行代码,显示了K.function()
在这种情况下如何构造必要的输入:
inputs = self._Feed_inputs + self._Feed_targets + self._Feed_sample_weights
if self.uses_learning_phase and not isinstance(K.learning_phase(), int):
inputs += [K.learning_phase()]
with K.name_scope('training'):
...
self.train_function = K.function(inputs,
[self.total_loss] + self.metrics_tensors,
updates=updates,
name='train_function',
**self._function_kwargs)
通过模仿此功能,您应该能够获得norm值:
def get_gradient_norm_func(model):
grads = K.gradients(model.total_loss, model.trainable_weights)
summed_squares = [K.sum(K.square(g)) for g in grads]
norm = K.sqrt(sum(summed_squares))
inputs = model.model._Feed_inputs + model.model._Feed_targets + model.model._Feed_sample_weights
func = K.function(inputs, [norm])
return func
def main():
x = np.random.random((128,)).reshape((-1, 1))
y = 2 * x
model = Sequential(layers=[Dense(2, input_shape=(1,)),
Dense(1)])
model.compile(loss='mse', optimizer='rmsprop')
get_gradient = get_gradient_norm_func(model)
history = model.fit(x, y, epochs=1)
print(get_gradient([x, y, np.ones(len(y))]))
执行输出:
Epoch 1/1
128/128 [==============================] - 0s - loss: 2.0073
[4.4091368]
请注意,由于您使用Sequential
而不是Model
,model.model._Feed_*
因此需要而不是model._Feed_*
。