广播从矩阵创建的子张量(Theano)
Broadcasting for subtensor created from matrix (Theano)
我想从矩阵创建两个子张量,使用 select 相应行的索引。
一个子张量有几行,另一个只有一行,应该广播以允许按元素添加。
我的问题是:我如何表明我想允许在给定索引的子张量中的特定维度上进行广播(下例中的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 进行整形会得到不同的结果?
问题是您的 theano 函数事先不知道正确的 (ri
) 索引将只有 1 个元素(所以众所周知,您将尝试从中减去 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 库来制作更具可读性的 theano 代码。在你的情况下:
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)
我想从矩阵创建两个子张量,使用 select 相应行的索引。 一个子张量有几行,另一个只有一行,应该广播以允许按元素添加。
我的问题是:我如何表明我想允许在给定索引的子张量中的特定维度上进行广播(下例中的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 进行整形会得到不同的结果?
问题是您的 theano 函数事先不知道正确的 (ri
) 索引将只有 1 个元素(所以众所周知,您将尝试从中减去 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 库来制作更具可读性的 theano 代码。在你的情况下:
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)