Tensorflow 學習筆記(一)TensorFlow入門

一、計算模型----計算圖

1.1 計算圖的概念:TensorFlow就是通過圖的形式繪製出張量節點的計算過程,例如下圖執行了一個a+b的操作。

Tensorflow 學習筆記(一)TensorFlow入門

1.2 計算圖的使用

TensorFlow程序一般分為兩個階段。第一個階段定義計算圖中的所有計算,第二個階段執行計算(執行會話)。

階段一

<code>>>> import tensorflow as tf
>>> a = tf.constant([1,2],name = 'a')
>>> b = tf.constant([2,4],name = 'b')
>>> result = a + b/<code>

階段二

<code>>>> ses = tf.Session()
2018-06-06 20:16:14.770712: I T:\\src\\github\\tensorflow\\tensorflow\\core\\platform\\cpu_feature_guard.cc:140] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2
>>> ses.run(result)
array([3, 6])
>>>/<code>

在TF中,系統會自動維護一個默認的計算圖,通過tf.get_default_graph函數可以獲取當前默認的計算圖。

a.graph可以查看當前張量所屬的計算圖。沒有特殊指定的情況下,一般為默認計算圖。

<code>>>> tf.get_default_graph()
<tensorflow.python.framework.ops.graph>
>>> a.graph
<tensorflow.python.framework.ops.graph>
#(兩個對象的內存地址相同)/<tensorflow.python.framework.ops.graph>/<tensorflow.python.framework.ops.graph>/<code>

TF可以通過tf.Graph函數來生成一個新的計算圖。不同計算圖上的張量不會共享。

Tensorflow 學習筆記(一)TensorFlow入門

<code>import tensorflow as tf

#創建新的計算圖,並且在計算圖的上下文管理器中定義變量v,初始化為0
g1 = tf.Graph()
with g1.as_default():
v = tf.get_variable("v",initializer=tf.zeros_initializer(),shape = [1,])
g2 = tf.Graph()
with g2.as_default():
v = tf.get_variable("v",initializer=tf.ones_initializer(),shape=[1])
#在計算圖g1中讀取變量V的取值
with tf.Session(graph=g1) as sess:
tf.global_variables_initializer().run()
with tf.variable_scope("",reuse=True):
print(sess.run(tf.get_variable("v")))


#在計算圖g2中讀取變量V的取值
with tf.Session(graph=g2) as sess:
tf.global_variables_initializer().run()
with tf.variable_scope("",reuse=True):
print(sess.run(tf.get_variable("v")))/<code>
Tensorflow 學習筆記(一)TensorFlow入門

可以通過tf.Graph.device()指定運行計算的設備,例如GPU。

g = tf.Graph()

with g.device("gpu/0") :

  result = a + b

二、數據模型------張量

2.1張量的概念

從功能的角度,張量可以被理解成一個N維數組。零階張量表示標量,一階張量表示向量,也就是一個以為數組,第n階張量為矩陣,也就是一個n維數組。

但張量在tf中並不是採用數組的形式,只是對TF的運算結果的引用。

Tensorflow 學習筆記(一)TensorFlow入門

<code>import tensorflow as tf

#tf.constant是一個計算,這個計算的結果為一個張量,保存在變量a中
a = tf.constant([1,2],name="a")
b = tf.constant([1,3],name="b")
result = tf.add(a,b,name="add")
print(result)

#輸出結果
Tensor("add:0", shape=(2,), dtype=int32)/<code>
Tensorflow 學習筆記(一)TensorFlow入門

TF的計算結果是一個張量結構。一個張量包含三個屬性:名字name ,維度shape,類型 dtype。

name :張量的唯一標識。命名規範:“node:src_input” 。node 表示圖的節點的名稱,src_input 表示張量來自節點的第幾個輸入(從0開始)

shape:描述張量的維度信息。

dtype;每一個張量有一個唯一的類型。不同類型計算會報錯。

Tensorflow 學習筆記(一)TensorFlow入門

<code>import tensorflow as tf

#tf.constant是一個計算,這個計算的結果為一個張量,保存在變量a中

a = tf.constant([1,2],name="a")
b = tf.constant([1.0,3.0],name="b")
result = tf.add(a,b,name="adds")
print(result)

TypeError: Input 'y' of 'Add' Op has type float32 that does not match type int32 of argument 'x'./<code>
Tensorflow 學習筆記(一)TensorFlow入門

tf有14中數值類型

2.2張量的使用。

張量的使用分為兩大類:

第一類,對中間計算結果的引用。提高代碼的可讀性。

Tensorflow 學習筆記(一)TensorFlow入門

<code>import tensorflow as tf

