获取 Keras ANN 模型中输入的梯度

Adi*_*dhi 5 gradient neural-network keras tensorflow

bce = tf.keras.losses.BinaryCrossentropy()
ll=bce(y_test[0], model.predict(X_test[0].reshape(1,-1)))
print(ll)
<tf.Tensor: shape=(), dtype=float32, numpy=0.04165391>
print(model.input)
<tf.Tensor 'dense_1_input:0' shape=(None, 195) dtype=float32>
model.output
<tf.Tensor 'dense_3/Sigmoid:0' shape=(None, 1) dtype=float32>
grads=K.gradients(ll, model.input)[0]
print(grads)
None
Run Code Online (Sandbox Code Playgroud)

所以在这里我训练了一个 2 隐藏层神经网络,输入有 195 个特征,输出是 1 个大小。我想向神经网络提供名为 X_test 的验证实例,并在 y_test 中逐个提供正确的标签,并为每个实例计算输出相对于输入的梯度,打印时的梯度给我一个“无”。感谢您的帮助。

小智 5

可以使用tf.GradientTape来做到这一点。我编写了以下代码来学习正弦波,并本着这个问题的精神得到它的导数。我认为,应该可以扩展以下代码来计算偏导数。
导入所需的库:

import numpy as np
from tensorflow.keras.layers import Dense, Input
from tensorflow.keras.models import Model, Sequential
from tensorflow.keras.optimizers import Adam
from tensorflow.keras import losses
import tensorflow as tf
Run Code Online (Sandbox Code Playgroud)

创建数据:

x = np.linspace(0, 6*np.pi, 2000)
y = np.sin(x)
Run Code Online (Sandbox Code Playgroud)

定义 Keras 神经网络:

def model_gen(Input_shape):
    X_input = Input(shape=Input_shape)
    X = Dense(units=64, activation='sigmoid')(X_input)
    X = Dense(units=64, activation='sigmoid')(X)
    X = Dense(units=1)(X)
    model = Model(inputs=X_input, outputs=X)
    return model
Run Code Online (Sandbox Code Playgroud)

训练模型:

model = model_gen(Input_shape=(1,))
opt = Adam(lr=0.01, beta_1=0.9, beta_2=0.999, decay=0.001)
model.compile(loss=losses.mean_squared_error, optimizer=opt)
model.fit(x,y, epochs=200)
Run Code Online (Sandbox Code Playgroud)

要获取网络相对于输入的梯度:

x = list(x)
x = tf.constant(x)
with tf.GradientTape() as t:
  t.watch(x)
  y = model(x)

dy_dx = t.gradient(y, x)

dy_dx.numpy()
Run Code Online (Sandbox Code Playgroud)

人们可以进一步可视化 dy_dx 以确保导数有多平滑。最后,请注意,当使用平滑激活(例如 sigmoid)而不是 Relu 时,会得到更平滑的导数,如此处所述