Трансляция для субтензора, созданного из матрицы (Theano)

Я хочу создать два подмножества из матрицы, используя индексы для выбора соответствующих строк. В одном подзадаче есть несколько строк, другое – одно, которое должно транслироваться, чтобы обеспечить добавление по элементам.

Мой вопрос: как я могу указать, что я хочу разрешить трансляцию по конкретному измерению в суб тензоре, полученному с учетом индексов ( subtensorRight в примере ниже)?

Вот пример, показывающий, что я хочу сделать:

 import theano import numpy as np import theano.tensor as T def embedding_matrix(D, N, name): W_values = np.random.uniform(size=(D, N)) return theano.shared(value=W_values, name=name) rE = embedding_matrix(4, 5, "rE") lis = T.ivector('lis')# [1,2] subtensorLeft = rE[lis,:] ri = T.ivector('ri')#[1] subtensorRight = rE[ri,:] def fnsim(left, right): return - T.sqrt(T.sum(T.sqr(left - right), axis=1)) distances_test = theano.function( inputs=[lis, ri], outputs=fnsim(subtensorLeft, subtensorRight) ) print distances_test([1,2],[1]) 

Это порождает эту ошибку:

 ValueError: Input dimension mis-match. (input[0].shape[0] = 2, input[1].shape[0] = 1) Apply node that caused the error: Elemwise{Composite{sqr((i0 - i1))}}[(0, 0)](AdvancedSubtensor1.0, AdvancedSubtensor1.0) Toposort index: 2 Inputs types: [TensorType(float64, matrix), TensorType(float64, matrix)] Inputs shapes: [(2, 5), (1, 5)] Inputs strides: [(40, 8), (40, 8)] Inputs values: ['not shown', array([[ 0.39528934, 0.4414946 , 0.36837258, 0.52523446, 0.35431748]])] Outputs clients: [[Sum{axis=[1], acc_dtype=float64}(Elemwise{Composite{sqr((i0 - i1))}}[(0, 0)].0)]] 

===

ОБНОВЛЕНИЕ 1:

Он перестает жаловаться и дает ожидаемый результат при изменении формы subtensorRight :

 subtensorRight = rE[ri,:] subtensorRight = subtensorRight.reshape((1, subtensorRight.shape[1])) 

Вопрос: Правильно ли это?

ОБНОВЛЕНИЕ 2:

Это не работает, если я попытаюсь изменить форму, как показано ниже (что, как я думал, эквивалентно перестройке выше):

 subtensorRight = rE[ri,:] subtensorRight = subtensorRight.reshape(subtensorRight.shape) 

Ошибка:

 ValueError: Input dimension mis-match. (input[0].shape[0] = 2, input[1].shape[0] = 1) Apply node that caused the error: Elemwise{Composite{sqr((i0 - i1))}}[(0, 0)](AdvancedSubtensor1.0, Reshape{2}.0) Toposort index: 6 Inputs types: [TensorType(float64, matrix), TensorType(float64, matrix)] Inputs shapes: [(2, 5), (1, 5)] Inputs strides: [(40, 8), (40, 8)] Inputs values: ['not shown', array([[ 0.54193252, 0.36793023, 0.89009085, 0.02487759, 0.95955664]])] Outputs clients: [[Sum{axis=[1], acc_dtype=float64}(Elemwise{Composite{sqr((i0 - i1))}}[(0, 0)].0)]] 

Вопрос: Почему переформатирование с учетом размерности 0 из подтензора дает другой результат?

One Solution collect form web for “Трансляция для субтензора, созданного из матрицы (Theano)”

Проблема в том, что ваша функция anano не знает заранее, что у правых ( ri ) индексов будет только один элемент (так что для всех в курсе вы будете пытаться вычесть матрицу NxD из матрицы MxD, которая не будет работать в общем, но для вашего случая вы только хотите N = 1.)

Решение состоит в том, чтобы объявить ваш правый индекс как скаляр.

Следующий код, я считаю, делает то, что вы хотите:

 import theano import numpy as np import theano.tensor as T def embedding_matrix(D, N, name): W_values = np.random.uniform(size=(D, N)) return theano.shared(value=W_values, name=name) rE = embedding_matrix(4, 5, "rE") lis = T.ivector('lis')# [1,2] subtensorLeft = rE[lis,:] ri = T.iscalar('ri') # Instead of: ri = T.ivector('ri') subtensorRight = rE[ri,:] def fnsim(left, right): return - T.sqrt(T.sum(T.sqr(left - right), axis=1)) distances_test = theano.function( inputs=[lis, ri], outputs=fnsim(subtensorLeft, subtensorRight) ) print distances_test([1,2],1) # Instead of: distances_test([1,2],[1]) 

(Выходы [-0. -1.01565315] )

Бесстыдная самооценка:

Вы можете использовать библиотеку Plato для создания более читаемого кода anano. В твоем случае:

 from plato.core import symbolic import numpy as np import theano.tensor as T @symbolic def distances_test(matrix, test_rows, reference_row): left = matrix[test_rows] right = matrix[reference_row] return - T.sqrt(T.sum(T.sqr(left - right), axis=1)) f = distances_test.compile() print f(np.random.uniform(size=(4, 5)), np.array([1,2]), 1) 
Python - лучший язык программирования в мире.