2016-12-29 120 views
15

我想知道tf.strided_slice()運營商實際上做了什麼。
doc說,`tf.strided_slice()`做了什麼?

對於一階,該操作提取大小端的片 - 由張量輸入開始開始在由開始所指定的位置。切片繼續向開始索引添加步幅,直到所有維度都不小於結尾。請注意,步幅的分量可能是負值,這會導致反向切片。

,以樣本中,

# '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]]] 

因此,在我的文檔的理解,第一個樣品(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()是什麼?

(注:method names in the samples and the last example is incorrect

+0

它不會將'strides'直接添加到'begin' – martianwars

+0

@martianwars謝謝回覆!那麼,「大步」用於什麼? – keisuke

+0

掛上,寫一個答案:) – martianwars

回答

9

在你的觀點的錯誤是事實,你直接添加列表strides和元素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) 
+2

,但'[1,1,0]'返回的是'4'而不是'3'? – southdoor

+0

嗨。我理解這部分是如何工作的「僅通過其步幅量增加最後維度」,但是我怎麼最終得到[[[3,3,3]]?你能不能更清楚些?謝謝@martianwars –

14

我嘗試了一下這個方法,這給了我一些啓發,我認爲可能是一些使用。假設我們有張量。

 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]]]) 
                shape = (3,3,3) 

strided_slice()需要4個必需的參數input_, begin, end, strides,我們正在給我們的ainput_參數。 與tf.slice()方法一樣,begin參數是基於零的,參數的其餘部分基於形狀。 然而在文檔beginend都是從零開始

方法的功能非常簡單:
它像迭代循環,其中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]]] 

strides就像步驟在其上循環迭代,這裏的[2,2,2]使得方法,以產生值開始在(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]) 

將產生類似於tf.strided_slice(input3, [1, 1, 0], [2, 2, 3], [1, 1, 1])輸出作爲張量a具有shape = (3,3,3)

+0

這真的很有幫助! –

7

真正幫助我理解這一點的概念是這個函數模擬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]) 

該文檔是有點混亂有關此方面的意義是:

一)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]) 

b)該規定, 「beginend,和strides將全部長度n,其中n通常是不相同的維數爲input

這聽起來像維意爲排在這裏 - 但input確實必須是至少rank-n的張量;它不能更低(見上面的rank-2例子)。

N.B.我什麼都沒說/沒有真正探討過掩蓋功能,但這似乎超出了問題的範圍。

1

tf.strided_slice()用於對張量變量進行numpy樣式的切片。 它一般有4個參數:輸入,開始,結束,步幅。切片繼續向開始索引添加步幅,直到所有維度不小於結束。對於前: 讓我們以一個名爲維度的「樣本」的張量常數:[3,2,3]

import tensorflow as tf 

sample = tf.constant(
    [[[11, 12, 13], [21, 22, 23]], 
    [[31, 32, 33], [41, 42, 43]], 
    [[51, 52, 53], [61, 62, 63]]]) 

slice = tf.strided_slice(sample, begin=[0,0,0], end=[3,2,3], strides=[2,2,2]) 

with tf.Session() as sess: 
    print(sess.run(slice)) 

現在,輸出將是:

[[[11 13]] 

[[51 53]]] 

這是因爲跨步從[0,0,0]開始並且前往[2,1,2]丟棄像任何不存在的數據:

[[0,0,0], [0,0,2], [0,2,0], [0,2,2], 
[2,0,0], [2,0,2], [2,2,0], [2,2,2]] 

如果使用[1,1,1]作爲進步那麼它只會打印所有的值。