1. 程式人生 > >Tensorflow 03_: tensorflow中tensor的生命週期

Tensorflow 03_: tensorflow中tensor的生命週期

前言

在學習上篇博文《Tensorflow 03: 前向神經網路-MIST》程式碼的過程中,發現一個比較有意思,但同時令人迷惑的一個問題,即tensorflow所定義在計算圖中的各種各樣的 tensor 的生命週期到底是怎樣的???大家都知道:變數的 “作用域” 和 “生命週期” 號稱C語言的倚天劍和屠龍刀,威力巨大。但在tensorflow中,tensor的所表現出來的生命週期現象與C語言中的不太一樣。

自已產生上述顧慮的一個原因是:在用tensorflow構造自已的深度神經網路模型時,大家都習慣於將 “構圖” 和 “圖的訓練” 分開,即將這兩部分分別寫到各自的函式中,如build_graph_model()和train_model()。那麼這個時候就會產生一個問題,因為構圖是在函式build_graph_model()中完成的,那麼其中用到的引數變數如W,bias等要不要作為函式的返回值返回呢???如果不返回,因為這些W,bias等tensor 變數是一個區域性變數,函式build_graph_model()呼叫完成後,是不是就死掉了,被程式回收了,那構圖豈不是失敗???

案例1

比如在上篇博文中有如下一段程式碼:

# 在 Tensorflow 預設圖中建立模型
    with tf.Graph().as_default():
        images_placeholder, labels_placeholder = placeholder_inputs(FLAGS.batch_size)

        # 構建前向計算的圖模型.
        logits = mnist.inference(images_placeholder, FLAGS.hidden1, FLAGS.hidden2)

其中,mnist.inference()是模組檔案mnist.py中的一個函式,如下所示:

def inference(images, hidden1_units, hidden2_units):
    """
    構建網路前向計算圖
    引數:
        images: 輸入的 images, placeholder.
        hidden1_units: 隱層1神經元大小.
        hidden2_units: 隱層2神經元大小.

    返回值:
        softmax_linear: logits.
    """
    # 隱層1
    # tf.name_scope()函式返回一個context manager
    with
tf.name_scope('hidden1'): weights = tf.Variable(tf.truncated_normal([IMAGE_PIXELS, hidden1_units], stddev=1.0 / math.sqrt(float(IMAGE_PIXELS))), name='weights') biases = tf.Variable(tf.zeros([hidden1_units]), name='biases') hidden1 = tf.nn.relu(tf.matmul(images, weights) + biases) # 隱層2 with tf.name_scope('hidden2'): weights = tf.Variable(tf.truncated_normal([hidden1_units, hidden2_units], stddev=1.0 / math.sqrt(float(hidden1_units))), name='weights') biases = tf.Variable(tf.zeros([hidden2_units]), name='biases') hidden2 = tf.nn.relu(tf.matmul(hidden1, weights) + biases) # 輸出 with tf.name_scope('softmax_linear'): weights = tf.Variable(tf.truncated_normal([hidden2_units, NUM_CLASSES], stddev=1.0 / math.sqrt(float(hidden2_units))), name='weights') biases = tf.Variable(tf.zeros([NUM_CLASSES]), name='biases') logits = tf.matmul(hidden2, weights) + biases return logits

那麼按照C語言中變數的生命週期原理,當程式執行完logits = mnist.inference(images_placeholder, FLAGS.hidden1, FLAGS.hidden2)這行程式碼後,函式inference中包含的區域性變數如weights,biases,hidden1,hidden2等等都應該消失死掉了,但從後面程式的執行結果來看,可以看到tensorflow還是能夠構造出完整的前向神經網路模型(該模型必須包含weights,biases,hidden1,hidden2等這些區域性變數),說明這些區域性變數可能沒有“死掉”。那麼可能的原因解釋是:
(1)這些區域性變數weights,biases,hidden1,hidden2等沒有死掉,他們始終作為tensorflow計算圖的的一部分存在。
(2)返回值logits可能包含這些區域性變數的所有資訊。雖然函式inference()執行完了,但這些區域性變數的資訊被儲存在了返回值logits中,從而帶出來了。

期待看到這篇部落格的大神更好的解釋!!!!