Tensorflow入門


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))

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM