kei*_*uke 20 python tensorflow
我想知道tf.strided_slice()运营商究竟做了什么.
该文档称,
对于第一个顺序,此操作提取大小结束的切片 - 从从begin指定的位置开始的张量输入开始.切片继续向开始索引添加步幅,直到所有维度都不小于结束.注意,步幅的分量可以是负的,这会导致反向切片.
在样本中,
# 'input' is [[[1, 1, 1], [2, 2, 2]],
# [[3, 3, 3], [4, 4, 4]],
# [[5, 5, 5], [6, 6, 6]]]
tf.slice(input, [1, 0, 0], [2, 1, 3], [1, 1, 1]) ==> [[[3, 3, 3]]]
tf.slice(input, [1, 0, 0], [2, 2, 3], [1, 1, 1]) ==> [[[3, 3, 3],
[4, 4, 4]]]
tf.slice(input, [1, 1, 0], [2, -1, 3], [1, -1, 1]) ==>[[[4, 4, 4],
[3, 3, 3]]]
Run Code Online (Sandbox Code Playgroud)
所以在我对doc的理解中,第一个样本(tf.slice(input, begin=[1, 0, 0], end=[2, 1, 3], strides=[1, 1, 1])),
end - begin = [1, 1, 3].样本结果显示[[[3, 3, 3,]]],该形状[1, 1, 3]似乎没问题.begin = [1, 0, 0].样本结果的第一个元素3是input[1,0,0],似乎没问题.input[begin + strides] = input[2, 1, 1] = 6,但样本显示第二个元素是3.是什么strided_slice()呢?
(注意:样本中的方法名称和最后一个示例不正确.)
Dee*_*rma 20
我用这种方法进行了一些实验,这给了我一些见解,我认为这些见解可能会有所帮助.让我们说我们有一个张量.
a = np.array([[[1, 1.2, 1.3], [2, 2.2, 2.3], [7, 7.2, 7.3]],
[[3, 3.2, 3.3], [4, 4.2, 4.3], [8, 8.2, 8.3]],
[[5, 5.2, 5.3], [6, 6.2, 6.3], [9, 9.2, 9.3]]])
# a.shape = (3, 3, 3)
Run Code Online (Sandbox Code Playgroud)
strided_slice()需要4个必需的参数input_, begin, end, strides,我们将其a作为input_参数.与tf.slice()方法一样,begin参数是从零开始的,其余的是基于形状的. 但是在文档中begin,end两者都是从零开始的.
方法的功能非常简单:
它的工作方式就像在循环上迭代一样,其中begin是元素在张量中的位置,从循环开始的位置和end停止的位置.
tf.strided_slice(a, [0, 0, 0], [3, 3, 3], [1, 1, 1])
# output = the tensor itself
tf.strided_slice(a, [0, 0, 0], [3, 3, 3], [2, 2, 2])
# output = [[[ 1. 1.3]
# [ 7. 7.3]]
# [[ 5. 5.3]
# [ 9. 9.3]]]
Run Code Online (Sandbox Code Playgroud)
strides就像循环迭代的步骤一样,这里[2,2,2]make方法产生从(0,0,0),(0,0,2),(0,2,0),(0,2,2)开始的值, (2,0,0),(2,0,2)......在a张量中.
tf.strided_slice(input3, [1, 1, 0], [2, -1, 3], [1, 1, 1])
Run Code Online (Sandbox Code Playgroud)
会产生类似的输出tf.strided_slice(input3, [1, 1, 0], [2, 2, 3], [1, 1, 1])作为张量a具有shape = (3,3,3).
jag*_*tle 13
真正帮助我理解这一点的概念化是这个函数模拟了numpy数组的索引行为.
如果您熟悉numpy数组,您就会知道可以通过切片进行切片input[start1:end1:step1, start2:end2:step2, ... startN:endN:stepN].基本上,一种非常简洁的编写for循环方式来获取数组的某些元素.
(如果你熟悉python索引,你知道你可以通过获取数组切片input[start:end:step].可能嵌套的Numpy数组使用上面的切片对象元组.)
好吧,strided_slice只是允许你在没有语法糖的情况下进行这种花哨的索引.上面的numpy例子变成了
# input[start1:end1:step1, start2:end2:step2, ... startN:endN:stepN]
tf.strided_slice(input, [start1, start2, ..., startN],
[end1, end2, ..., endN], [step1, step2, ..., stepN])
Run Code Online (Sandbox Code Playgroud)
从某种意义上说,文档有点令人困惑:
a)begin- end严格来说不是返回值的形状:
该文件另有说明,但只有你的步伐全部都是如此.例子:
rank1 = tf.constant(list(range(10)))
# The below op is basically:
# rank1[1:10:2] => [1, 3, 5, 7, 9]
tf.strided_slice(rank1, [1], [10], [2])
# [10,10] grid of the numbers from 0 to 99
rank2 = tf.constant([[i+j*10 for i in range(10)] for j in range(10)])
# The below op is basically:
# rank2[3:7:1, 5:10:2] => numbers 30 - 69, ending in 5, 7, or 9
sliced = tf.strided_slice(rank2, [3, 5], [7, 10], [1, 2])
# The below op is basically:
# rank2[3:7:1] => numbers 30 - 69
sliced = tf.strided_slice(rank2, [3], [7], [1])
Run Code Online (Sandbox Code Playgroud)
b)它声明" begin,end并且strides将是所有长度n,其中n通常不是与"相同的维度input"
这听起来像维度意味着在这里排名 - 但input 确实必须是至少rank-n的张量; 它不能低(见上面的排名-2例).
NB我没有说/没有真正探索过屏蔽功能,但这似乎超出了问题的范围.
mar*_*ars 10
你的论证中的错误是你直接添加列表strides和begin逐个元素的事实.这将使该功能不那么有用.相反,它begin从最后一个维度开始一次增加一个列表的列表.
让我们逐个部分地解决第一个例子.begin = [1, 0, 0]和end = [2, 1, 3].所有的strides都是1.从最后一个维度向后工作.
从元素开始[1,0,0].现在只增加最后一个维度的步幅,给你[1,0,1].继续这样做,直到达到极限.类似的东西[1,0,2],[1,0,3](循环结束).现在,在下一次迭代中,首先将第二个维度递增到最后一个维度并重置最后一个维度[1,1,0].这里倒数第二个维度等于end[1],所以移动到第一个维度(从第三个到最后一个)并重置其余维度,给你[2,0,0].再次,您处于第一个维度的限制,因此退出循环.
以下代码是我上面描述的递归实现,
# Assume global `begin`, `end` and `stride`
def iterate(active, dim):
if dim == len(begin):
# last dimension incremented, work on the new matrix
# Note that `active` and `begin` are lists
new_matrix[active - begin] = old_matrix[active]
else:
for i in range(begin[dim], end[dim], stride[dim]):
new_active = copy(active)
new_active[dim] = i
iterate(new_active, dim + 1)
iterate(begin, 0)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
10656 次 |
| 最近记录: |