1. 概述
TensorFlow是Google開發的一款用於深度學習的python庫,TensorFlow用圖來表示計算任務,數據在創建的數據流圖中被處理。節點(operation,op)在圖中表示數學操作,圖中的線表示節點間相互聯系的多維數據數組,即張量(tensor)。訓練模型的過程中 tensor 會在幾點之間傳遞,由此也可以更好的理解TensorFlow這個名字。圖必須在會話里被啟動,會話(Session)將圖的 op 分發到CPU或GPU之類的計算設備上,同時執行op的方法,計算過后將產生的 tensor 返回。

張量(Tensor): * 張量有多種. 零階張量為 純量或標量 (scalar) 也就是一個數值. 比如
[1]* 一階張量為 向量 (vector), 比如 一維的[1, 2, 3]* 二階張量為 矩陣 (matrix), 比如 二維的[[1, 2, 3],[4, 5, 6],[7, 8, 9]]* 以此類推, 還有 三階 三維的 ...
2. 基本用法
環境:python3.7 tensorflow1.15
使用一個簡單擬合二維線性函數的例子來解釋TensorFlow的基本用法,這樣更容易理解和記憶。整體代碼如下:
import tensorflow as tf
import numpy as np
# 針對線性方程 y = 0.1*x + 0.3,生成100個數據
x_data = np.random.rand(100).astype(np.float32)
y_data = x_data*0.1 + 0.3
#構建一個線性模型
Weights = tf.Variable(tf.random_uniform([1],-1.0,1.0))
biases = tf.Variable(tf.zeros([1]))
y = Weights*x_data + biases
# 最小化方差
loss = tf.reduce_mean(tf.square(y-y_data))
optimizer = tf.train.GradientDescentOptimizer(0.5)
train = optimizer.minimize(loss)
# 初始化變量
init = tf.initialize_all_variables()
# 啟動圖
sess = tf.Session()
sess.run(init)
# 擬合線性方程
for step in range(201):
sess.run(train)
if step%20 == 0:
print(step,sess.run(Weights),sess.run(biases))
首先需要構建我們的數據集,生成隨機數據時使用numpy這個庫比較方便,然后就是構建一個線性模型, tf.Variable用來在模型構建過程中定義一個變量,這里定義一個權重 Weights,可以理解為y = a*x + b 中的參數 a,還定義了一個偏量 biases,可以理解為參數 b。定義完變量之后需要計算方差,並且使用優化器 tf.train.GradientDescentOptimizer(0.5)將方差降低至最小,使得預測數據和樣本數據盡量擬合。然后就是初始化變量,通過會話來啟動計算模型,最后訓練201回合,並每20回合輸出一次參數。下面我們從構件圖、會話、變量、傳入值、添加層、構建神經網絡等部分講解TensorFlow的使用。
2.1 構建圖
使用兩個矩陣相乘這個簡單的例子來解釋怎樣構建一個圖:
import tensorflow as tf # 創建一個 常量 op, 返回值 'matrix1' 代表這個 1x2 矩陣. matrix1 = tf.constant([[3., 3.]]) # 創建另外一個 常量 op, 返回值 'matrix2' 代表這個 2x1 矩陣. matrix2 = tf.constant([[2.]
,[2.]]) # 創建一個矩陣乘法 matmul op , 把 'matrix1' 和 'matrix2' 作為輸入. # 返回值 'product' 代表矩陣乘法的結果. product = tf.matmul(matrix1, matrix2)
圖中有三個節點,兩個矩陣常量使用 tf.constant()來定義,最后矩陣相乘得出結果,用tf.matmul(matrix1,matrix2)計算兩個矩陣相乘,並返回計算結果。這里只是定義了矩陣如何計算並沒有執行,計算的過程必須在會話中啟動,這部分在之后的會話中講解。
2.2 會話控制Session
Session是 Tensorflow 為了控制和輸出文件的執行的語句. 運行 session.run() 可以獲得你要得知的運算結果, 或者是你所要運算的部分。之前在矩陣相乘的例子中已經構建好了變量和常量,但是定義的計算方法並不是實際的運算過程,真正的運算過程要是用Session來激活product,並得到計算結果,使用會話控制Session的方法有兩種:
# method 1
sess = tf.Session()
result = sess.run(product)
print(result)
sess.close()
# [[12]]
# method 2
with tf.Session() as sess:
result2 = sess.run(product)
print(result2)
# [[12]]
2.3 變量Variable
和python的變量不同,TensorFlow中變量需要進行提前定義才能使用。
定義語法:state = tf.Variable()
變量定義過后還需要對其進行初始化,這一步尤為關鍵,很容易被忽略。
init = tf.initialize_all_variables()
到這一步變量還是沒有被激活,需要使用sess.run()來激活變量,TensorFlow中變量的使用必須要有定義、初始化、激活三個步驟之后才會在計算中被使用。下面是一個簡單的計數器:
# -創建一個變量, 初始化為標量 0. 初始化定義初值
state = tf.Variable(0, name="counter")
# 創建一個 op, 其作用是使 state 增加 1
one = tf.constant(1)
new_value = tf.add(state, one)
update = tf.assign(state, new_value)
# 啟動圖后, 變量必須先經過`初始化` (init) op 初始化,
# 才真正通過Tensorflow的initialize_all_variables對這些變量賦初值
init_op = tf.initialize_all_variables()
# 啟動默認圖, 運行 op
with tf.Session() as sess:
# 運行 'init' op
sess.run(init_op)
# 打印 'state' 的初始值
# 取回操作的輸出內容, 可以在使用 Session 對象的 run() 調用 執行圖時,
# 傳入一些 tensor, 這些 tensor 會幫助你取回結果.
# 此處只取回了單個節點 state,
# 也可以在運行一次 op 時一起取回多個 tensor:
# result = sess.run([mul, intermed])
print sess.run(state)
# 運行 op, 更新 'state', 並打印 'state'
for _ in range(3):
sess.run(update)
print sess.run(state)
# 輸出:
# 0
# 1
# 2
# 3
2.4傳入值 placeholder
placeholder是TensorFlow中的占位符,暫時存儲變量,TensorFlow如果想要從外部傳入data,那就需要使用 tf.placeholder(),然后以這種形式傳輸數據 sess.run(***,feed_dict={inputt:***}),下面代碼是一個簡單例子,傳值的工作交給了sess.run(),需要傳入的值放在了feed_dict={},並一一對應的每一個input。placeholder和feed_dict={}是綁定在一起出現的。
import tensorflow as tf
#在 Tensorflow 中需要定義 placeholder 的 type ,一般為 float32 形式
input1 = tf.placeholder(tf.float32)
input2 = tf.placeholder(tf.float32)
# mul = multiply 是將input1和input2 做乘法運算,並輸出為 output
ouput = tf.multiply(input1, input2)
with tf.Session() as sess:
print(sess.run(ouput, feed_dict={input1: [7.], input2: [2.]}))
# [ 14.]
2.5 添加層 def add_layer()
最基本的神經網絡結構也包含輸入層、隱藏層、輸出層,在構建神經網絡過程中我們需要構建一層又一層的神經元,神經層中常見的參數包含weights、biases和激勵函數。
import tensorflow as tf
def add_layer(inputs,in_size,out_size,activation_function=None):
Weights = tf.Variable(tf.random_normal([in_size,out_size]))
biases = tf.Variable(tf.zeros([1,out_size]) + 0.1)
Wx_plus_b = tf.matmul(inputs,Weights) + biases
if activation_function is None:
outputs = Wx_plus_b
else:
outputs = activation_function(Wx_plus_b)
return outputs
上面代碼是一個添加神經層的函數,參數包括該層輸入數據:inputs,輸入數據的大小:in_size、輸出數據的大小:out_size、激活函數:activation_function,默認的激活函數為None。
首先是定義參數weights和biases。因為在生成初始參數時,隨機變量(normal distribution)會比全部為0要好很多,所以我們這里的weights為一個in_size行, out_size列的隨機變量矩陣。
Weights = tf.Variable(tf.random_normal([in_size, out_size]))
在機器學習中,biases的推薦值不為0,所以我們這里是在0向量的基礎上又加了0.1。
biases = tf.Variable(tf.zeros([1, out_size]) + 0.1)
下面,我們定義Wx_plus_b, 即神經網絡未激活的值。其中,tf.matmul()是矩陣的乘法。
Wx_plus_b = tf.matmul(inputs, Weights) + biases
當activation_function——激勵函數為None時,輸出就是當前的預測值——Wx_plus_b,不為None時,就把Wx_plus_b傳到activation_function()函數中得到輸出。
if activation_function is None:
outputs = Wx_plus_b
else:
outputs = activation_function(Wx_plus_b)
最后,返回輸出,添加一個神經層的函數——def add_layer()就定義好了。
return outputs
2.6 構建神經網絡
在之前的基礎上我們可以知道構建魔性的過程可以概括為:建圖——啟動圖——運行取值。
1、建圖
構建神經層想必是建圖的核心部分,之前我們已經構造好了add_layer()函數,通過輸入不同的參數我們可以構建不同的神經層。
def add_layer(inputs,in_size,out_size,activation_function=None):
Weights = tf.Variable(tf.random_normal([in_size,out_size]))
biases = tf.Variable(tf.zeros([1,out_size]) + 0.1)
Wx_plus_b = tf.matmul(inputs,Weights) + biases
if activation_function is None:
outputs = Wx_plus_b
else:
outputs = activation_function(Wx_plus_b)
return outputs
2、導入數據
這里構建一個方程 y = x^2 -0.5有噪聲的數據,x_data 和 y_data,noise表示噪聲,均值為o,方差為0.05
x_data = np.linspace(-1,1,300, dtype=np.float32)[:, np.newaxis] noise = np.random.normal(0, 0.05, x_data.shape).astype(np.float32) y_data = np.square(x_data) - 0.5 + noise
利用占位符定義我們所需的神經網絡的輸入。 tf.placeholder()就是代表占位符,這里的None代表無論輸入有多少都可以,因為輸入只有一個特征,所以這里是1。
xs = tf.placeholder(tf.float32, [None, 1]) ys = tf.placeholder(tf.float32, [None, 1])
3、搭建網絡
神經網絡的結構通常包含輸入層、隱藏層和輸出層。由於我們的輸入數據比較簡單,所以我們的輸入層就是我們的導入數據部分;隱藏層我們可以根據具體情況自定義結構,這里我們設置神經元個數為10個,該層輸入大小即輸入層輸出的大小為1,有十個神經元,所以輸出數據大小為10。激活函數為None時使用的是TensorFlow自帶的激活函數 tf.nn.relu 。
l1 = add_layer(xs, 1, 10, activation_function=tf.nn.relu)
輸出層的輸入就是隱藏層的輸出,所以輸入大小為10,輸出大小為1,輸出層的輸出數據即為模型的預測值。
prediction = add_layer(l1, 10, 1, activation_function=None)
接下來求loss值,計算預測值 prediction 和真實值的誤差,對二者差的平方求和再取平均。
loss = tf.reduce_mean(tf.reduce_sum(tf.square(ys - prediction),reduction_indices=[1]))
然后就是使用優化函數讓機器學習模型在訓練過程中提升准確率,最基本的優化函數是 tf.train.GradientDescentOptimizer() 中的值通常都小於1,這里取的是 0.1,代表學習率為0.1,以0.1的效率最小化誤差loss。
train_step = tf.train.GradientDescentOptimizer(0.1).minimize(loss)
設置完變量,神經層,誤差計算,訓練優化函數之后剩下的就是變量的初始化,定義session,對session進行初始化,最后運行session。
init = tf.global_variables_initializer() # 初始化所有變量 sess = tf.Session() sess.run(init)
4、訓練模型
讓之前構建好的神經網絡模型訓練1000回合,機器學習的內容已經設置好是train_step,用Session來run每一次的train,當運算要用到placeholder時,就需要feed_dict這個字典來指定輸入。
for i in range(1000):
# training
sess.run(train_step, feed_dict={xs: x_data, ys: y_data})
if i % 50 == 0:
# to see the step improvement
print(sess.run(loss, feed_dict={xs: x_data, ys: y_data}))
5、(數據可視化)
利用matplotlib.pyplot庫將原本數據和訓練好的數據可視化。
# 可視化數據
fig = plt.figure()
ax = fig.add_subplot(1,1,1)
ax.scatter(x_data,y_data)
# 訓練模型
for i in range(1000):
sess.run(train_step,feed_dict={xs:x_data,ys:y_data})
if i%50 == 0:
print(sess.run(loss,feed_dict={xs:x_data,ys:y_data}))
prediction_value = sess.run(prediction,feed_dict={xs:x_data})
lines = ax.plot(x_data,prediction_value,'r-',lw=5)
plt.show()


完整代碼如下:
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
def add_layer(inputs,in_size,out_size,activation_function=None):
Weights = tf.Variable(tf.random_normal([in_size,out_size]),name='w')
biases = tf.Variable(tf.zeros([1,out_size]) + 0.1,name='b')
Wx_plus_b = tf.matmul(inputs,Weights) + biases
if activation_function is None:
outputs = Wx_plus_b
else:
outputs = activation_function(Wx_plus_b)
return outputs
x_data = np.linspace(-1,1,300)[:,np.newaxis]
noise = np.random.normal(0,0.05,x_data.shape)
y_data = np.square(x_data) - 0.5 + noise
xs = tf.placeholder(tf.float32,[None,1],name='x_input')
ys = tf.placeholder(tf.float32,[None,1],name='y_input')
# 添加隱藏層
L1 = add_layer(xs,1,10,activation_function=tf.nn.relu)
# 添加輸出層
prediction = add_layer(L1,10,1,activation_function=None)
loss = tf.reduce_mean(tf.reduce_sum(tf.square(ys - prediction),reduction_indices=[1]))
train_step = tf.train.GradientDescentOptimizer(0.1).minimize(loss)
init = tf.initialize_all_variables()
sess = tf.Session()
writer = tf.summary.FileWriter('./logs',sess.graph)
sess.run(init)
# 可視化數據
fig = plt.figure()
ax = fig.add_subplot(1,1,1)
ax.scatter(x_data,y_data)
# 訓練模型
for i in range(1000):
sess.run(train_step,feed_dict={xs:x_data,ys:y_data})
if i%50 == 0:
print(sess.run(loss,feed_dict={xs:x_data,ys:y_data}))
prediction_value = sess.run(prediction,feed_dict={xs:x_data})
lines = ax.plot(x_data,prediction_value,'r-',lw=5)
plt.show()
3.classification
任務:使用神經網絡模型將一組代表0-9數字的圖片按照數字進行分類,使用的數據為MNIST庫,如果導入失敗可以下載該數據,將tutorials文件夾放入python安裝目錄的 \python3.7\Lib\site-packages\tensorflow_core\examples\文件夾中,tensorflow官方github中不知道為什么已經沒有這個文件夾了,所以我把這個文件夾的微雲鏈接放在這里tutorials。分類模型的完整代碼如下:

