寫在前面
學(xué)習(xí)建議:以下學(xué)習(xí)過(guò)程中有不理解可以簡(jiǎn)單查找下資料似嗤,但不必糾結(jié)(比如非得深究某一個(gè)函數(shù)等),盡量快速的學(xué)一遍届宠,不求甚解無(wú)妨烁落。因?yàn)橛行┲R(shí)現(xiàn)在陌生,可能學(xué)到后面就發(fā)現(xiàn)之前的問(wèn)題都很自然的理解與會(huì)用了豌注。多實(shí)操代碼伤塌,不能只復(fù)制代碼,或者感覺(jué)懂了就只看轧铁。熟能生巧每聪,我亦無(wú)他,唯手熟爾
計(jì)算模型:計(jì)算圖
計(jì)算圖是TensorFlow中最基本的一個(gè)概念属桦,TensorFlow中所有的計(jì)算都會(huì)被轉(zhuǎn)化為計(jì)算圖上的節(jié)點(diǎn)熊痴。TensorFlow名字中的tensor即張量他爸,可以理解為多維數(shù)組聂宾。tensor表明了TensorFlow的數(shù)據(jù)結(jié)構(gòu),即它處理的都是一個(gè)個(gè)tensor诊笤,flow-流體現(xiàn)的是TensorFlow的計(jì)算模型系谐。張量這定義的模型中流動(dòng),轉(zhuǎn)化成不同的tensor,最終完成任務(wù)纪他。
TensorFlow也是一種懶操作鄙煤,即先畫圖,并沒(méi)有真正的開始計(jì)算茶袒,只是定義了各個(gè)計(jì)算節(jié)點(diǎn)梯刚,定義了計(jì)算邏輯,只有最終調(diào)用run()時(shí)才會(huì)真正開始計(jì)算薪寓,有點(diǎn)像scala的模式亡资。TensorFlow中的每一個(gè)計(jì)算都是計(jì)算圖中的一個(gè)節(jié)點(diǎn),而節(jié)點(diǎn)之間的邊描述了計(jì)算之間的依賴關(guān)系(計(jì)算邏輯)向叉。
具體的計(jì)算網(wǎng)絡(luò)結(jié)構(gòu)锥腻,可以通過(guò)TensorFlow中專門的可視化工具TensorBoard畫出來(lái)。TensorBoard后面會(huì)專門講母谎。
TensorFlow程序分為兩個(gè)階段瘦黑,一是定義計(jì)算(圖的形成),二是執(zhí)行計(jì)算(run)
先看一段代碼奇唤,我盡量把注釋寫滿點(diǎn)幸斥,開始接觸不懂沒(méi)關(guān)系,先跟著套路走咬扇,本地跑下代碼
代碼可以左右滑動(dòng)哦
import tensorflow as tf # 幾乎默認(rèn)這種睡毒,咱也不免俗
a = tf.constant([1.0,2.0]) # 定義一個(gè)變量a,并初始化
b = tf.constant([3.0,4.0]) # 定義一個(gè)變量b 冗栗,并初始化
add = a + b # 定義計(jì)算 (這時(shí)并沒(méi)有真正計(jì)算演顾,只是定義了計(jì)算圖邏輯)
print(add) # 打印出 add 從結(jié)果看(輸出 Tensor("add:0", shape=(2,), dtype=float32)),這也只是一種定義沒(méi)有真正計(jì)算出a+b的結(jié)果隅居,
# 三個(gè)節(jié)點(diǎn) a , b , add 钠至。注意這里沒(méi)有顯式的指定計(jì)算圖(tf.Graph),則會(huì)通過(guò)tf.get_default_graph()獲取默認(rèn)的計(jì)算圖
print(a.graph is tf.get_default_graph())
# 輸出 True
# 補(bǔ)充:初學(xué)時(shí)總是混淆這兩個(gè)函數(shù)tf.multiply()與tf.matmul(),在這里記錄下
# tensoflow 中tf.multiply(a,b)與tf.matmul(c,d)比較
a = tf.constant([1.0,2.0]) # 定義一個(gè)變量a胎源,并初始化
b = tf.constant([3.0,4.0]) # 定義一個(gè)變量b 棉钧,并初始化
c = tf.constant([1, 2, 3, 4, 5, 6], shape=[2, 3])
d = tf.constant([7, 8, 9, 10, 11, 12], shape=[3, 2]) # 定義一個(gè)變量d ,并初始化
product1 = tf.multiply(a,b) # 對(duì)應(yīng)位置相乘
product2 = tf.matmul(c,d) # 矩陣的乘法涕蚤,得到的結(jié)果是一個(gè)矩陣胎许,行乘列作為對(duì)應(yīng)位置的元素
with tf.Session() as sess:
print(sess.run(product1))
print(sess.run(product2))
再來(lái)一段在不同計(jì)算圖中的例子
# 下面定義不同的計(jì)算圖塞赂,并執(zhí)行計(jì)算
import tensorflow as tf
g1 = tf.Graph()
with g1.as_default():
# 在計(jì)算圖g1中定義變量v,并初始化為0
v = tf.get_variable('v', shape=[1], initializer=tf.zeros_initializer())
# # 初始化為常數(shù)
# v = tf.get_variable('v',initializer=tf.constant([2.0,3.1]))
g2 = tf.Graph()
with g2.as_default():
# 在計(jì)算圖g2中定義變量v,并初始化為1
v = tf.get_variable('v', shape=[1], initializer=tf.ones_initializer())
# 在計(jì)算圖g1 中讀取變量 'v'的值方面,輸出
with tf.Session(graph=g1) as sess: # 這種也幾乎是默認(rèn)对室,參考官網(wǎng)
# TensorFlow中蜡秽,run之前需要先初始化
tf.global_variables_initializer().run()
with tf.variable_scope('',reuse=True):
# 根據(jù)計(jì)算圖g1初始化的值輸出
print(sess.run(tf.get_variable('v')))
# tf.get_variable('v') 獲取變量蚤氏,因前面指定了計(jì)算圖g1代赁,這里會(huì)到g1中獲取
# 在計(jì)算圖g2 中讀取變量 'v'的值,輸出
with tf.Session(graph=g2) as sess:
# 初始化
tf.global_variables_initializer().run()
with tf.variable_scope('',reuse=True):
# 根據(jù)計(jì)算圖g2初始化的值輸出兽掰,這行會(huì)輸出[1.]
print(sess.run(tf.get_variable('v')))
數(shù)據(jù)模型:張量
張量是TensorFlow中管理數(shù)據(jù)的形式芭碍。在TensorFlow程序中,所有的數(shù)據(jù)都是通過(guò)張量的形式來(lái)表示孽尽。
零階張量表示標(biāo)量(scalar),也就是一個(gè)數(shù)
一階張量為向量(vector),也就是一個(gè)一維數(shù)組
第n階張量可以理解為一個(gè)n 維數(shù)組
注意在TensorFlow中張量只是對(duì)運(yùn)算結(jié)果的引用窖壕,不是直接采用數(shù)組的形式,在張量中沒(méi)有真正的保存數(shù)字杉女,它保存的是如何得到這些數(shù)字的計(jì)算過(guò)程
import tensorflow as tf # 幾乎默認(rèn)這種
a = tf.constant([1.0,2.0]) # 定義一個(gè)變量a艇拍,并初始化
b = tf.constant([3.0,4.0]) # 定義一個(gè)變量b ,并初始化
add = a + b # 定義計(jì)算 (這時(shí)并沒(méi)有真正計(jì)算宠纯,只是定義了計(jì)算圖邏輯)
print(add)
# 輸出為 Tensor("add:0", shape=(2,), dtype=float32)
看這個(gè)輸出:Tensor("add:0", shape=(2,), dtype=float32)
可以看出 add 在TensorFlow中是一個(gè)Tensor, 在TensorFlow計(jì)算的結(jié)果不是一個(gè)具體的數(shù)字卸夕,而是一個(gè)張量(Tensor)。一個(gè)Tensor中主要保存了3個(gè)屬性: name,shape,type,(名字婆瓜、維度結(jié)構(gòu)快集、類型)
屬性name是一個(gè)張量的唯一標(biāo)識(shí)符(有重復(fù)會(huì)報(bào)異常),也給出了這個(gè)張量是如何計(jì)算出來(lái)的
其中add:0 說(shuō)明了add這個(gè)張量是計(jì)算節(jié)點(diǎn)’add’輸出的第一個(gè)結(jié)果(編號(hào)從0開始)
屬性shape描述了張量的維度信息廉白。shape=(2,)說(shuō)明張量add是一個(gè)一維數(shù)組个初,數(shù)組的長(zhǎng)度是2
屬性type,是指張量的類型猴蹂,每一個(gè)張量會(huì)有一個(gè)唯一的類型院溺。類型不匹配時(shí)會(huì)報(bào)錯(cuò)
# 使用張量記錄中間結(jié)果
a = tf.constant([1.0,2.0],name='a') # 定義一個(gè)變量a,并初始化
b = tf.constant([3.0,4.0],name='b') # 定義一個(gè)變量b 磅轻,并初始化
result = a + b
# 直接計(jì)算向量的和珍逸,這樣可讀性會(huì)比較差
result = tf.constant([1.0,2.0],name='a') + tf.constant([3.0,4.0],name='b')
好吧,今天就先介紹這兩個(gè)概念了聋溜,本來(lái)還準(zhǔn)備了會(huì)話谆膳、變量、常量這些概念撮躁,再寫就篇幅太長(zhǎng)了點(diǎn)漱病。索性就寫短點(diǎn)吧,盡量發(fā)的勤快點(diǎn)把曼,小步快跑~
最后杨帽,有問(wèn)題歡迎溝通交流
關(guān)注-微-公眾號(hào)【學(xué)習(xí)與成長(zhǎng)資源庫(kù)】獲取更多免費(fèi)學(xué)習(xí)資料
參考資料
TensorFlow官網(wǎng)
實(shí)戰(zhàn)Google深度學(xué)習(xí)框架