#使用張量記錄計算結果
a = tf.constant([1.0,2.0],name="a")
b = tf.constant([1.0,3.0],name="b")
result = a+b
#直接計算向量的和,可讀性很差
result = tf.constant([1.0,2.0],name="a") + tf.constant([1.0,2.0],name="b")/<code>
Tensorflow 學習筆記(一)TensorFlow入門

第二類情況,當計算圖構造完成後,張量可以用來獲取計算結果,得到真實的數字。(利用Session)

三、TF運行模型----會話

會話用來執行定義好的計算。會話可以調用和管理TF的所有資源。會話用完後需要關閉釋放資源。

會話的模式有兩種:

第一種、顯式調用會話生成函數和關閉會話函數。

<code>#創建一個會話
sess = tf.Session()
#運行會話得到計算結果
sess.run(result)
#關閉會話,釋放資源
sess.close()/<code>

第二種,運用上下文管理器來使用會話

<code>with tf.Session() as session:
session.run(result)/<code>

設置默認會話

TF可以手動指定默認的會話,當默認的會話被指定之後可以通過tf.Tensor.eval函數來計算一個張量的取值。

以下兩種代碼均可以完成這種功能。

Tensorflow 學習筆記(一)TensorFlow入門

<code>import tensorflow as tf
a = tf.constant([1.0,2.0],name="a")
b = tf.constant([1.0,3.0],name="b")
result = a+b
#方法一
sess = tf.Session()
with sess.as_default():
print(result.eval())
#方法二
sess = tf.Session()
print(sess.run(result))
print(result.eval(session=sess))/<code>
Tensorflow 學習筆記(一)TensorFlow入門

設置交互式默認會話

在交互環境下,通過設置默認會話的方式來獲取張量的取值更方便。TF提供了在交互環境下直接構建默認會話的函數。這個函數就是tf.InteractiveSession。可以省略將會話註冊為默認會話的過程

<code>sess = tf.InteractiveSession()
print(result.eval())
sess.close()/<code>

通過ConfigProto Protocol Buffer 來配置需要生成的會話。

<code>config = tf.ConfigProto(allow_soft_placement = True,log_device_placement = True)
sess1 = tf.Session(config=config)
sess2 = tf.InteractiveSession(config=config)/<code>

ConfigProto的功能:配置類似並行的線程數、GPU分配策略、運行超時時間參數等。

第一個常用的參數allow_soft_placement。為True的時候,在某些條件成立時下,GPU運算可以放在CPU上進行;

第二個常用參數log_device_placement。當為True的時候,日誌會記錄每個節點被安排在哪個節點上以方便調試。生產環境中設為False,以減少日誌量。

四、TF實現神經網絡

4.1神經網絡簡介

使用神經網絡解決分類問題主要有以下四個步驟:

1、提取問題中實體的特徵向量作為神經網絡的輸入。

2.定義神經網絡的結構,並定義如何從神經網絡的輸入得到輸出。這就是神經網絡的前向傳播算法。

3.通過訓練數據來調整神經網絡中參數的取值,這就是訓練神經網絡的過程。主要利用反向傳播算法。

4.使用訓練好的神經網絡來預測未知的數據。

4.2 前向傳播算法簡介以及TF實現前向傳播算法。

Tensorflow 學習筆記(一)TensorFlow入門

將輸入x1和x2組織成一個1X2的矩陣x = [x1,x2],而w1組織成一個2X3的矩陣:

Tensorflow 學習筆記(一)TensorFlow入門

TF實現前向傳播

a = tf.matmul(x,w1)

y = tf.matmul(a,w2)

其中malmul函數實現了矩陣乘法的功能。

4.3 神經網絡參數與TensorFlow變量

weights = tf.Variable(tf.random_normal([2,3],stddev =2))

