Преобразование типов теано-тензора

У меня есть график вычислений, построенный с помощью Theano. Это выглядит так:

import theano
from theano import tensor as T
import numpy as np

W1 = theano.shared( np.random.rand(45,32).astype('float32'), 'W1')
b1 = theano.shared( np.random.rand(32).astype('float32'), 'b1')
W2 = theano.shared( np.random.rand(32,3).astype('float32'), 'W2')
b2 = theano.shared( np.random.rand(3).astype('float32'), 'b2')

input  = T.matrix('input')
hidden = T.tanh(T.dot(input, W1)+b1)
output = T.nnet.softmax(T.dot(hidden, W2)+b2)

Теперь отображение из вектора в вектор. Однако ввод задан как матричный тип, поэтому я могу одновременно передавать множество векторов через отображение. Я занимаюсь машинным обучением, и это делает фазу обучения более эффективной.

Проблема в том, что после этапа обучения я хотел бы просмотреть отображение как вектор в вектор, чтобы я мог вычислить:

jac = theano.gradient.jacobian(output, wrt=input)

jacobian жалуется, что ввод не TensorType(float32, vector). Есть ли способ изменить тип входного тензора без перестройки всего графа вычислений?


person Matt Hancock    schedule 08.10.2014    source источник
comment
Невозможно ответить на этот вопрос без конкретного примера - в принципе вы можете изменить форму тензоров так же легко, как и массивы numpy. То же самое касается нарезки. Вам понадобится любая из этих операций, если я правильно понимаю. input.reshape((-1,)) составляет длинный вектор. input[:, 0] выбирает первый столбец. ХТН   -  person eickenberg    schedule 09.10.2014
comment
Проблема с использованием измененного или сплющенного тензора в вызове jacobian заключается в том, что этот измененный тензор не является частью графа вычислений output. Поток: ввод => материал => вывод. Можно ли вставить изменение формы между вводом и прочим?   -  person Matt Hancock    schedule 09.10.2014
comment
Я не знаю. Но если бы у нас был рабочий пример, мы могли бы узнать :)   -  person eickenberg    schedule 09.10.2014
comment
Я добавил пример графика вычислений. Этот граф вообще строится внутри объекта по аргументам пользователя. Так что этот график не всегда выглядит именно так. Тем не менее, input всегда является матрицей, но моделируемая неотъемлемая функция является векторной. Я спрашиваю, можно ли изменить TensorType из input после построения этого графика.   -  person Matt Hancock    schedule 09.10.2014
comment
В theano 0.6.0 я не получаю эту ошибку. Тем не менее, я получаю один из-за формы вывода, но jac = theano.gradient.jacobian(output.flatten(), wrt=input) исправляет это и должно быть в порядке для вас, если вы хотите оценить это одно изображение за раз. Если это не работает для вас, вы можете сделать input=T.fvector(), а затем преобразовать его в скрытую матрицу, используя hidden = T.tanh(T.dot(input.reshape((-1, W1.shape[0])), W1)+b1). (Мне любопытно - это для манипулирования входными образцами? :)). Не могли бы вы исправить опечатки в выражениях для b1 и b2?   -  person eickenberg    schedule 09.10.2014
comment
Да, я должен был упомянуть, что выравнивание output было одной из проблем. Это было легко исправить, так как output находится в конце цепочки вычислений. Я все еще получал сообщение об ошибке на 0.6.0 в отношении формы input, но когда я попытался выполнить отдельную установку на отдельной машине с версией 0.6.0.dev-RELEASE, jacobian отлично работает с output.flatten() и input как TensorType(float32, matrix). Я предполагаю, что это было недавнее обновление, хотя я не уверен, почему это будет работать в вашем 0.6.0, но не в моем.   -  person Matt Hancock    schedule 09.10.2014
comment
Чтобы ответить на ваш второй вопрос (это для манипулирования входными выборками?), я тренирую нейронные сети и проверяю свойства сети после того, как параметры были изучены. На этапе обучения более эффективно передавать входные данные пакетами (поэтому input должна быть матрицей). После этого я хотел бы измерить якобиан сети о точке. Я не мог сделать это в своем 0.6.0, не установив input в качестве типа вектора и не перестроив всю цепочку вычислений.   -  person Matt Hancock    schedule 09.10.2014


Ответы (1)


Технически это возможное решение:

import theano
from theano import tensor as T
import numpy as np

W1 = theano.shared( np.random.rand(45,32).astype('float32'), 'W1')
b1 = theano.shared( np.random.rand(32).astype('float32'), 'b1')
W2 = theano.shared( np.random.rand(32,3).astype('float32'), 'W2')
b2 = theano.shared( np.random.rand(3).astype('float32'), 'b2')

input  = T.vector('input') # it will be reshaped!
hidden = T.tanh(T.dot(input.reshape((-1, 45)), W1)+b1)
output = T.nnet.softmax(T.dot(hidden, W2)+b2)

#Here comes the trick
jac = theano.gradient.jacobian(output.reshape((-1,)), wrt=input).reshape((-1, 45, 3))

Таким образом, jac.eval({input: np.random.rand(10*45)}).shape приведет к (100, 45, 3)!

Проблема в том, что он вычисляет производную по пакетному индексу. Таким образом, теоретически первое число 1x45 может влиять на все 10x3 выходов (в пакете длиной 10).

Для этого есть несколько решений. Вы можете провести диагональ по первым двум осям, но, к сожалению, Theano не реализует это, numpy реализует< /а>!

Я думаю, что это можно сделать с помощью scan, но это уже другой вопрос.

person BGabor    schedule 10.02.2017