第一節,TensorFlow基本用法

一 TensorFlow安裝

TensorFlow是谷歌基於DistBelief進行研發的第二代人工智能學習系統,其命名來源於自己的運行原理。Tsnsor(張量)意味着N維數組,Flow(流)意味着基於數據流圖的計算,TensorFlow爲張量從流圖的一端流動到另外一端的計算過程。TensorFlow是將複雜的數據結構傳輸至人工神經網絡中進行分析和處理過程的系統。html

下載和安裝https://blog.csdn.net/darlingwood2013/article/details/60322258python

本文是將tensorflow在原生windows系統上安裝, 採用anocanda的安裝方式, 安裝的是cpu版本(個人顯卡不支持CUDA)git

1.按照官網的指示:
pip install --ignore-installed --upgrade https://storage.googleapis.com/tensorflow/windows/cpu/tensorflow-1.0.0-cp35-cp35m-win_x86_64.whl 
github

 

2 上一步安裝顯示個人平臺不支持,嘗試使用 conda install  tensorflow安裝算法

 

這裏安裝成功了,我是AMD的卡,可能對應的安裝不同!編程

3.確認tensorflow安裝成功: 錯誤嘗試:直接在cmd裏面鍵入python,而後鍵入import tensorflow as tfwindows

 

顯然到此咱們已經安裝成功了,參考tensorflow官方文檔,請上英文官網,中文社區彷佛沒有更新windows上的安裝api

二 基本使用

使用TensorFlow,你必須明白TensorFlow:數組

  • 使用圖(graph)來表示計算任務
  • 在被稱之爲會話(Session)的上下文(context)中執行圖
  • 使用tensor表示數據
  • 經過變量(Variable)維護狀態
  • 使用feed和fetch能夠爲任意的操做(arbitrary operation)賦值或者從中獲取數據

1.綜述

TensorFlow是一個編程系統,使用圖來表示計算任務,圖中的節點被稱做op(operation的縮寫),一個op得到0個或者多個Tensor,執行計算,產生0個或者多個Tensor,每一個tensor是一個類型的多維數組。例如,你能夠將一小組圖像集表示爲一個四維浮點數數字,這四個維度分別是[batch,height,width,channels]。一個TensorFlow圖描述了計算的過程,爲了進行計算,圖必須在會話裏啓動,會話將圖的op分發到諸如CPU或者GPU的設備上,同時提供執行op的方法,這些方法執行後,將產生的tensor返回,在python語言中,返回的tensor是numpy array對象,在C或者C++語言中,返回的tensor是tensorflow:Tensor實例。網絡

2.計算圖

TensorFlow 程序一般被組織成一個構建階段和一個執行階段. 在構建階段, op 的執行步驟被描述成一個圖, 在執行階段, 使用會話執行執行圖中的 op。例如, 一般在構建階段建立一個圖來表示訓練神經網絡, 而後在執行階段反覆執行圖中的訓練 op。

TensorFlow 支持 C, C++, Python 編程語言. 目前, TensorFlow 的 Python 庫更加易用, 它提供了大量的輔助函數來簡化構建圖的工做, 這些函數還沒有被C 和 C++ 庫支持。三種語言的會話庫 (session libraries) 是一致的。

3.構建圖

構建圖的第一步, 是建立源 op (source op), 源 op 不須要任何輸入, 例如 常量 (Constant), 源 op 的輸出被傳遞給其它 op 作運算。

Python 庫中, op 構造器的返回值表明被構造出的 op 的輸出, 這些返回值能夠傳遞給其它 op 構造器做爲輸入。

TensorFlow Python 庫有一個默認圖 (default graph), op 構造器能夠爲其增長節點. 這個默認圖對 許多程序來講已經足夠用了. 閱讀 Graph 類 文檔來了解如何管理多個圖。

4.示例程序

# -*- coding: utf-8 -*-
"""
Created on Sat Mar 31 16:54:02 2018

@author: Administrator
"""

#TensorFlow第一節

import tensorflow as tf

'''
構建階段:op 的執行步驟被描述成一個圖
'''

#建立一個常量op,產生一個1 x 2矩陣,這個op被稱作一個節點,加到默認圖中,構造器的返回值表明常量op的輸出
matrix1 = tf.constant([[3.,3.]])

#建立另外一個常量op。產生一個2 x 1的矩陣
matrix2 = tf.constant([[2.],[2.]])

#建立一個矩陣乘法 matmul op,把matrix1和matrix2做爲輸入
product = tf.matmul(matrix1,matrix2)

'''
默認圖如今有三個節點,兩個常量 constant() op和一個 matmul() op,wile真正進行矩陣相乘運算,並獲得矩陣
乘法的結果,你必須載會話中啓動這個圖
'''
'''
執行階段:使用會話執行執行圖中的 op.
'''
#構造階段完成後,才能啓動圖,啓動圖的第一步是建立一個Session對象,若是無任何建立函數,會話構造器將啓動默認圖
sess = tf.Session()

'''
調用sess的run()方法來執行矩陣乘法op,傳入product做爲該方法的參數,上面提到,product表明矩陣乘法op的輸出
#傳入它是向方法代表,咱們但願取回矩陣乘法op的輸出
整個執行過程是自動化的,會話負責傳遞op所需的所有輸入,op一般是併發執行的
函數調用run(product)觸發了圖中三個op的執行
返回值result是一個numpy.ndarray對象
'''

result = sess.run(product)
print(result)                         #[[ 12.]]

#任務完畢,關閉會話,Session對象在使用完畢後須要關閉以釋放資源,除了顯示調用close()外,也可使用with代碼塊
sess.close()


'''
在實現上, TensorFlow 將圖形定義轉換成分佈式執行的操做, 以充分利用可用的計算資源(如 CPU 或 GPU).
通常你不須要顯式指定使用 CPU 仍是 GPU, TensorFlow 能自動檢測. 若是檢測到 GPU, TensorFlow 會盡
可能地利用找到的第一個 GPU 來執行操做.
若是機器上有超過一個可用的 GPU, 除第一個外的其它 GPU 默認是不參與計算的. 爲了讓 TensorFlow 使用
這些 GPU, 你必須將 op 明確指派給它們執行. with...Device 語句用來指派特定的 CPU 或 GPU 執行操做:
'''

'''
設備用字符串進行標識. 目前支持的設備包括:
    "/cpu:0": 機器的 CPU.
    "/gpu:0": 機器的第一個 GPU, 若是有的話.
    "/gpu:1": 機器的第二個 GPU, 以此類推.
'''
with tf.Session() as sess:
    with tf.device("/cpu:0"):
        print(sess.run(product))             #[[ 12.]]
        
        
'''
交互式使用
文檔中的python實例使用一個會話Seesion來啓動圖,並調用Session.run()方法執行操做
爲了方便使用諸如IPython之類的Python交互環境,可使用InteractiveSession替代Session類,使用Tensor.eval()
和Operation.run()方法來代替Session.run(),這樣能夠避免使用一個變量來持有會話
'''
#進入一個交互式TensorFlow會話
sess = tf.InteractiveSession()

x = tf.Variable([1.0,2.0])
a = tf.constant([3.0,3.0])

#使用初始化器 initinalizer op的run()初始化x
x.initializer.run()

#增長一個減去sub op,從 x 減去 a,運行減去op,輸出結果
sub = tf.subtract(x,a)
print(sub.eval())               #[-2. -1.]

5.Tensor

TensorFlow程序使用tensor數據結構來表明全部的數據,計算圖中,操做間傳遞的數據都是tensor,你能夠把TensorFlow tensor看作一個n維的數組或者列表。一個tensor包含一個靜態類型rank,和一個shape。具體參見Rank, Shape, 和 Type.。

6.變量

Variables  變量維護圖執行過程當中的狀態信息. 下面的例子演示瞭如何使用變量實現一個簡單的計數器.

#建立一個變量,初始化爲標量0
state = tf.Variable(0,name = 'counter')

#建立一個op,其做用是使state增1
one = tf.constant(1)
new_value = tf.add(state,one)

'''
assign()操做室圖所描述的表達式的一部分,正如add()操做同樣,因此在調用run()執行表達式以前,它並不會
正則執行賦值操做

一般會將一個統計模型中的參數表示爲一組變量. 例如, 你能夠將一個神經網絡的權重做爲某個變量存儲在一個 
tensor 中. 在訓練過程當中, 經過重複運行訓練圖, 更新這個 tensor.
'''
update = tf.assign(state,new_value)

#啓動圖後,變量必須先通過'初始化' op 
#首先必須增長一個 '初始化' op 到圖中
init_op = tf.global_variables_initializer()

#啓動圖,運行op
with tf.Session() as sess:
    sess.run(init_op)
    #打印state初始值
    print(sess.run(state))             #0
    #運行op,更新state,並打印
    for _ in range(3):
        sess.run(update)
        print(sess.run(state))      #1  2  3

7.Fetch

爲了取回操做中的輸出內容,能夠在使用Seesion對象的run()調用執行圖時,傳入一些tensor,這些tensor會幫助你取回結果,在以前的例子裏,咱們只取回了單個節點state,可是你能夠取回多個tensor。

in1 = tf.constant(1.0)
in2 = tf.constant(2.0)
in3 = tf.constant(3.0)
intermed = tf.add(in1,in2)
mul = tf.multiply(in2,in3)

#須要獲取多個tensor,在op的一次運行中一塊兒得到。
with tf.Session() as sess:
    re = sess.run([intermed,mul])
    print(re)                 #[3.0, 6.0]

8.Feed

上述示例在計算圖中引入了 tensor, 以常量或變量的形式存儲. TensorFlow 還提供了 feed 機制, 該機制 能夠臨時替代圖中的任意操做中的tensor能夠對圖中任何操做提交補丁, 直接插入一個 tensor。

feed 使用一個 tensor 值臨時替換一個操做的輸出結果. 你能夠提供 feed 數據做爲 run() 調用的參數. feed 只在調用它的方法內有效, 方法結束,feed 就會消失. 最多見的用例是將某些特殊的操做指定爲 "feed" 操做, 標記的方法是使用 tf.placeholder() 爲這些操做建立佔位符。

input1 = tf.placeholder(tf.float32)
input2 = tf.placeholder(tf.float32)
output = tf.multiply(input1, input2)

#使用7替代input1,2替代input2,feed操做至關於設置一個佔位符
with tf.Session() as sess:
  print(sess.run([output], feed_dict={input1:[7.], input2:[2.]}))    #[array([ 14.], dtype=float32)]  

三 案例

在使用TensorFlow的時候,須要注意如下幾點;

1.就是 Session() 和 InteractiveSession() 的用法。後者用 Tensor.eval() 和 Operation.run() 來替代了 Session.run(). 其中更多的是用 Tensor.eval(),全部的表達式均可以看做是 Tensor。

2.另外,tf的表達式中全部的變量或者是常量都應該是 tf 的類型。

3.只要是聲明瞭變量,就得用 sess.run(tf.global_variables_initializer()) 或者 x.initializer.run() 方法來初始化才能用。

例一

 經過切記多元線性迴歸問題熟悉機器學習的一個流程

1.準備數據

2.構造模型(主要是設置目標函數)

3.求解模型(不須要考慮反向傳播問題)

#二元線性迴歸案例
import numpy as np

'''
準備數據,並設置目標函數
'''
#產生測試數據     
def genDate(numPoints,bias,variance):
    '''
    :param numPoints : 實例個數 兩維數據
    :param bias : 偏向值
    :param variance : 變化
    返回獲得的x和y數據
    '''
    #產生numPoints*2的零矩陣
    x = np.zeros(shape = (numPoints,2))
    #產生一維數組
    y = np.zeros(shape = numPoints)
    for i in range(0,numPoints):        
        #x賦值  x = [[1,0],[1,1],[1,2]...]
        x[i][0] = 1
        x[i][1] = i        
        #y賦值  正太分佈      
        y[i] = i + np.random.normal(loc=bias, scale=variance, size=None)   
    return np.array(x,dtype = 'float32').reshape(numPoints,2),np.array(y,dtype = 'float32').reshape(numPoints,1)

#生成數據
x_data,y_data = genDate(100,25,3)


print(x_data.shape,y_data.shape)

#print(training_x,training_y)

import matplotlib.pyplot as plt

fig = plt.figure(1,figsize=(8,4))
#http://blog.csdn.net/eddy_zheng/article/details/48713449
#ax=plt.subplot(111,projection='3d') #建立一個三維的繪圖工程
ax = Axes3D(fig)

#座標軸
ax.set_zlabel('Z') 
ax.set_ylabel('Y')
ax.set_xlabel('X')

ax.scatter(x_data[:,0],x_data[:,1],y_data,c='r',s=1)         #繪製數據點


#構造二元線性迴歸模型
b = tf.Variable(1.0)
w = tf.Variable(tf.ones([2,1])) 
y = tf.matmul(x_data,w) + b

#設置均方差損失函數,在使用梯度下架法的時候學習率不能選擇太多,否則會震盪,不會收斂  
cost = tf.reduce_mean(tf.square(y - y_data))  #擬合效果更好

#選擇絕對損失函數能夠擬合很好
#cost = tf.reduce_mean(tf.abs(y - y_data))

#選擇梯度降低的方法 傳入學習率
optimizer = tf.train.GradientDescentOptimizer(0.0001)   #學習率不能選擇過大,否則會震盪
#迭代的目標,最小化損失函數
train = optimizer.minimize(cost)

'''
#開始求解
'''
#初始化變量:tf的準備工做,主要聲明瞭變量,就必須先初始化纔可使用
init = tf.global_variables_initializer()

#設置tensorflow對GPU使用按需分配
config = tf.ConfigProto()
config.gpu_options.allow_growth = True

#使用會話執行圖
with tf.Session(config=config) as sess:
    sess.run(init)
    #迭代,重複執行最下化損失函數這一步驟
    for step in range(100000):
        sess.run(train)
        if step % 10000 == 0:
            print('迭代次數{0}:W->{1},b->{2},{3}'.format(step,sess.run(w),sess.run(b),sess.run(cost)))
    #保存最後結果
    rw = sess.run(w)
    rb = sess.run(b)
   
     
#計算預測的結果
X, Y = np.meshgrid(x_data[:,0], x_data[:,1])
Z = rb + rw[0]*X + rw[1]*Y 
#繪製數據點
ax.scatter(X,Y,Z,'b--',s=1)       

當選擇絕對損失函數,迭代一萬次以後的擬合曲線圖。

 

當選擇均方差損失函數,迭代一萬次以後的擬合曲線圖。

 

從上面能夠看到,選擇均方差損失函數,擬合效果更好。

注意:在使用梯度降低法求解多元線性迴歸問題時,若是學習率設置太大,則會一直震盪,不會收斂,當我把學習率從0.0001改成0.1時,咱們會發現運行結果以下

  

除此以外,咱們也能夠本身手寫梯度降低法,或者使用sklearn庫求解以上多元線性迴歸問題:

# -*- coding: utf-8 -*-
"""
Created on Thu Dec 21 22:06:59 2017

@author: zy
"""


#線性迴歸的例子 求解線性迴歸方程時採用的是梯度降低法
import numpy as np
from  sklearn import linear_model
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D



#梯度降低法
def gradientDescent(x,y,theta,alpha,m,numIterations):
    '''
    損失函數取:L(θ)=1/2*m*Σ(h(xi) - yi)^2 
    :param x: traning set 訓練集數據
    :param y:輸出
    :param theta:估計的參數向量  依次爲b,w1,w2....
    :param alpha:梯度降低的步長
    :param m:樣本的總個數
    :param numIterations : 迭代次數
    返回最後迭代值 局部極小值 
    '''
    #構建x的增廣矩陣
    temp = np.ones([x.shape[0],x.shape[1]+1])
    temp[:,1:] = x
    x = temp
    xTrans = x.transpose()
    for i in range(0,numIterations):
        #hypothesis = X*θ
        hypothesis = np.dot(x,theta)         
        #偏差 error = hypothesis - y
        loss = hypothesis - y
        #損失函數值L(θ)  
        #cost = np.sum(loss**2) / (2*m)
        #輸出損失值
        #print('Iteration %d | cost: %f'%(i,cost))
        #梯度 x'*E
        gradient = np.dot(xTrans,loss)/m
        #更新參數
        theta = theta - alpha * gradient
    return theta
  
#產生測試數據     
def genDate(numPoints,bias,variance):
    '''
    :param numPoints : 實例個數 兩維數據
    :param bias : 偏向值
    :param variance : 變化
    返回獲得的x和y數據
    '''
    #產生numPoints*2的零矩陣
    x = np.zeros(shape = (numPoints,2))
    #產生一維數組
    y = np.zeros(shape = numPoints)
    for i in range(0,numPoints):        
        #x賦值  x = [[1,0],[1,1],[1,2]...]
        x[i][0] = 1
        x[i][1] = i        
        #y賦值  正太分佈      
        y[i] = i + np.random.normal(loc=bias, scale=variance, size=None)   
    return np.array(x,dtype = 'float32'),np.array(y,dtype = 'float32')

#生成測試數據
x,y = genDate(100,25,3)

#print('x:',x)
#print('y:',y)
#獲取行數和列數
m,n = np.shape(x)
n = n+1
    
numIterations = 100000
alpha = 0.0005
#初始化參數值
theta = np.ones(n)   
#print(theta)     
#使用梯度降低法求解多元線性迴歸
theta = gradientDescent(x,y,theta,alpha,m,numIterations)
print('theta',theta)


#使用自帶多元線性迴歸類庫求解  能夠看出下面求得與梯度降低的結果同樣
#建立實例
regr = linear_model.LinearRegression()
#開始訓練算法
regr.fit(x,y)

#打印權重係數
print('coefficients')
print(regr.coef_)
#打印截距
print('intercept')
print(regr.intercept_)


'''
繪製結果
'''
fig = plt.figure(1,figsize=(8,4))
#http://blog.csdn.net/eddy_zheng/article/details/48713449
#ax=plt.subplot(111,projection='3d') #建立一個三維的繪圖工程
ax = Axes3D(fig)

#座標軸
ax.set_zlabel('Z') 
ax.set_ylabel('Y')
ax.set_xlabel('X')

#將數據點分紅三部分畫,在顏色上有區分度
ax.scatter(x[:30,0],x[:30,1],y[:30],c='y',s=2)         #繪製數據點
ax.scatter(x[30:70,0],x[30:70,1],y[30:70],c='r',s=2)
ax.scatter(x[70:,0],x[70:,1],y[70:],c='g',s=2)

#計算預測的結果
X, Y = np.meshgrid(x[:,0], x[:,1])
#print('X',X)
#print('Y',Y)
Z = theta[0] + theta[1]*X + theta[2]*Y 
#print('Z',Z)
#繪製數據點
ax.scatter(X,Y,Z,'b--',s=1)       

運行結果以下:

 

咱們能夠看到這個程序兩種方法求解獲得的的結果並不同,可是從圖形上看,擬合效果差很少,這主要是由於多元線性迴歸可能會有多個解,而且這多個解均能使均方差最小化。

例二:

使用tf來實現對一組數求和,再計算平均:

'''
使用tf來實現對一組數求和,再計算平均
'''
h_sum = tf.Variable(0.0,dtype=tf.float32)
h_vec = tf.constant([1.0,2.0,3.0,4.0])
#把h_vec每一個元素加到h_sum中,而後再除以10來計算平均值
#待添加的數
h_add = tf.placeholder(tf.float32)
#添加以後的值
h_new = tf.add(h_sum,h_add)
#更新h_new
update = tf.assign(h_sum,h_new)


with tf.Session() as sess:    
    sess.run(tf.global_variables_initializer())
    #輸出原始值
    print('h_sum',sess.run(h_sum))          #h_sum 0.0
    print('h_vec',sess.run(h_vec))          #h_vec [ 1.  2.  3.  4.]
    
    
    #循環添加
    for i in range(4):
        sess.run(update,feed_dict={h_add:sess.run(h_vec[i])})     
        #輸出每次求和以後的值
        print('h_sum',sess.run(h_sum))    #h_sum 1.0
                                          #h_sum 3.0
                                          #h_sum 6.0
                                          #h_sum 10.0
        
    
    #計算平均值
    print('The mean is:',sess.run(h_sum)/4.0)                            #The mean is: 2.5
    #print('The mean is:',sess.run(sess.run(h_sum)/tf.constant(4.0)))     #The mean is: 2.5
    
    

'''    
使用 tf.InteractiveSession() 來 求和 、平均 的操做呢?
'''
sess = tf.InteractiveSession()
#初始化變量
sess.run(tf.global_variables_initializer())
print('h_sum', h_sum.eval())
print("h_vec", h_vec.eval())
print("vec", h_vec[0].eval())


for i in range(4):
    update.eval(feed_dict={h_add: h_vec[i].eval()})
    print('h_sum =', h_sum.eval())
sess.close()

 參考文獻

[1]個人Tensorflow學習之路

[2]http://wiki.jikexueyuan.com/project/tensorflow-zh/get_started/basic_usage.html

[3]項目代碼: https://github.com/yongyehuang/Tensorflow-Tutorial

相關文章
相關標籤/搜索