Как тензорный поток обрабатывает сложный градиент?
Пусть z комплексная переменная, C(z) ее сопряжение. В теории комплексного анализа производная C(z) по z не существует. Но в tesnsorflow мы можем вычислить dC(z)/dz, и результат равен всего 1. Вот пример:
x = tf.placeholder('complex64',(2,2))
y = tf.reduce_sum(tf.conj(x))
z = tf.gradients(y,x)
sess = tf.Session()
X = np.random.rand(2,2)+1.j*np.random.rand(2,2)
X = X.astype('complex64')
Z = sess.run(z,{x:X})[0]
Вход X
[[0.17014372+0.71475762j 0.57455420+0.00144318j]
[0.57871044+0.61303568j 0.48074263+0.7623235j ]]
и результат Z
[[1.-0.j 1.-0.j]
[1.-0.j 1.-0.j]]
Я не понимаю, почему градиент установлен на 1? И я хочу знать, как тензорный поток обрабатывает сложные градиенты в целом.
0 ответов
Как?
Уравнение, используемое Tensorflow для градиента:
Где "*" означает конъюгат.
При использовании определения частных производных по z и z * используется исчисление Виртингера. Исчисление Виртингера позволяет вычислять производную по комплексной переменной для неголоморфных функций. Определение Виртингера:
Почему это определение?
При использовании, например, комплексных нейронных сетей (CVNN), градиенты будут использоваться над неголоморфной скалярной функцией с действительным знаком одной или нескольких комплексных переменных, определение градиента тензорным потоком может быть записано как:
Это определение соответствует литературе по CVNN, например, главе 4, раздел 4.3 этой книги или Amin et al.(между бесчисленными примерами).
Немного поздно, но я тоже недавно столкнулся с этой проблемой.
Ключевым моментом является то, что TensorFlow определяет "градиент" комплексной функции f(z) комплексной переменной как "градиент реальной карты F: (x,y) -> Re(f(x+iy)), выраженное в виде комплексного числа " (градиент этой реальной карты является вектором в R^2, поэтому мы можем выразить его как комплексное число очевидным образом).
По-видимому, причина этого определения заключается в том, что в TF обычно используются градиенты с целью выполнения градиентного спуска на функции потерь и, в частности, для определения направления максимального увеличения / уменьшения этой функции потерь. Использование приведенного выше определения градиента означает, что комплексная функция комплексных переменных может использоваться как функция потерь в стандартном алгоритме градиентного спуска, и в результате реальная часть функции будет минимизирована (что мне кажется несколько разумная интерпретация "оптимизировать эту комплексную функцию").
Теперь, к вашему вопросу, эквивалентный способ записать это определение градиента:
градиент (f):= dF/dx + idF/dy = con(df / dz + dconj(f) / dz)
(вы можете легко убедиться в этом, используя определение d/dz). Вот как TensorFlow обрабатывает сложные градиенты. Что касается случая f(z):=con(z), у нас есть df/dz=0 (как вы упомянули) и dconj(f)/dz=1, что дает gradient(f)=1.
Я написал здесь более подробное объяснение, если вам интересно: https://github.com/tensorflow/tensorflow/issues/3348