将 python 循环翻译成 Theano
Translating python loop to Theano
我想使用以下公式将 n
个元素的 P
向量转换为 n+1
个元素的 Z
向量:
我能够在 python 中做到这一点:
import numpy as np
def p_to_Z(p):
k = len(p)
Z = np.zeros(k+1)
Z[0] = p[0]
Z[1:k] = [p[i] / (1 - sum(p[range(i)])) for i in range(1,k)]
Z[-1] = 1
return Z
示例:
p_ex = np.array([0.3,0.4,0.1,0.2])
p_to_Z(p_ex)
output:
array([ 0.3, 0.57142857, 0.33333333, 1. , 1. ])
对于具有以下内容的矩阵:
M = np.array([[0.2, 0.05, 0.1],
[0.5, 2.0, 0.2],
[0.1, 0.2, 1.0]])
np.apply_along_axis(p_to_Z, 1, M)
array([[ 0.2 , 0.0625 , 0.13333333, 1.],
[ 0.5 , 4. ,-0.13333333, 1.],
[ 0.1 , 0.22222222, 1.42857143, 1.]])
我一直在尝试将其转化为 theano but I have been getting my ass kicked by the scan 函数。
有人可以帮我在 theano 中定义这些函数吗?我将永远感激不已。
编辑:尝试失败
import theano.tensor as tt
import numpy as np
import theano
from theano.compile.ops import as_op
p = tt.vector('p')
results, updates = theano.scan(lambda i: p[i] / (1 - tt.sum(p[:i-1])), sequences=tt.arange(1,N))
fn = theano.function([p,N],results)
p_ex = np.array([0.3,0.4,0.1,0.2])
Z = fn(p_ex,tt.get_vector_length(p_ex))
和装饰器:
@as_op(itypes=[tt.dvector],otypes=[tt.dvector])
def p_to_Z_theno(p):
N = tt.get_vector_length(p)
Z= theano.scan(lambda i: p[i] / (1 - tt.sum(p[:i - 1])), sequences=tt.arange(1, N))
fn = theano.function([p, N], results)
Z[0]=p[0]
Z[-1]=Z
return(Z)
第一个显然没有产生预期的结果,而第二个给出:
Traceback (most recent call last): File "/usr/lib/python3/dist-packages/IPython/core/interactiveshell.py", line 2882, in run_code
exec(code_obj, self.user_global_ns, self.user_ns) File "<ipython-input-21-211efc53b449>", line 1, in <module>
p_to_Z_theno(p_ex) File "/usr/local/lib/python3.6/dist-packages/theano/gof/op.py", line 615, in __call__
node = self.make_node(*inputs, **kwargs) File "/usr/local/lib/python3.6/dist-packages/theano/gof/op.py", line 983, in make_node
if not all(inp.type == it for inp, it in zip(inputs, self.itypes)): File "/usr/local/lib/python3.6/dist-packages/theano/gof/op.py", line 983, in <genexpr>
if not all(inp.type == it for inp, it in zip(inputs, self.itypes)): AttributeError: 'numpy.ndarray' object has no attribute 'type'
让我们从向量化运算的角度来考虑这个问题。如果我们使用 numpy 的 cumsum
函数,你的初始方程可以写得非常简单:
def p2Z_numpy(p):
Z = np.r_[p, 1]
Z[1:-1] /= np.cumsum(p[:-1])
return Z
例如:
>>> p2Z_numpy([0.3, 0.4, 0.1, 0.2])
array([0.3 , 1.33333333, 0.14285714, 0.25 , 1. ])
这是一个重要起点的原因是 Theano 允许所有相同类型的操作,但规模要大得多。那么让我们在Theano中做同样的除法、串联和累加:
import theano.tensor as tt
import theano.tensor.extra_ops as te
from theano import function
p = tt.vector()
denom = 1 - te.cumsum(p[:-1])
frac = p[1:] / denom
Z = tt.concatentat([p[0:1], frac, [1]])
p2Z = function([p], Z)
正在测试:
>>> p2Z([0.3, 0.4, 0.1, 0.2])
array([0.3 , 0.57142857, 0.33333333, 1. , 1. ])
虽然我将函数分解为多个步骤,但您实际上可以将它变成一个非常丑陋的单行代码:
p = tt.vector()
Z = tt.concatenate([p[0:1], p[1:] / (1 - te.cumsum(p[:-1])), [1]])
p2Z = function([p], Z)
甚至
p2Z = function([p], tt.concatenate([p[0:1], p[1:] / (1 - te.cumsum(p[:-1])), [1]]))
我想使用以下公式将 n
个元素的 P
向量转换为 n+1
个元素的 Z
向量:
我能够在 python 中做到这一点:
import numpy as np
def p_to_Z(p):
k = len(p)
Z = np.zeros(k+1)
Z[0] = p[0]
Z[1:k] = [p[i] / (1 - sum(p[range(i)])) for i in range(1,k)]
Z[-1] = 1
return Z
示例:
p_ex = np.array([0.3,0.4,0.1,0.2])
p_to_Z(p_ex)
output:
array([ 0.3, 0.57142857, 0.33333333, 1. , 1. ])
对于具有以下内容的矩阵:
M = np.array([[0.2, 0.05, 0.1],
[0.5, 2.0, 0.2],
[0.1, 0.2, 1.0]])
np.apply_along_axis(p_to_Z, 1, M)
array([[ 0.2 , 0.0625 , 0.13333333, 1.],
[ 0.5 , 4. ,-0.13333333, 1.],
[ 0.1 , 0.22222222, 1.42857143, 1.]])
我一直在尝试将其转化为 theano but I have been getting my ass kicked by the scan 函数。 有人可以帮我在 theano 中定义这些函数吗?我将永远感激不已。
编辑:尝试失败
import theano.tensor as tt
import numpy as np
import theano
from theano.compile.ops import as_op
p = tt.vector('p')
results, updates = theano.scan(lambda i: p[i] / (1 - tt.sum(p[:i-1])), sequences=tt.arange(1,N))
fn = theano.function([p,N],results)
p_ex = np.array([0.3,0.4,0.1,0.2])
Z = fn(p_ex,tt.get_vector_length(p_ex))
和装饰器:
@as_op(itypes=[tt.dvector],otypes=[tt.dvector])
def p_to_Z_theno(p):
N = tt.get_vector_length(p)
Z= theano.scan(lambda i: p[i] / (1 - tt.sum(p[:i - 1])), sequences=tt.arange(1, N))
fn = theano.function([p, N], results)
Z[0]=p[0]
Z[-1]=Z
return(Z)
第一个显然没有产生预期的结果,而第二个给出:
Traceback (most recent call last): File "/usr/lib/python3/dist-packages/IPython/core/interactiveshell.py", line 2882, in run_code
exec(code_obj, self.user_global_ns, self.user_ns) File "<ipython-input-21-211efc53b449>", line 1, in <module>
p_to_Z_theno(p_ex) File "/usr/local/lib/python3.6/dist-packages/theano/gof/op.py", line 615, in __call__
node = self.make_node(*inputs, **kwargs) File "/usr/local/lib/python3.6/dist-packages/theano/gof/op.py", line 983, in make_node
if not all(inp.type == it for inp, it in zip(inputs, self.itypes)): File "/usr/local/lib/python3.6/dist-packages/theano/gof/op.py", line 983, in <genexpr>
if not all(inp.type == it for inp, it in zip(inputs, self.itypes)): AttributeError: 'numpy.ndarray' object has no attribute 'type'
让我们从向量化运算的角度来考虑这个问题。如果我们使用 numpy 的 cumsum
函数,你的初始方程可以写得非常简单:
def p2Z_numpy(p):
Z = np.r_[p, 1]
Z[1:-1] /= np.cumsum(p[:-1])
return Z
例如:
>>> p2Z_numpy([0.3, 0.4, 0.1, 0.2])
array([0.3 , 1.33333333, 0.14285714, 0.25 , 1. ])
这是一个重要起点的原因是 Theano 允许所有相同类型的操作,但规模要大得多。那么让我们在Theano中做同样的除法、串联和累加:
import theano.tensor as tt
import theano.tensor.extra_ops as te
from theano import function
p = tt.vector()
denom = 1 - te.cumsum(p[:-1])
frac = p[1:] / denom
Z = tt.concatentat([p[0:1], frac, [1]])
p2Z = function([p], Z)
正在测试:
>>> p2Z([0.3, 0.4, 0.1, 0.2])
array([0.3 , 0.57142857, 0.33333333, 1. , 1. ])
虽然我将函数分解为多个步骤,但您实际上可以将它变成一个非常丑陋的单行代码:
p = tt.vector()
Z = tt.concatenate([p[0:1], p[1:] / (1 - te.cumsum(p[:-1])), [1]])
p2Z = function([p], Z)
甚至
p2Z = function([p], tt.concatenate([p[0:1], p[1:] / (1 - te.cumsum(p[:-1])), [1]]))