Как вычислить несмешанные вторые частные производные в Tensorflow - PullRequest
1 голос
/ 26 февраля 2020

В настоящее время я использую tenorflow v1.15 и у меня возникли проблемы с вычислением несмешанных вторых производных. Я никогда не видел решения для стекового потока, которое позволяет избежать ненужных вычислений смешанных производных. Скажем, мои входные данные имеют размер input = tf.compat.v1.placeholder(type=tf.float32, shape=(None, A, B)) и скаляр output (через серию tf.matmul и tf.reduce_sum) формы (None,). Я попробовал следующее, пытаясь получить несмешанные вторые производные:

  • Запуск tf.gradients(output, input) возвращает вектор градиента grad1 формы (None, A, B), такой же формы, как input. Выполнение grad2 = tf.gradients(grad1, input) не дает несмешанных вторых производных (даже не гессиана), так как Tensorflow, похоже, имеет это странное поведение, когда вы получите grad2, имеющий такую ​​же форму, как input и i -ая запись grad2 (представьте себе одну партию) sum(d2y/dx[j]dx[i]) для всех (dy / dx) с в grad1.
  • Используя tf.hessians (или хотя бы некоторую реализацию кода здесь: https://github.com/tensorflow/tensorflow/blob/v2.1.0/tensorflow/python/ops/gradients_impl.py#L333) и извлеките несмешанные частные производные. Тем не менее, это включает в себя ненужные вычисления смешанных вторых частных производных, и это также делает это между партиями. Следовательно, число вычислений составляет O(batch_size^2 * n_variables^2). Что мне действительно нужно, так это просто вычисления O(batch_size*n_variables). Как и ожидалось, я столкнулся с проблемами памяти графического процессора при использовании этого метода, так как число переменных в моей сети довольно большое.
  • Создайте список входов размера 1, а затем измените его, то есть input_list=[tf.compat.v1.placeholder(type=tf.float32, shape=1) for _ in range(batch_size*A*B)], input=tf.reshape(input_list, shape=(-1, A, B)). Опять же, используйте a для l oop, чтобы получить первый градиент и второй градиент через grad1 = [tf.gradients(output, x) for x in input_list], grad2 = [tf.gradient(g, x) for (g,x) in zip(grad1, input_list)]. Это дает мне желаемые результаты и не вычисляет другие смешанные частные производные. Тем не менее, это очень медленно, скорее всего, из-за использования для циклов.

Кто-нибудь знает, как этого добиться?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...