在 theano 张量上重叠迭代
Overlapping iteration over theano tensor
我正在尝试在 theano 中实现一个扫描循环,给定张量将使用输入的 "moving slice"。它不必实际上是一个移动切片,它可以是另一个表示移动切片的张量的预处理张量。
本质上:
[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16]
|-------| (first iteration)
|-------| (second iteration)
|-------| (third iteration)
...
...
...
|-------| (last iteration)
其中 |-------|
是每次迭代的输入。
我正在尝试找出最有效的方法,可能使用某种形式的引用或操纵步幅,但即使对于纯 numpy,我也没有设法让某些东西起作用。
可以找到我找到的一个可能的解决方案 here,但我不知道如何使用 strides 并且我没有看到将其与 theano 一起使用的方法。
您可以使用 this rolling_window recipe:
import numpy as np
def rolling_window_lastaxis(arr, winshape):
"""
Directly taken from Erik Rigtorp's post to numpy-discussion.
http://www.mail-archive.com/numpy-discussion@scipy.org/msg29450.html
(Erik Rigtorp, 2010-12-31)
See also:
http://mentat.za.net/numpy/numpy_advanced_slides/ (Stéfan van der Walt, 2008-08)
(Warren Weckesser, 2011-01-11)
(Joe Kington, 2011-02-07)
(Joe Kington, 2011-02-09)
"""
if winshape < 1:
raise ValueError("winshape must be at least 1.")
if winshape > arr.shape[-1]:
print(winshape, arr.shape)
raise ValueError("winshape is too long.")
shape = arr.shape[:-1] + (arr.shape[-1] - winshape + 1, winshape)
strides = arr.strides + (arr.strides[-1], )
return np.lib.stride_tricks.as_strided(arr, shape=shape, strides=strides)
x = np.arange(17)
print(rolling_window_lastaxis(x, 5))
打印
[[ 0 1 2 3 4]
[ 1 2 3 4 5]
[ 2 3 4 5 6]
[ 3 4 5 6 7]
[ 4 5 6 7 8]
[ 5 6 7 8 9]
[ 6 7 8 9 10]
[ 7 8 9 10 11]
[ 8 9 10 11 12]
[ 9 10 11 12 13]
[10 11 12 13 14]
[11 12 13 14 15]
[12 13 14 15 16]]
请注意,还有更高级的扩展,例如 Joe Kington's rolling_window which can roll over multi-dimensional windows, and Sebastian Berg's implementation,此外,它还可以逐步跳转。
您可以构建一个向量,其中包含切片在每个时间步的起始索引,然后将该向量作为序列调用 Scan,并将原始向量作为非序列调用。然后在Scan里面,每次迭代都可以得到你想要的slice。
我提供了一个示例,其中我还将切片的大小作为符号输入,以防您想将其从一次调用 Theano 函数更改为下一次调用:
import theano
import theano.tensor as T
# Input variables
x = T.vector("x")
slice_size = T.iscalar("slice_size")
def step(idx, vect, length):
# From the idx of the start of the slice, the vector and the length of
# the slice, obtain the desired slice.
my_slice = vect[idx:idx + length]
# Do something with the slice here. I don't know what you want to do
# to I'll just return the slice itself.
output = my_slice
return output
# Make a vector containing the start idx of every slice
slice_start_indices = T.arange(x.shape[0] - slice_size + 1)
out, updates = theano.scan(fn=step,
sequences=[slice_start_indices],
non_sequences=[x, slice_size])
fct = theano.function([x, slice_size], out)
运行 带有您的参数的函数产生输出:
print fct(range(17), 5)
[[ 0. 1. 2. 3. 4.]
[ 1. 2. 3. 4. 5.]
[ 2. 3. 4. 5. 6.]
[ 3. 4. 5. 6. 7.]
[ 4. 5. 6. 7. 8.]
[ 5. 6. 7. 8. 9.]
[ 6. 7. 8. 9. 10.]
[ 7. 8. 9. 10. 11.]
[ 8. 9. 10. 11. 12.]
[ 9. 10. 11. 12. 13.]
[ 10. 11. 12. 13. 14.]
[ 11. 12. 13. 14. 15.]
[ 12. 13. 14. 15. 16.]]
我正在尝试在 theano 中实现一个扫描循环,给定张量将使用输入的 "moving slice"。它不必实际上是一个移动切片,它可以是另一个表示移动切片的张量的预处理张量。
本质上:
[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16]
|-------| (first iteration)
|-------| (second iteration)
|-------| (third iteration)
...
...
...
|-------| (last iteration)
其中 |-------|
是每次迭代的输入。
我正在尝试找出最有效的方法,可能使用某种形式的引用或操纵步幅,但即使对于纯 numpy,我也没有设法让某些东西起作用。
可以找到我找到的一个可能的解决方案 here,但我不知道如何使用 strides 并且我没有看到将其与 theano 一起使用的方法。
您可以使用 this rolling_window recipe:
import numpy as np
def rolling_window_lastaxis(arr, winshape):
"""
Directly taken from Erik Rigtorp's post to numpy-discussion.
http://www.mail-archive.com/numpy-discussion@scipy.org/msg29450.html
(Erik Rigtorp, 2010-12-31)
See also:
http://mentat.za.net/numpy/numpy_advanced_slides/ (Stéfan van der Walt, 2008-08)
(Warren Weckesser, 2011-01-11)
(Joe Kington, 2011-02-07)
(Joe Kington, 2011-02-09)
"""
if winshape < 1:
raise ValueError("winshape must be at least 1.")
if winshape > arr.shape[-1]:
print(winshape, arr.shape)
raise ValueError("winshape is too long.")
shape = arr.shape[:-1] + (arr.shape[-1] - winshape + 1, winshape)
strides = arr.strides + (arr.strides[-1], )
return np.lib.stride_tricks.as_strided(arr, shape=shape, strides=strides)
x = np.arange(17)
print(rolling_window_lastaxis(x, 5))
打印
[[ 0 1 2 3 4]
[ 1 2 3 4 5]
[ 2 3 4 5 6]
[ 3 4 5 6 7]
[ 4 5 6 7 8]
[ 5 6 7 8 9]
[ 6 7 8 9 10]
[ 7 8 9 10 11]
[ 8 9 10 11 12]
[ 9 10 11 12 13]
[10 11 12 13 14]
[11 12 13 14 15]
[12 13 14 15 16]]
请注意,还有更高级的扩展,例如 Joe Kington's rolling_window which can roll over multi-dimensional windows, and Sebastian Berg's implementation,此外,它还可以逐步跳转。
您可以构建一个向量,其中包含切片在每个时间步的起始索引,然后将该向量作为序列调用 Scan,并将原始向量作为非序列调用。然后在Scan里面,每次迭代都可以得到你想要的slice。
我提供了一个示例,其中我还将切片的大小作为符号输入,以防您想将其从一次调用 Theano 函数更改为下一次调用:
import theano
import theano.tensor as T
# Input variables
x = T.vector("x")
slice_size = T.iscalar("slice_size")
def step(idx, vect, length):
# From the idx of the start of the slice, the vector and the length of
# the slice, obtain the desired slice.
my_slice = vect[idx:idx + length]
# Do something with the slice here. I don't know what you want to do
# to I'll just return the slice itself.
output = my_slice
return output
# Make a vector containing the start idx of every slice
slice_start_indices = T.arange(x.shape[0] - slice_size + 1)
out, updates = theano.scan(fn=step,
sequences=[slice_start_indices],
non_sequences=[x, slice_size])
fct = theano.function([x, slice_size], out)
运行 带有您的参数的函数产生输出:
print fct(range(17), 5)
[[ 0. 1. 2. 3. 4.]
[ 1. 2. 3. 4. 5.]
[ 2. 3. 4. 5. 6.]
[ 3. 4. 5. 6. 7.]
[ 4. 5. 6. 7. 8.]
[ 5. 6. 7. 8. 9.]
[ 6. 7. 8. 9. 10.]
[ 7. 8. 9. 10. 11.]
[ 8. 9. 10. 11. 12.]
[ 9. 10. 11. 12. 13.]
[ 10. 11. 12. 13. 14.]
[ 11. 12. 13. 14. 15.]
[ 12. 13. 14. 15. 16.]]