我希望能够为损失函数计算高阶导数。至少我希望能够计算Hessian矩阵。目前我正在计算Hessian的数值近似值,但这更昂贵,更重要的是,据我所知,如果矩阵病态(条件数非常大),则不准确。
Theano通过符号循环来实现这一点,请参阅here,但Tensorflow似乎还不支持符号控制流,请参阅here。在TF github页面上提出了类似的问题,请参阅here,但看起来似乎没有人在这个问题上进行了一段时间的跟进。
是否有人了解TensorFlow中更近期的发展或计算高阶导数(象征性地)的方法?
答案 0 :(得分:8)
嗯,你可以毫不费力地计算出粗麻布矩阵!
假设您有两个变量:
x = tf.Variable(np.random.random_sample(), dtype=tf.float32)
y = tf.Variable(np.random.random_sample(), dtype=tf.float32)
和使用这两个变量定义的函数:
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)
其中:
def cons(x):
return tf.constant(x, dtype=tf.float32)
所以在代数术语中,这个函数是
现在我们定义一个计算粗麻布的方法:
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
并将其命名为:
# arg1: our defined function, arg2: list of tf variables associated with the function
hessian = compute_hessian(f, [x, y])
现在我们抓住tensorflow会话,初始化变量,然后运行hessian
:
sess = tf.Session()
sess.run(tf.initialize_all_variables())
print sess.run(hessian)
注意:由于我们使用的函数本质上是二次的(并且我们进行了两次微分),所以返回的粗体将具有恒定值,而与变量无关。
输出结果为:
[[ 2. 2.]
[ 2. 6.]]
答案 1 :(得分:0)
警告:Hessian 矩阵(或更一般地说,张量)的计算和存储成本很高。您实际上可能会重新考虑是否真的需要完整的 Hessian,或者只是一些 Hessian 属性。其中一些,包括迹、范数和顶部特征值可以无需显式 Hessian 矩阵即可获得,只需使用 Hessian 向量乘积预言机即可。反过来,可以有效地实现 hessian-vector 产品(也在领先的 autodiff 框架中,例如 Tensorflow 和 PyTorch)