Градиенты тензорного потока: без автоматической неявной суммы

#python #tensorflow #gradient

#python #тензорный поток #градиент

Вопрос:

В tensorflow, если у вас есть два тензора x , y и вы хотите иметь градиенты y относительно x использования tf.gradients(y,x) . Тогда на самом деле получается :

 gradient[n,m] = sum_ij d y[i,j]/ d x[n,m]
  

Существует сумма по индексам y, есть ли способ избежать этой неявной суммы? Чтобы получить весь тензор градиента gradient[i,j,n,m] ?

Ответ №1:

Вот моя работа, связанная с тем, чтобы просто взять производную от каждого компонента (как также упоминалось @Yaroslav), а затем снова собрать их все вместе в случае тензоров ранга 2 (матриц):

 import tensorflow as tf

def twodtensor2list(tensor,m,n):
    s = [[tf.slice(tensor,[j,i],[1,1]) for i in range(n)] for j in range(m)]
    fs = []
    for l in s:
        fs.extend(l)
    return fs

def grads_all_comp(y, shapey, x, shapex):
    yl = twodtensor2list(y,shapey[0],shapey[1])
    grads = [tf.gradients(yle,x)[0] for yle in yl]
    gradsp = tf.pack(grads)
    gradst = tf.reshape(gradsp,shape=(shapey[0],shapey[1],shapex[0],shapex[1]))
    return gradst
  

Теперь grads_all_comp(y, shapey, x, shapex) будет выведен тензор ранга 4 в желаемом формате. Это очень неэффективный способ, потому что все нужно нарезать и переупаковывать вместе, поэтому, если кто-то найдет лучшее, мне было бы очень интересно его увидеть.

Ответ №2:

Способа нет. TensorFlow 0.11 tf.gradients реализует стандартный AD в обратном режиме, который дает производную от скалярной величины. Вам нужно будет вызывать tf.gradients для каждого y[i,j] отдельно

Комментарии:

1. этот ответ устарел, как и для tf2.7 (и, возможно, более ранних версий), см. Мой ответ ниже

Ответ №3:

для будущих читателей:

Tensorflow добился некоторых успехов, а что касается tf2.7 (и, возможно, даже более ранних версий), ответ на этот вопрос заключается в использовании tf.GradientTape.jacobian

https://www.tensorflow.org/guide/advanced_autodiff#jacobians