TensorFlow Batch Hessian

问题描述 投票:0回答:1

我正在构建一个必须逼近某个多元函数的神经网络,例如 f(x)。损失函数定义为网络的二阶导数与函数f的接近程度。为此,我必须计算 f(x) 的 Hessian 矩阵。我编写了一个自定义 TensorFlow 模型,看起来像这样

class ApproximateModel(tf.keras.Model):
    @tf.function
    def f_true_hessian(x: tf.Tensor) -> tf.Tensor:
        # Some function that should return the actual Hessian
        return x
    
    def train_step(self, data):
        # tf.get_shape(x) -> (batch_size, dimension_x)
        x = data[0]
        
        # Calculate loss
        with tf.GradientTape() as second_tape:
            with tf.GradientTape() as first_tape:
                first_tape.watch(x)
                second_tape.watch(x)
                
                f = self(x, training=True)
            
            f_x = first_tape.gradient(f, x)
            second_tape.watch(f_x)
        
        f_jacobian = second_tape.jacobian(f_x, x)
        # tf.get_shape(f) -> (batch_size, dimension_x, batch_size, dimension_x)
        
        # I want to get (batch_size, dimension_x, dimension_x) somehow..
        loss = tf.math.reduce_mean(tf.math.square(tf.reduce_sum(f_jacobian, axis=[1, 2]) - self.f_true_hessian(x))))
        return loss

对于感兴趣的读者,这种类型的网络的应用是近似偏微分方程,如这里

如果我没有批量大小,上面的代码可以很好地工作。如果我有一批 x 的样本,我不知道如何获得 Hessian 矩阵。如何获得所需的输出,其中仅计算 dimension_x 的 Hessian 矩阵并省略 batch_size

python tensorflow derivative
1个回答
0
投票

我刚刚发现自己处于类似的情况。我不知道这是否是最好的解决方案,但我所做的是堆叠渐变

f_jacobian = tf.stack([second_tape.gradient(f_x[:,i:i+1], x) for i in range(dimension_x)], 1)
© www.soinside.com 2019 - 2024. All rights reserved.