import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
# 讀取樣本數據
mnist = input_data.read_data_sets('MNIST_data',one_hot=True)
# 定義添加層函數
def add_layer(inputs,in_size,out_size,activation_function=None):
Weights = tf.Variable(tf.random_normal([in_size,out_size]))
biases = tf.Variable(tf.zeros([1,out_size]) + 0.1)
Wx_plus_b = tf.matmul(inputs,Weights) + biases
if activation_function is None:
outputs = Wx_plus_b
else:
outputs = activation_function(Wx_plus_b)
return outputs
def compute_accuracy(v_xs,v_ys):
global prediction
y_pre = sess.run(prediction,feed_dict={xs:v_xs})
correct_prediction = tf.equal(tf.argmax(y_pre,1),tf.argmax(v_ys,1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction,tf.float32))
result = sess.run(accuracy,feed_dict={xs:v_xs,ys:v_ys})
return result
# 784 = 28*28個像素點
xs = tf.placeholder(tf.float32,[None,784])
# 10種數字類型
ys = tf.placeholder(tf.float32,[None,10])
# 添加輸出層
prediction = add_layer(xs,784,10,activation_function=tf.nn.softmax)
# 計算loss
cross_entropy = tf.reduce_mean(-tf.reduce_sum(ys*tf.log(prediction),reduction_indices=[1]))
train_step = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy)
sess = tf.Session()
sess.run(tf.initialize_all_variables())
print('每一輪的准確率如下:')
for i in range(1000):
batch_xs,batch_ys = mnist.train.next_batch(100)
sess.run(train_step,feed_dict={xs:batch_xs,ys:batch_ys})
if i % 50 == 0:
print(compute_accuracy(mnist.test.images,mnist.test.labels))

