1. 程式人生 > >Tensorflow基礎知識與神經網路構建--step by step 入門TensorFlow(一)

Tensorflow基礎知識與神經網路構建--step by step 入門TensorFlow(一)

Tensorflow基礎知識與神經網路構建–step by step 入門TensorFlow(一)

標籤: Tensorflow

我們將採用Jupyter notebook互動式程式設計的方式,通過一步步程式碼的講解,學習Tensorflow程式設計。推薦使用Jupyter notebook作為開發環境按照文中的程式碼step by step 的學習。

計算圖

tensorflow程式一般分為2部分:1、構造計算圖 2、執行計算
一般不用指定計算圖,系統會維護一個預設的計算圖
下面關於a、b、c的定義都是構造圖,並且使用的是預設
下面的程式演示的就是圖的構造

import
tensorflow as tf print(a.graph is tf.get_default_graph())
True

可以構造新圖,但圖上的變數不會共享

import tensorflow as tf

g1 = tf.Graph()
with g1.as_default():
    v = tf.get_variable("v",shape=[1], initializer=tf.zeros_initializer())

g2 = tf.Graph()
with g2.as_default():
    v = tf.get_variable("v",shape=[1
], initializer=tf.ones_initializer()) with tf.Session(graph=g1) as sess: sess.run(tf.global_variables_initializer()) with tf.variable_scope("",reuse=True): print(sess.run(tf.get_variable("v"))) with tf.Session(graph=g2) as sess: sess.run(tf.global_variables_initializer()) with
tf.variable_scope("",reuse=True): print(sess.run(tf.get_variable("v")))
[ 0.]
[ 1.]

還可以指定運算裝置

g = tf.Graph()
with g.device('/gpu:0'):
    result = a + b
    with tf.Session() as sess:
        sess.run(tf.global_variables_initializer())
        print(sess.run(result))
[ 5.  7.]

張量

tensorflow中所有資料都有張量表示,張量不儲存資料,儲存的是如何獲得資料
如我們輸出張量時,得到的是一個對張量的引用,如未命名,它會以 運算名_當前第幾次 命名
從輸出可看出張量只儲存名字、維度、型別3個屬性

import tensorflow as tf
a = tf.constant([1.0, 4.0], name='a')
b = tf.constant([3.0, 4.0], name='b')
c = tf.add(a, b, name='c')
d = a+b
print(c)
print(d)
Tensor("c:0", shape=(2,), dtype=float32)
Tensor("add_5:0", shape=(2,), dtype=float32)

若a、b型別不匹配,將會運算錯誤。tensorflow支援14種不同型別,包括tf.float32,tf.float64,tf.int8,tf.int16,tf.int32,tf.int64,tf.uint8,tf.bool,tf.complex64,tf.complex128

%xmode Plain
e = tf.constant([1,2], name='e')
f = a + e
print(f)
Exception reporting mode: Plain



Traceback (most recent call last):


  File "<ipython-input-25-e87db19d2077>", line 3, in <module>
    f = a + e

  ...

ValueError: Tensor conversion requested dtype float32 for Tensor with dtype int32: 'Tensor("e_1:0", shape=(2,), dtype=int32)'

張量有2類用途,一類是對中間結果的引用,一類是對最後結果的引用。之前的a、b都是對中間結果的應用,下面我們將通過對話的介紹,來展示對最後結果的引用

會話

會話(session)擁有和管理tensorflow程式的所有資源,程式通過會話來執行運算。
會話有兩種模式,一種需要明確呼叫生成函式和關閉函式,另一種python的上下文管理器來管理。可以用sess.run()來執行會話,也可以用變數.eval(session=sess)來執行

import tensorflow as tf
a = tf.constant([3.0,4.0], name='a')
b = tf.constant([2.0, 3.0], name='b')
result = a + b 
sess = tf.Session()
print(sess.run(result))
sess.close()
[ 5.  7.]
with tf.Session() as sess:
    print(sess.run(result))
    print(result.eval(session=sess))
[ 5.  7.]
[ 5.  7.]

tensorflow不會生成預設的session,需要自己指定,而指定後該session將會被當作預設的session

sess = tf.Session()
with sess.as_default():
    print(result.eval())
[ 5.  7.]

在python指令碼或Jupyter編輯器上,可以通過tf.InteractiveSession()構造預設會話,以供全域性使用


print(result.eval())
sess.close()
[ 5.  7.]

同時可通過ConfigProto()進行會話的配置,當第一個引數為true時,在缺少GPU資源或有定義在CPU上的計算時會把計算放到CPU上。當第二個引數為true時,將把運算的裝置也記錄日誌,以便除錯。

config = tf.ConfigProto(allow_soft_placement=True, log_device_placement=True)
sess1 = tf.InteractiveSession(config=config)
sess2 = tf.Session(config=config)

tensorflow變數

tensorflow中的變數tf.Variable用以儲存和更新神經網路引數,變數定義的時候需要初始化,一般用下列隨機函式進行初始化

w1 = tf.Variable(tf.random_normal([3,4], mean=0, stddev=0.8))#生成3*4的矩陣,矩陣中的元素未平均值0,標準差0.8的隨機數
w2 = tf.Variable(tf.truncated_normal([3,4], mean=0, stddev=0.8))#隨機分佈,若值超過平均數2個標準差將,重新生成
w3 = tf.Variable(tf.random_uniform([3,4], minval=-0.7, maxval=0.6)) #平均分佈
w4 = tf.Variable(tf.random_gamma([3,4], alpha=0.1, beta=0.4)) # gamma分佈

tensorflow中的變數也有設為常數值,比如b一般初始化為常數

import tensorflow as tf
b1 = tf.Variable(tf.zeros([2,3], tf.int32))
b2 = tf.Variable(tf.ones([3,4],tf.int32))
b3 = tf.Variable(tf.fill([2,3], 8))
b4 = tf.Variable(tf.constant([2,4,6]))

下面是一個簡單的前向神經網路

import tensorflow as tf
w1 = tf.Variable(tf.random_normal([2,3],stddev=0.8, seed=1)) # seed為隨機種子
w2 = tf.Variable(tf.random_normal([3,1],stddev=0.8, seed=1))
b1 = tf.Variable(tf.constant([0.1,0.2,0.3]))
b2 = tf.Variable(tf.constant([0.4]))
x = tf.constant([[0.5, 0.6]]) # 1*2矩陣->列向量
l1=tf.matmul(x, w1)+b1
y = tf.matmul(l1, w2) +b2
init_op = tf.global_variables_initializer() # 初始化所有全域性變數
with tf.Session() as sess:
    sess.run(init_op)
    print(sess.run(y))
[[ 2.33802915]]

神經網路實現

下面我們將實現一個完整的神經網路,具體解析見註釋。

import tensorflow as tf
from numpy.random import RandomState

batch_size = 8

x = tf.placeholder(tf.float32, shape=[None, 2], name='x_input')
y_label = tf.placeholder(tf.float32, shape=[None, 1], name='y_output')
# 定義網路結構
w1 = tf.Variable(tf.random_normal([2,3],stddev=1, seed=1)) # seed為隨機種子
w2 = tf.Variable(tf.random_normal([3,1],stddev=1, seed=1))
b1 = tf.Variable(tf.constant([0.1,0.2,0.3]))
b2 = tf.Variable(tf.constant([0.1]))
l1=tf.matmul(x, w1)+b1
y = tf.matmul(l1, w2) +b2

# 定義損失函式和反向傳播演算法
cross_entroy = -tf.reduce_mean(y_label*tf.log(tf.clip_by_value(y, 1e-10, 1.0)))

train_step = tf.train.AdamOptimizer(0.001).minimize(cross_entroy)

# 通過隨機數生成一個模擬資料集
ram = RandomState(1)
dataset_size = 200 
X = ram.rand(dataset_size, 2) # 隨機生成X
Y = [[int(x1+x2<1)] for (x1, x2) in X] # x1+x2小於1的為正樣本

init_op = tf.global_variables_initializer() # 初始化所有全域性變數
with tf.Session() as sess:
    sess.run(init_op)
    print(sess.run([w1,w2,b1,b2]))
    #print(sess.run(w2))
    steps = 1000
    for i in range(steps):
        start = batch_size * i % dataset_size
        end = min(batch_size + start, dataset_size)
        sess.run(train_step, feed_dict={x:X[start:end], y_label:Y[start:end]})
        if i%100==0:
            entroy = sess.run(cross_entroy, feed_dict={x:X, y_label: Y})
            print("after %d step entroy is %g" % (i, entroy))
    print(sess.run([w1,w2,b1,b2]))

[array([[-0.81131822,  1.48459876,  0.06532937],
       [-2.4427042 ,  0.0992484 ,  0.59122431]], dtype=float32), array([[-0.81131822],
       [ 1.48459876],
       [ 0.06532937]], dtype=float32), array([ 0.1       ,  0.2       ,  0.30000001], dtype=float32), array([ 0.1], dtype=float32)]
after 0 step entroy is 0.0109935
after 100 step entroy is 0.00414283
after 200 step entroy is 0.00180442
after 300 step entroy is 0.00119243
after 400 step entroy is 0.000892674
after 500 step entroy is 0.000589411
after 600 step entroy is 0.000288374
after 700 step entroy is -0
after 800 step entroy is -0
after 900 step entroy is -0
[array([[-0.8940888 ,  1.56725895,  0.17195038],
       [-2.50734305,  0.16374315,  0.68157411]], dtype=float32), array([[-0.88425207],
       [ 1.61494493],
       [ 0.19808137]], dtype=float32), array([-0.02715978,  0.32707116,  0.46436408], dtype=float32), array([ 0.22417794], dtype=float32)]