1. 程式人生 > >【T-Tensorflow框架學習】Tensorflow “計算圖”入門理解

【T-Tensorflow框架學習】Tensorflow “計算圖”入門理解

#

  1. Tensorflow 不是一個普通的 Python 庫。大多數 Python 庫被編寫為 Python 的自然擴充套件形式。當你匯入一個庫時,你得到的是一組變數、函式和類,它們補充並擴充套件了你的程式碼“工具箱”。使用這些庫時,你知道它們將產生怎樣的結果。
  2. 我認為談及 Tensorflow 時應該拋棄這些認識,這些認知從根本上就不符合 Tensorflow 的理念,無法反映 TF 與其它程式碼互動的方式。pthon 和 Tensorflow 之間的聯絡,可以類比 Java 和 HTML 之間的關係。Java 是一種全功能的程式語言,可以實現各種出色的效果。HTML 是用於表示某種型別的實用計算抽象(這裡指的是可由 Web 瀏覽器呈現的內容)的框架。Java 在互動式網頁中的作用是組裝瀏覽器看到的 HTML 物件,然後在需要時通過將其更新為新的 HTML 來與其互動。
  3. 與 HTML 類似,Tensorflow 是用於表示某種型別的計算抽象(稱為“計算圖”)的框架。我們用 Python 操作 Tensorflow 時,我們用 Python 程式碼做的第一件事是組裝計算圖。之後我們的第二個任務就是與它進行互動(使用 Tensorflow 的“會話”)。
  4. 但重要的是,要記住計算圖不在變數內部,它處在全域性名稱空間內

第一個關鍵抽象:計算圖

'''
Creat by HuangDandan
[email protected]
2018-08-25_26

Tensorflow 不是一個普通的 Python 庫。
Tensorflow 是用於表示某種型別的計算抽象(稱為“計算圖”)的框架。
我們用 Python 操作 Tensorflow 時,我們用 Python 程式碼做的第一件事是組裝計算圖。
之後我們的第二個任務就是與它進行互動(使用 Tensorflow 的“會話”)。
但重要的是,要記住計算圖不在變數內部,它處在全域性名稱空間內。
'''
''' 第一個關鍵抽象:計算圖 0-僅僅匯入 Tensorflow 並不會給我們生成一個有趣的計算圖,而只有一個孤獨的,空白的全域性變數 1-當我們呼叫tf.constant ,得到了一個節點,它包含常量: 當我們列印這個變數時,我們看到它返回一個 tf.Tensor 物件,它是一個指向我們剛建立的節點的指標。 2-每次我們呼叫 tf.constant 的時候,我們都會在圖中建立一個新節點。 即使節點在功能上與現有節點完全相同,即使我們將節點重新分配給同一個變數,甚至我們根本沒有將其分配給變數,結果都一樣。 3-相反,如果建立一個新變數並將其設定為與現有節點相等,則只需將該指標複製到該節點,並且不會向該圖新增任何內容 4-現在我們來看——這才是我們要的真正的計算圖表! 請注意,+ 操作在 Tensorflow 中過載,所以同時新增兩個張量會在圖中增加一個節點,儘管它看起來不像是 Tensorflow 操作。 two_node 指向包含 2 的節點,three_node 指向包含 3 的節點, 而 sum_node 指向包含... + 的節點?什麼情況?它不是應該包含 5 嗎?事實證明,沒有。計算圖只包含計算步驟,不包含結果。至少...... 還沒有! '''
#01 import tensorflow as tf two_node = tf.constant(2) print(two_node) #02 import tensorflow as tf two_node = tf.constant(2) another_two_node = tf.constant(2) two_node = tf.constant(2) print(tf.constant(3)) #03 import tensorflow as tf two_node = tf.constant(2) another_two_node = two_node two_node = None print(two_node) print(another_two_node) #04 import tensorflow as tf two_node = tf.constant(2) three_node = tf.constant(3) sum_node = two_node + three_node print(two_node) print(sum_node)

輸出:

01輸出:
Tensor(“Const:0”, shape=(), dtype=int32)
03輸出:
None
Tensor(“Const:0”, shape=(), dtype=int32)
04輸出:
Tensor(“Const:0”, shape=(), dtype=int32)
Tensor(“add:0”, shape=(), dtype=int32)

