簡體   English   中英

理解tensorflow切片操作

[英]Understand tensorflow slice operation

我對以下代碼感到困惑:

import tensorflow as tf
import numpy as np
from tensorflow.python.framework import ops
from tensorflow.python.ops import array_ops
from tensorflow.python.ops import control_flow_ops
from tensorflow.python.ops import math_ops
from tensorflow.python.framework import dtypes

'''
Randomly crop a tensor, then return the crop position
'''
def random_crop(value, size, seed=None, name=None):
    with ops.name_scope(name, "random_crop", [value, size]) as name:
        value = ops.convert_to_tensor(value, name="value")
        size = ops.convert_to_tensor(size, dtype=dtypes.int32, name="size")
        shape = array_ops.shape(value)
        check = control_flow_ops.Assert(
                math_ops.reduce_all(shape >= size),
                ["Need value.shape >= size, got ", shape, size],
                summarize=1000)
        shape = control_flow_ops.with_dependencies([check], shape)
        limit = shape - size + 1
        begin = tf.random_uniform(
                array_ops.shape(shape),
                dtype=size.dtype,
                maxval=size.dtype.max,
                seed=seed) % limit
        return tf.slice(value, begin=begin, size=size, name=name), begin

sess = tf.InteractiveSession()
size = [10]
a = tf.constant(np.arange(0, 100, 1))

print (a.eval())

a_crop, begin = random_crop(a, size = size, seed = 0)
print ("offset: {}".format(begin.eval()))
print ("a_crop: {}".format(a_crop.eval()))

a_slice = tf.slice(a, begin=begin, size=size)
print ("a_slice: {}".format(a_slice.eval()))

assert (tf.reduce_all(tf.equal(a_crop, a_slice)).eval() == True)
sess.close()

輸出:

[ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
 96 97 98 99]
offset: [46]
a_crop: [89 90 91 92 93 94 95 96 97 98]
a_slice: [27 28 29 30 31 32 33 34 35 36]

有兩個tf.slice選項:

(1). 在函數random_crop中調用,如tf.slice(value, begin=begin, size=size, name=name)

(2). 稱為a_slice = tf.slice(a, begin=begin, size=size)

這兩個slice操作的參數( valuesbeginsize )是相同的。

但是,為什么打印的值a_cropa_slice不同,而tf.reduce_all(tf.equal(a_crop, a_slice)).eval()是 True?

謝謝

EDIT1 謝謝@xdurch0,我現在明白第一個問題了。 Tensorflow random_uniform看起來像一個隨機生成器。

import tensorflow as tf
import numpy as np

sess = tf.InteractiveSession()
size = [10]
np_begin = np.random.randint(0, 50, size=1)
tf_begin = tf.random_uniform(shape = [1], minval=0, maxval=50, dtype=tf.int32, seed = 0)
a = tf.constant(np.arange(0, 100, 1))

a_slice = tf.slice(a, np_begin, size = size)
print ("a_slice: {}".format(a_slice.eval()))
a_slice = tf.slice(a, np_begin, size = size)
print ("a_slice: {}".format(a_slice.eval()))

a_slice = tf.slice(a, tf_begin, size = size)
print ("a_slice: {}".format(a_slice.eval()))
a_slice = tf.slice(a, tf_begin, size = size)
print ("a_slice: {}".format(a_slice.eval()))

sess.close()

輸出

a_slice: [42 43 44 45 46 47 48 49 50 51]
a_slice: [42 43 44 45 46 47 48 49 50 51]
a_slice: [41 42 43 44 45 46 47 48 49 50]
a_slice: [29 30 31 32 33 34 35 36 37 38]

這里令人困惑的是tf.random_uniform (就像 TensorFlow 中的每個隨機操作)在每次評估調用(每次調用.eval()或通常每次調用tf.Session.run )都會產生一個新的、不同的值。 因此,如果你評估a_crop你會得到一件事,如果你然后評估a_slice你會得到不同的東西,但是如果你評估tf.reduce_all(tf.equal(a_crop, a_slice))你會得到True ,因為所有都是在一個單一的計算評估步驟,所以只產生一個隨機值,它決定了a_cropa_slice的值。 另一個例子是,如果你運行tf.stack([a_crop, a_slice]).eval()你會得到一個行相等的張量; 同樣,只產生了一個隨機值。 更一般地,如果您使用多個張量調用tf.Session.run進行評估,則該調用中的所有計算都將使用相同的隨機值。

附帶說明一下,如果您在計算中確實需要一個隨機值並希望為以后的計算維護,最簡單的方法是使用tf.Session.run檢索 if 以及任何其他需要的計算,以提供稍后通過feed_dict 或者你可以有一個tf.Variable並將隨機值存儲在那里。 更高級的可能性是使用partial_run ,這是一種實驗性 API,允許您評估計算圖的一部分並在以后繼續評估它,同時保持相同的狀態(即相同的隨機值等)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM