TensorFlow:计算Hessian矩阵(和更高阶导数)

ste*_*ano 4 python matrix tensorflow

我希望能够为我的损失函数计算更高阶导数.至少我希望能够计算Hessian矩阵.目前我正在计算Hessian的数值近似值,但这更昂贵,更重要的是,据我所知,如果矩阵病态(条件数非常大),则不准确.

Theano通过符号循环来实现这一点,请参见此处,但Tensorflow似乎还不支持符号控制流,请参见此处.在TF github页面上已经提出了类似的问题,请参见此处,但看起来似乎没有人对此问题进行了一段时间的跟进.

是否有人了解TensorFlow中更近期的发展或计算高阶导数(象征性地)的方法?

Raj*_*tra 8

好吧,你可以毫不费力地计算粗体矩阵!

假设您有两个变量:

x = tf.Variable(np.random.random_sample(), dtype=tf.float32)
y = tf.Variable(np.random.random_sample(), dtype=tf.float32)
Run Code Online (Sandbox Code Playgroud)

以及使用这两个变量定义的函数:

f = tf.pow(x, cons(2)) + cons(2) * x * y + cons(3) * tf.pow(y, cons(2)) + cons(4) * x + cons(5) * y + cons(6)
Run Code Online (Sandbox Code Playgroud)

哪里:

def cons(x):
    return tf.constant(x, dtype=tf.float32)
Run Code Online (Sandbox Code Playgroud)

所以在代数术语中,这个函数是

在此输入图像描述

现在我们定义一个计算粗麻布的方法:

def compute_hessian(fn, vars):
    mat = []
    for v1 in vars:
        temp = []
        for v2 in vars:
            # computing derivative twice, first w.r.t v2 and then w.r.t v1
            temp.append(tf.gradients(tf.gradients(f, v2)[0], v1)[0])
        temp = [cons(0) if t == None else t for t in temp] # tensorflow returns None when there is no gradient, so we replace None with 0
        temp = tf.pack(temp)
        mat.append(temp)
    mat = tf.pack(mat)
    return mat
Run Code Online (Sandbox Code Playgroud)

并称之为:

# arg1: our defined function, arg2: list of tf variables associated with the function
hessian = compute_hessian(f, [x, y])
Run Code Online (Sandbox Code Playgroud)

现在我们抓住tensorflow会话,初始化变量,然后运行hessian :

sess = tf.Session()
sess.run(tf.initialize_all_variables())
print sess.run(hessian)
Run Code Online (Sandbox Code Playgroud)

注意:由于我们使用的函数本质上是二次的(并且我们进行了两次微分),所以返回的粗体将具有恒定值而不管变量如何.

输出是:

[[ 2.  2.]
[ 2.  6.]]
Run Code Online (Sandbox Code Playgroud)

  • 警告,亲爱的读者:这个例子只适用于`vars`的内容包含单个浮点数的情况.如果任何是向量,矩阵或更高维度的Tensor,则此代码将失败.相反,使用`tf.hessians`,它将计算与'vars`中每个变量相关的Hessian部分(只要每个变量是一个向量).如果你想要FULL Hessian(包括变量之间的所有成对交互),你需要从包含你关心的每个变量的单个超向量开始,然后从那里切片. (5认同)