第二個關鍵抽象:會話

'''
第二個關鍵抽象:會話
會話的作用是處理記憶體分配和優化,使我們能夠實際執行由圖形指定的計算。
可以將計算圖想象為我們想要執行的計算的“模板”:它列出了所有的步驟。
為了使用這個圖表,我們還需要發起一個會話,它使我們能夠實際地完成任務。
例如,遍歷模板的所有節點來分配一組用於儲存計算輸出的儲存器。
為了使用 Tensorflow 進行各種計算,我們既需要圖也需要會話。

會話包含一個指向全域性圖的指標,該指標通過指向所有節點的指標不斷更新。
這意味著在建立節點之前還是之後建立會話都無所謂。
建立會話物件後,可以使用 sess.run(node) 返回節點的值,並且 Tensorflow 將執行確定該值所需的所有計算。
一般來說,sess.run() 呼叫往往是最大的 TensorFlow 瓶頸之一,所以呼叫它的次數越少越好。
可以的話在一個 sess.run() 呼叫中返回多個專案,而不是進行多個呼叫。

'''
import tensorflow as tf
two_node = tf.constant(2)
three_node = tf.constant(3)
sum_node = two_node + three_node
sess = tf.Session()
print(sess.run(sum_node))

輸出:

5

佔位符和 feed_dict

'''
佔位符和 feed_dict
我們迄今為止所做的計算一直很乏味:沒有機會獲得輸入,所以它們總是輸出相同的東西。
一個實用的應用可能涉及構建這樣一個計算圖:它接受輸入,以某種(一致)方式處理它,並返回一個輸出。
最直接的方法是使用佔位符。佔位符是一種用於接受外部輸入的節點。

佔位符被賦予一個值,為了提供一個值,我們使用 sess.run() 的 feed_dict 屬性。
直接傳遞給run()回報錯,必須通過 feed_dict方法 傳遞給session.run(), Tensor.eval(),或者Operation.run()
注意傳遞給 feed_dict 的數值格式。這些鍵應該是與圖中佔位符節點相對應的變數(如前所述,它實際上意味著指向圖中佔位符節點的指標)。
相應的值是要分配給每個佔位符的資料元素——通常是標量或 Numpy 陣列

'''
import tensorflow as tf
input_placeholder = tf.placeholder(tf.int32)
sess = tf.Session()
print(sess.run(input_placeholder,feed_dict={input_placeholder: 2}))

第三個關鍵抽象:計算路徑

'''
第三個關鍵抽象:計算路徑
當我們在依賴於圖中其他節點的節點上呼叫 sess.run() 時,我們也需要計算這些節點的值。如果這些節點有依賴關係,
那麼我們需要計算這些值(依此類推......),直到達到計算圖的“頂端”,也就是所有的節點都沒有前置節點的情況
根據圖的結構,我們不需要計算所有的節點也可以評估我們想要的節點!

因為我們不需要評估 placeholder_node 來評估 three_node,所以執行 sess.run(three_node) 不會引發異常。
Tensorflow僅通過必需的節點自動路由計算這一事實是它的巨大優勢。
如果計算圖非常大並且有許多不必要的節點,它就能節約大量執行時間。
它允許我們構建大型的“多用途”圖形,這些圖形使用單個共享的核心節點集合根據採取的計算路徑來做不同的任務。
對於幾乎所有應用程式而言,根據所採用的計算路徑考慮 sess.run() 的呼叫方法是很重要的。

'''
import tensorflow as tf
input_placeholder = tf.placeholder(tf.int32)
three_node = tf.constant(3)
sum_node = input_placeholder + three_node
sess = tf.Session()
print(sess.run(three_node))
print(sess.run(input_placeholder,feed_dict={input_placeholder: 2}))
print(sess.run(sum_node))

異常:

InvalidArgumentError (see above for traceback): You must feed a value for placeholder tensor ‘Placeholder’ with dtype int32
[[Node: Placeholder = Placeholder[dtype=DT_INT32, shape=, _device=”/job:localhost/replica:0/task:0/device:C

問題在於計算sum_node結點,必須要通過佔位符,佔位符執行的時候才會賦值,而且需要用feed_dict傳入引數給run()函式,將上面的程式修改如下:

import tensorflow as tf
input_placeholder = tf.placeholder(tf.int32)
three_node = tf.constant(3)
sum_node = input_placeholder + three_node
sess = tf.Session()

print(sess.run(input_placeholder, feed_dict={input_placeholder: 2}))
print(sess.run(three_node))
print(sess.run(sum_node,feed_dict={input_placeholder: 10}))

輸出:

2
3
13

變數和副作用

  • tensorflow中的三個節點:兩種型別的“無祖先”節點:
  • tf.constant(每次執行都一樣)
  • tf.placeholder(每次執行都不一樣)
  • 還有第三種節點:通常情況下具有相同的值,但也可以更新成新值。這個時候就要用到變數
  • 瞭解變數對於使用 Tensorflow 進行深度學習來說至關重要,因為模型的引數就是變數。在訓練期間,通過梯度下降在每個步驟更新引數,但在計算過程中,希望保持引數不變,並將大量不同的測試輸入集傳入到模型中。模型所有的可訓練引數很有可能都是變數。

建立變數

  • tf.get_variable()

tf.get_variable() 的前兩個引數是必需的,其餘可選的。
tf.get_variable(name,shape)。name 是一個唯一標識這個變數物件的字串。它在全域性圖中必須是唯一的,所以要確保不會出現重複的名稱。shape 是一個與張量形狀相對應的整數陣列,它的語法很直觀——每個維度對應一個整數,並按照排列。
例如,一個 3×8 的矩陣可能具有形狀 [3,8]。要建立標量,請使用空列表作為形狀:[]。

#tf.assign()初始化
import tensorflow as tf
count_variable = tf.get_variable('count',[])
sess = tf.Session()
print(sess.run(count_variable))

異常:

tensorflow.python.framework.errors_impl.FailedPreconditionError: Attempting to use uninitialized value count
[[Node: _retval_count_0_0 = _RetvalT=DT_FLOAT, index=0, _device=”/job:localhost/replica:0/task:0/device:CPU:0”]]

  • 問題在於:一個變數節點在首次建立時,它的值基本上就是“null”,任何嘗試對它進行計算的操作都會丟擲這個異常。我們只能先給一個變數賦值後才能用它做計算。有兩種主要方法可以用於給變數賦值:初始化器和
    tf.assign()。

兩種方法建立變數:
- tf.assign()
- 初始化器

#tf.assign()初始化
import tensorflow as tf
count_variable = tf.get_variable('count',[])
zero_node = tf.constant(0.)
assign_node = tf.assign(count_variable,zero_node)
sess = tf.Session()
sess.run(assign_node)
print(sess.run(count_variable))

輸出:

0.0

與我們迄今為止看到的節點相比,tf.assign(target,value) 有一些獨特的屬性:

  • 標識操作。tf.assign(target,value) 不做任何計算,它總是與 value 相等。
  • 副作用。當計算“流經”assign_node 時,就會給圖中的其他節點帶來副作用。在這種情況下,副作用就是用儲存在 zero_node 中的值替換 count_variable 的值。
  • 非依賴邊。即使 count_variable 節點和 assign_node 在圖中是相連的,兩者都不依賴於其他節點。這意味著在計算任一節點時,計算不會通過該邊迴流。不過,assign_node 依賴 zero_node,它需要知道要分配什麼。

“副作用”節點充斥在大部分 Tensorflow 深度學習工作流中。當我們呼叫 sess.run(assign_node) 時,計算路徑將經過 assign_node 和 zero_node。
當計算流經圖中的任何節點時,它還會讓該節點控制的副作用(綠色所示)起效。由於 tf.assign 的特殊副作用,與 count_variable(之前為“null”)關聯的記憶體現在被永久設定為 0。這意味著,當我們下一次呼叫 sess.run(count_variable) 時,不會丟擲任何異常。相反,我們將得到 0。

初始化器初始化變數

#初始化器
import tensorflow as tf
const_init_node = tf.constant_initializer(0.)
count_variable = tf.get_variable('count',[], initializer = const_init_node)
sess = tf.Session()
print(sess.run(count_variable))

異常:

tensorflow.python.framework.errors_impl.FailedPreconditionError: Attempting to use uninitialized value count
[[Node: _retval_count_0_0 = _Retval[T=DT_FLOAT, index=0, _device=”/job:localhost/replica:0/task:0/device:CPU:0”](cou


初始化器不起作用
問題在於會話和圖之間的分隔。我們已經將 get_variable 的 initializer 屬性指向 const_init_node,但它只是在圖中的節點之間添加了一個新的連線。我們還沒有做任何與導致異常有關的事情:與變數節點(儲存在會話中,而不是圖中)相關聯的記憶體仍然為“null”。我們需要通過會話讓 const_init_node 更新變數

#初始化器
import tensorflow as tf
const_init_node = tf.constant_initializer(0.)
count_variable = tf.get_variable('count',[], initializer = const_init_node)
init = tf.global_variables_initializer()
sess = tf.Session()
sess.run(init)
print(sess.run(count_variable))

輸出:

0.0

為此,我們添加了另一個特殊節點:init = tf.global_variables_initializer()。與 tf.assign() 類似,這是一個帶有副作用的節點。與 tf.assign() 不一樣的是,我們實際上並不需要指定它的輸入!tf.global_variables_initializer() 將在其建立時檢視全域性圖,自動將依賴關係新增到圖中的每個 tf.initializer 上。當我們呼叫 sess.run(init) 時,它會告訴每個初始化器完成它們的任務,初始化變數,這樣在呼叫 sess.run(count_variable) 時就不會出錯。

變數共享

你可能會碰到帶有變數共享的 Tensorflow 程式碼,程式碼有它們的作用域,並設定“reuse=True”。強烈建議不要在程式碼中使用變數共享。如果你想在多個地方使用單個變數,只需要使用指向該變數節點的指標,並在需要時使用它。換句話說,對於打算儲存在記憶體中的每個引數,應該只調用一次 tf.get_variable()。

在深度學習中,典型的“內迴圈”訓練如下:
獲取輸入和 true_output
根據輸入和引數計算出一個“猜測”
根據猜測和 true_output 之間的差異計算出一個“損失”
根據損失的梯度更新引數

相關推薦

T-Tensorflow框架學習Tensorflow計算入門理解

# Tensorflow 不是一個普通的 Python 庫。大多數 Python 庫被編寫為 Python 的自然擴充套件形式。當你匯入一個庫時,你得到的是一組變數、函式和類,它們補充並擴充套件了你的程式碼“工具箱”。使用這些庫時,你知道它們將產生怎樣的結果

T-Tensorflow框架學習Tensorflow簡單邏輯迴歸實現

Softmax迴歸介紹 我們知道MNIST的每一張圖片都表示一個數字,從0到9。我們希望得到給定圖片代表每個數字的概率。比如說,我們的模型可能推測一張包含9的圖片代表數字9的概率是80%但是判斷它是8的概率是5%(因為8和9都有上半部分的小圓),然後給予它代表

深度學習基於計算的反向傳播詳解

計算圖 計算圖就是將計算過程用圖形表示出來,這裡所說的圖形是資料結構圖,通過多個節點和邊表示(邊是用來連線節點的)。 下面我們先來通過一個簡單的例子瞭解計算圖的計算過程 假設我們有如下需求: 一個蘋果100塊錢,一個橘子150塊錢 消費稅為10% 買了

我的javaEE學習redis的簡單入門

四月份學習的redis,雖然我個人認為應該分到資料庫裡,但是我學習他的目的,主要是為了JAVAEE開發,所以我繼續歸類到這個類裡。redis的環境我是搭建在自己的特惠買的阿里雲伺服器上,自學的入門教程,如有問題歡迎指出,彼此交流。1.redis在linux上的安裝1.1安裝r

深度學習Tensorflow函式詳解

  目錄 tf.truncated_normal tf.random_normal tf.nn.conv2d tf.nn.max_pool tf.reshape tf.nn.softmax tf.reduce_sum tf.reduce_max,tf.r

深度學習Tensorflow——CNN 卷積神經網路 2

轉自https://morvanzhou.github.io/tutorials/machine-learning/tensorflow/5-05-CNN3/ 目錄 圖片處理  建立卷積層  建立全連線層  選優化方法  完整程式碼

深度學習Tensorflow——CNN 卷積神經網路 1

轉自https://morvanzhou.github.io/tutorials/machine-learning/tensorflow/5-04-CNN2/ 這一次我們會說道 CNN 程式碼中怎麼定義 Convolutional 的層和怎樣進行 pooling. 基於上一次卷積神經網路的介

AI實戰快速掌握TensorFlow(二):計算、會話

在前面的文章中,我們已經完成了AI基礎環境的搭建(見文章:Ubuntu + Anaconda + TensorFlow + GPU + PyCharm搭建AI基礎環境),以及初步瞭解了TensorFlow的特點和基本操作(見文章:快速掌握TensorFlow(一)),接下來將繼續學習掌握Tenso

基於tensorflow學習VGG、Goolenet、Resnet

1.VGG VGG實際上就是Alexnet的“加深版”,它其中比較出名的就是VGG16、VGG19。 它的加深不僅僅是層數的加深,VGG的conv-pool都是五層,但是它的特點在於每一層的conv-pool當中是幾層卷積層串聯之後再連線池化層的。還有它的一些訓練技巧。如圖所示:

基於Tensorflow學習Keras的使用

Keras tutorial - the Happy House Welcome to the first assignment of week 2. In this assignment, you will: Learn to use Keras, a high-level neur

基於tensorflow學習經典卷積神經網路、模型的儲存和讀取

 CNN發展史: 1.經典卷積神經網路 以下僅列出關於CNN的深層次理解: 卷積層 tensorflow中卷積層的建立函式:_conv1 = tf.nn.conv2d(_input_r, tf.Variable(tf.random_normal([3, 3, 1, 6

深度學習TensorFlow版本概述

目錄 AVX指令集 問題 解決 CUDA和cuDNN對照表 windows Linux macOS TensorFlow歷史版本 TensorLayer A

深度學習Tensorflow基礎知識

Tensorflow簡介 \quad\quad在我們使用以統計方法為核心的機器學習方法的時候,重要的是做特徵工程,然後調一些引數,根據一些領域的經驗來不斷提取特徵,特徵的好壞往往決定模型的好壞。 \qu

機器學習Tensorflow:理解和實現快速風格化影象fast neural style

Neural Style開闢了計算機與藝術的道路,可以將照片風格化為名家大師的畫風。然而這種方法即使使用GPU也要花上幾十分鐘。Fast Neural Style則啟用另外一種思路來快速構建風格化影象,在筆記本CPU上十幾秒就可以風格化一張圖片。我們來看看這是什

機器學習TensorFlow 在 iOS 端的用例

機器學習這種計算方式,於上世紀就已經被世人所知,但是受限制於計算機的計算能力和網路速度等原因,沒有得到發展。在摩爾效應下,現在的計算機效能大幅提升,即便是手上的iPhone,都會比當時美國登月所使用的機器要強。於是,在這個背景下,機器學習開始飛速發展,各大公

機器學習Tensorflow:概率程式設計初步印象

  谷歌對Tensorflow的定位是機器學習庫而不僅僅是深度學習庫。隨著基於Tensorflow的深度概率程式設計庫Edward的發展,Tensorflow踏入概率程式設計領域,與stan、pymc展開了競爭,大大擴充套件了應用範圍。現在來看看基於Tensor

機器學習tensorflow: GPU求解帶核函式的SVM二分類支援向量機

SVM本身是一個最優化問題,因此理所當然可以用簡單的最優化方法來求解,比如SGD。2007年pegasos就發表了一篇文章講述簡單的求解SVM最優化的問題。其求解形式簡單,但是並沒有解決核函式計算量巨大的問題。這裡給出了一個tensorflow的帶核函式的SVM

深度學習TensorFlow詳解

TensorFlow 是一個用於人工智慧的開源神器 TensorFlow 是谷歌的第二代機器學習系統,按照谷歌所說,在某些基準測試中,TensorFlow的表現比第一代的DistBelief快了2倍。 TensorFlow 內建深度學習

機器學習TensorFlow (二)優化器Optimizer

昨天整理了一下梯度下降演算法及其優化演算法,傳送門:https://blog.csdn.net/zxfhahaha/article/details/81385130 那麼在實戰中我們如何用到這些優化器,今天就整理一下TensorFlow中關於優化器Optimi

框架學習Nancy 框架

log 打包 ext nancy 站點 sock mage 介紹 有一個 Nancy 框架   1、是一個輕量級用於構建http相應的web框架;   2、與mvc類似,有自己的路由機制;   3、可以處理 DELETE , GET , HEAD , OPTION