其中tf.random_normal([2,3],stddev =2會產生一個2X3的矩陣,矩陣中元素均值為0,標準差為2的隨機數。

TF支持的隨機數生成器

Tensorflow 學習筆記(一)TensorFlow入門

TF也支持通過常數來初始化變量。

Tensorflow 學習筆記(一)TensorFlow入門

bias(偏置項)通常會使用常數來初始化。

baises = tf.Variable(tf.zeros([3]))

TF還支持通過其他其他變量的初始值來初始化新的變量

w2 = Variable(weights.initiialized_values() )

w3 = Variable(weights.initiialized_values() *2.0 )

一個前向傳播算法的樣例:

Tensorflow 學習筆記(一)TensorFlow入門

<code>import tensorflow as tf

#聲明w1,w2 兩個變量,通過seed設定隨機種子

w1 = tf.Variable(tf.random_normal([2,3],stddev=1.0 ,seed =1 ))
w2 = tf.Variable(tf.random_normal([3,1],stddev=1.0 ,seed =1 ))
#暫時將輸入的謄正向量定義為一個常量,這裡的X是一個【1,2】矩陣
x = tf.constant([[0.7,0.9]])
#通過前向傳播算法得到輸出y
hd = tf.matmul(x,w1)
y = tf.matmul(hd,w2)

sess = tf.Session()
#初始化w1和w2
sess.run(w1.initializer)
sess.run(w2.initializer)
print(sess.run(y))
sess.close()/<code>
Tensorflow 學習筆記(一)TensorFlow入門

這裡調用變量的初始化過程比較麻煩,TF提供了一種便捷的方法:initialize_all_variables()

init_op = tf.initialize_all_variables()

sess.run(init_op)

4.4 通過TensorFlow訓練神經網絡模型

網絡訓練的流程圖

Tensorflow 學習筆記(一)TensorFlow入門

為了避免大量的存放輸入的常量,可以用placeholder

Tensorflow 學習筆記(一)TensorFlow入門

<code>import tensorflow as tf

#聲明w1,w2 兩個變量,通過seed設定隨機種子

w1 = tf.Variable(tf.random_normal([2,3],stddev=1.0 ,seed =1 ))
w2 = tf.Variable(tf.random_normal([3,1],stddev=1.0 ,seed =1 ))
#用placeholder定義存放輸入數據的地方,維度可以不用定義,但維度確定,可減少出錯率
x = tf.placeholder(tf.float32,shape=(1,2),name= 'input')
#通過前向傳播算法得到輸出y
hd = tf.matmul(x,w1)
y = tf.matmul(hd,w2)


sess = tf.Session()
#初始化w1和w2
init_op = tf.global_variables_initializer()
sess.run(init_op)
#計算過程,需要feed_dict來制定x的值
print(sess.run(y,feed_dict={x:[[0.7,0.9]]}))
sess.close()/<code>
Tensorflow 學習筆記(一)TensorFlow入門

定義反向傳播算法

Tensorflow 學習筆記(一)TensorFlow入門

<code>#定義損失函數來刻畫預測值和真實值的差距
cross_entropy = tf.reduce_mean(y* tf.log(tf.clip_by_value(y,1e-10,1.0)))
#定義學習率
learning_rate = 0.001
#定義反向傳播算法來優化神經網絡中的參數
train_step = tf.train.AdamOptimizer(learning_rate).minimize(cross_entropy)

sess.run(train_step)/<code>
Tensorflow 學習筆記(一)TensorFlow入門

4.5跑一個完整的NN的樣例

在模擬數據集上訓練神經網絡,實現一個二分類的問題

Tensorflow 學習筆記(一)TensorFlow入門

<code>import tensorflow as tf
from numpy import random as rd

#定義batch的大小
batch_size = 8
#定義神經網絡的參數
w1 = tf.Variable(tf.random_normal([2,3],stddev=1,seed=1))
w2 = tf.Variable(tf.random_normal([3,1],stddev=1,seed=1))
# shape的一個維度用None方便使用不大的batch。在訓練時需要把數據分成較少的batch,測試時可以一次性使用全部數據
x = tf.placeholder(tf.float32,shape=(None,2),name='x_input')
y_ = tf.placeholder(tf.float32,shape=(None,1),name='y_input')
#學習率
lr = 0.001
#定義前向傳播過程

a = tf.matmul(x,w1)
y = tf.matmul(a,w2)
# 定義loss和bp
cross_entropy = -tf.reduce_mean(y_* tf.log(tf.clip_by_value(y,1e-10,1)))
train_step = tf.train.AdamOptimizer(lr).minimize(cross_entropy)

#生成模擬數據集
rdm = rd.RandomState(1)
dataset_size = 128
X = rdm.rand(dataset_size,2)
Y = [[int(x1+x2 < 1)] for( x1,x2) in X ]
print(X,Y)
#創建會話來運行TF
with tf.Session() as sess:
init_op = tf.global_variables_initializer()
sess.run(init_op)
print(sess.run(w1))
print(sess.run(w2))
#設定訓練次數
epho = 5000
for i in range(epho):
#每次選取batch個樣本進行訓練
start = i*batch_size % dataset_size
end = min(start + batch_size,dataset_size)
#用樣本訓練神經網絡,更新參數
sess.run(train_step,feed_dict={x:X[start:end],y_:Y[start:end]})
if i %1000 ==0:
#每隔一段時間計算在所有數據上的交叉熵斌輸出
total_cross_entropy = sess.run(cross_entropy,feed_dict={x:X,y_:Y})
print("After %s epho ,total_cross_entropy is %s"%(i,total_cross_entropy))
print(sess.run(w1))
print(sess.run(w2))/<code>


分享到:


相關文章: