Частная производная Теано по элементу в символическом векторе

Недавно я столкнулся с некоторыми узкими местами производительности с производными символьных матриц в Sympy (в частности, одна строка кода, оценивающая символьные матрицы посредством подстановки с использованием лямбда-выражений, занимала около 90% времени выполнения программы), поэтому я решил попробовать Theano.

Его предыдущее приложение оценивало частные производные по гиперпараметрам гауссовского процесса, где использование матрицы размерности (1, k) символов Симпи (MatrixSymbol) хорошо работало с точки зрения итерации по этому списку и дифференцирования матрицы по каждому элементу.

Однако это не переносится в Theano, и в документации, похоже, не подробно описано, как это сделать. Индексирование символьного вектора в Theano возвращает тип Subtensor, который недопустим для вычисления градиента.

Ниже приведена простая (но полностью алгоритмически неверная - урезанная до функциональности, которую я пытаюсь получить) версия того, что я пытаюсь сделать.

РЕДАКТИРОВАТЬ: я изменил пример кода, чтобы включить данные в качестве тензора для передачи в функцию, как это предлагается ниже, и включил альтернативную попытку вместо этого использовать список отдельных скалярных тензоров, поскольку я не могу индексировать значения символического вектора Theano. , хотя тоже безрезультатно.

import theano
import numpy as np

# Sample data
data = np.array(10*np.random.rand(5, 3), dtype='int64')

# Not including data as tensor, incorrect/invalid indexing of symbolic vector
l_scales_sym = theano.tensor.dvector('l_scales')
x = theano.tensor.dmatrix('x')
f = x/l_scales_sym
f_eval = theano.function([x, l_scales_sym], f)

df_dl = theano.gradient.jacobian(f.flatten(), l_scales_sym[0])
df_dl_eval = theano.function([x, l_scales_sym], df_dl)

Во второй последней строке фрагмента кода я пытаюсь получить частную производную по одному из элементов в списке переменных «шкалы длин», но такая индексация неприменима к символическим векторам.

Любая помощь будет принята с благодарностью!


person mediantis    schedule 27.07.2016    source источник


Ответы (1)


При использовании theano все переменные должны быть определены как theano тензоры (или общие переменные); в противном случае переменная не становится частью вычислительного графа. В f = data/l_scales_sym переменная data представляет собой массив numpy. Попробуйте также определить его как тензор, он должен работать.

person Mehdi    schedule 27.07.2016
comment
Спасибо @Мехди. Вероятно, мне все еще не хватает больших объемов знаний о том, как работает Theano (работаю над этим), но будет ли это означать, что каждый раз, когда выполняются вычисления, мне нужно будет заменять свой набор данных обратно? Я не понимаю, как Theano хранит свои данные и работает с ними, поэтому, возможно, накладные расходы, связанные с этим, намного перевешиваются общим приростом производительности по сравнению с использованием матриц Sympy. - person mediantis; 27.07.2016
comment
Общий процесс часто выглядит следующим образом: определите переменные (все символические переменные, которые вы хотите использовать, должны быть теано-тензорами, даже если вы используете скаляр). Затем вы определяете свою функцию, как только что сделали, используя все математические операции и теано-функции. например grad. Затем используйте `theano.function([входной список], вывод)' для компиляции вашей определенной функции. Затем это становится похоже на стандартную функцию Python, которую вы можете вызывать с помощью входных данных массива numpy. Также может быть полезно посмотреть: учебник - person Mehdi; 27.07.2016
comment
Мое главное препятствие, которое, кажется, не отображается ни в каких примерах в документах или вообще во всем, что мне удалось найти на различных форумах и т. д. онлайн выполняет частные производные по каждому измерению исходной матрицы данных - я отразил некоторые из предложенных вами изменений и вторую попытку сделать это во фрагменте кода выше. - person mediantis; 27.07.2016
comment
Две проблемы: 1. Строка l_symbols = [theano.tensor.dvector('l' + str(i)) for i in range(data.shape[1])] — это список Python, а не матрица (т. е. теано-тензор). 2. В theano.function([x] + l_symbols, df_dl0) вы должны передать список входов. Утверждение [x] + l_symbols не должно быть правильным. Но я думаю, что для вашей проблемы вам лучше использовать переменные shared, чтобы облегчить жизнь. Взгляните на это (deeplearning.net/software/theano/ учебник/) - person Mehdi; 27.07.2016
comment
Спасибо. Однако, основываясь на основных примерах, которые у них есть, я не могу приблизиться к тому, чтобы на самом деле иметь переменную тензорного/символического типа и выполнять частные производные по каждому из них, тогда как это почти тривиально с точки зрения логика в Sympy. Если бы вы могли привести базовый пример этого в своем исходном сообщении, это было бы здорово / я отмечу его как принятый ответ. - person mediantis; 28.07.2016
comment
Хорошо.. Я вижу это сейчас. Проблема связана с l_scales_sym[0]. Субтензорный оператор не дифференцируем, что и вызывает ошибку. Например, скажем, x определяется как вектор. Затем, хотя T.grad(x[0], x) в порядке, T.grad(x[0], x[0]) НЕТ. - person Mehdi; 28.07.2016
comment
Да, я понял, что при дифференцировании по всему вектору результирующее оцененное выражение содержит частные производные по каждой переменной, но объединенные, что требует, чтобы программист распаковал их, чтобы получить соответствующие частные производные. Как только я исправлю пару вещей, я добавлю это как ответ позже. - person mediantis; 28.07.2016