張量
TensorFlow 中的tensor就張量葫松,可見張量在tensorflow中低位非同一般压储。在tensorflow中所有的數(shù)據(jù)都是通過張量的形式表示的急黎。張量可以簡單的理解為多維數(shù)組,其中零階張量表示標(biāo)量魄梯,就是一個數(shù)梅誓。第n階張量表示n維數(shù)組恰梢。但張量在tensorflow中的實現(xiàn)并不是直接采用數(shù)組的形式,它只是對tensorflow中運算結(jié)果的引用梗掰。在張量中并沒有真正的保存數(shù)字嵌言,它只是保存如何得到這些數(shù)字的計算過程。比如代碼的運行結(jié)果并不會得到加法的結(jié)果及穗,而只是保存如何得到結(jié)果的過程的引用
張量使用
import tensorflow as tf
a = tf.constant([1, 2, 3], name="a")
b = tf.constant([2, 3, 4], name="b")
result = a + b
print(result)
計算圖
Tensorflow中flow就簡單可以理解為就是計算圖摧茴。它表達(dá)了張量之間通過計算相互轉(zhuǎn)化的過程。Tensorflow程序一般分為兩個階段埂陆。在第一個階段
定義計算圖中所有的計算苛白。第二階段執(zhí)行計算娃豹。在tensorflow中系統(tǒng)會自動維護(hù)一個默認(rèn)的計算圖,通過tf.get_default_graph函數(shù)可以獲得當(dāng)前
默認(rèn)的計算圖购裙。以下代碼示意了如何獲得默認(rèn)計算圖懂版。不同計算圖上的張量、運算不會共享
import tensorflow as tf
# 不同計算圖上的張量躏率、運算不會共享
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("v in g1: %s" % str(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("v in g2: %s" % str(sess.run(tf.get_variable("v"))))
會話
上例中并沒有輸出result的值躯畴,那么如何得到result值呢?答案是會話(session)薇芝。tensorflow中通過會話來執(zhí)行定義好的運算蓬抄。會話管理并管理tensorflow程序運行時需要的所有資源。tensorflow中的使用會話有兩種方式
- 需要明確的打開和關(guān)閉會話
sess = tf.Session()
print(sess.run(result)) # 和下面一行功能一直
print(result.eval(session=sess))
sess.close()
- 用python中的上下文管理器, 關(guān)閉夯到、異常處理由管理器來完成
with tf.Session() as sess:
print(sess.run(result))
變量
tensorflow變量定義:
import tensorflow as tf
b1 = tf.Variable(tf.zeros([3])) # 常數(shù)生成
b2 = tf.Variable([1, 2, 3]) #
b3 = tf.Variable(tf.random_normal([2, 3], stddev=1, seed=1)) # 隨機函數(shù)生成,指定seed那么每次生成的結(jié)果都一樣
b4 = tf.Variable(b3.initialized_value() * 3) # 別的變量的初始化值生成
with tf.Session() as sess:
sess.run(b1.initializer) # tensorflow中變量的初始化需要被明確的調(diào)用
sess.run(b2.initializer)
sess.run(b3.initializer)
sess.run(b4.initializer)
print(sess.run(b1))
print(sess.run(b2))
print(sess.run(b3))
print(sess.run(b4))
with tf.Session() as sess:
init_op = tf.global_variables_initializer() # 省去上面一個一個的初始化的繁瑣嚷缭。一個函數(shù)初始化所有的變量
sess.run(init_op)
print(sess.run(b1))
print(sess.run(b2))
print(sess.run(b3))
print(sess.run(b4))
tensorflow中變量的初始化有三種方式
- 隨機數(shù)生成函數(shù)
- 常數(shù)生成函數(shù)
- 其他變量的初始值
<center>tensorflow 隨機生成函數(shù)</center>
函數(shù)名稱 | 隨機數(shù)分布 | 主要參數(shù) |
---|---|---|
tf.random_normal | 正太分布 | 平均值、標(biāo)準(zhǔn)差黄娘、取值類型 |
tf.truncated_normal | 正太分布峭状、如果隨機出來的值偏離平均值2個標(biāo)準(zhǔn)差克滴,那這個數(shù)重新隨機 | 平均值逼争、標(biāo)準(zhǔn)差、取值類型 |
tf.random_uniform | 均勻分布 | 平均值劝赔、標(biāo)準(zhǔn)差誓焦、取值類型 |
tf.random_gamma | Gamma分布 | 平均值、標(biāo)準(zhǔn)差着帽、取值類型 |
<center>tensorflow常數(shù)生成函數(shù)</center>
函數(shù)名稱 | 功能 | 樣例 |
---|---|---|
tf.zeros | 產(chǎn)生全0的數(shù)組 | tf.zeros([2,3],int32)->[[0,0,0],[0,0,0]] |
tf.ones | 產(chǎn)生全1的數(shù)組 | tf.ones([2,3],int32)->[[1,1,1],[1,1,1]] |
tf.filll | 產(chǎn)生一個全部為給定數(shù)字的數(shù)組 | tf.fill([2,3],9)->[[9,9,9],[9,9,9]] |
tf.constant | 產(chǎn)生一個給定值的常量 | tf.constant([1,2,3])->[1,2,3] |
張量杂伟、變量的區(qū)別與聯(lián)系
tensorflow中所有的數(shù)據(jù)都是通過張量來組織的,那么為什么又出現(xiàn)了變量了呢仍翰?在tensorflow中變量聲明函數(shù)tf.Variable()是一個運算赫粥。這個運算的結(jié)果就是一個張量,所以變量是一種特殊的張量予借。tf.constant等常量函數(shù)生成的張量是不可變的越平,沒有assign操作,只能引用于值灵迫,不能引用于操作秦叛,但是tf.Variable()聲明的變量是可變的,有assign操作瀑粥,且可以應(yīng)用于操作挣跋,必須tf.Variable(a+b).
一個完整的神經(jīng)網(wǎng)絡(luò)樣例程序
下面給出一個實例程序來訓(xùn)練如下的神經(jīng)網(wǎng)絡(luò)(全連接神經(jīng)網(wǎng)絡(luò)),輸入2個節(jié)點狞换,隱藏層3個節(jié)點避咆,輸出一個節(jié)點舟肉。主要用來學(xué)習(xí)代碼應(yīng)該這么寫
import tensorflow as tf
import numpy as np
# sgd batch的大小
batch_size = 8
# 定義神經(jīng)網(wǎng)絡(luò)的參數(shù)
w1 = tf.Variable(tf.random_normal((2, 3), stddev=1, seed=1))
w2 = tf.Variable(tf.random_normal((3, 1), stddev=1, seed=1))
# 定義輸入, 占位符
x = tf.placeholder(tf.float32, shape=(None, 2), name='x-input')
y_ = tf.placeholder(tf.float32, shape=(None, 1), name='y-input')
# 定義神經(jīng)網(wǎng)絡(luò)前項傳播過程
a = tf.matmul(x, w1)
y = tf.matmul(a, w2)
# 定義損失函數(shù)和反向傳播過程
y = tf.sigmoid(y)
# 定義損失函數(shù),交叉熵
cross_entropy = -tf.reduce_mean(
y_ * tf.log(tf.clip_by_value(y, 1e-10, 1.0)) + (1 - y) * tf.log(
tf.clip_by_value(1 - y, 1e-10, 1.0))) #clip_by_value 參數(shù)修剪查库,防止0的數(shù)度气,大于1的數(shù)
# 定義目標(biāo)函數(shù)
train_step = tf.train.AdamOptimizer(0.001).minimize(cross_entropy)
# 生成一個模擬數(shù)據(jù)集
rdm = np.random.RandomState(1)
dataset_size = 128
# 樣本
X = rdm.rand(dataset_size, 2)
# label, Attention: 這里的Y是一個矩陣
Y = [[int(x1 + x2 < 1)] for (x1, x2) in X]
with tf.Session() as sess:
init_op = tf.global_variables_initializer()
# 初始化變量
sess.run(init_op)
STEPS = 5000
for i in range(STEPS):
# print("step:%d,start", i)
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[start:end],
y_: Y[start:end]
})
print("step:%d, %f", i, total_cross_entropy)
print(sess.run(w1))
print(sess.run(w2))
總結(jié)
一個完整的神經(jīng)網(wǎng)絡(luò)程序需要包含以下三個步驟
- 定義神經(jīng)網(wǎng)絡(luò)的結(jié)果和前項傳播的結(jié)果
- 定義損失函數(shù)已經(jīng)選擇反向傳播的優(yōu)化算法
- 生成會話已經(jīng)在訓(xùn)練數(shù)據(jù)上反復(fù)執(zhí)行方向傳播算法
import numpy as np
import tensorflow as tf
rdm = np.random.RandomState(1)
X = rdm.rand(128, 2)
Y = [[int(x1+x2< 1)] for (x1,x2) in X]
print(Y[0:8])
w1 = tf.Variable(tf.random_normal((2, 3), stddev=1, seed=1))
w2 = tf.Variable(tf.random_normal((3, 1), stddev=1, seed=128))
with tf.Session() as sess:
init_op = tf.global_variables_initializer()
sess.run(init_op)
print(sess.run(w1))
print(sess.run(w2))