一直焙、tensorflow初體驗(yàn)
tensorflow與原生python語(yǔ)言不太相同,tensorflow將每個(gè)對(duì)象都封裝成一個(gè)tensor類型
a = tf.constant(10.0)
print(a)
輸入結(jié)果:
python原生語(yǔ)言實(shí)現(xiàn)加法 VS tensorflow實(shí)現(xiàn)加法:
import tensorflow as tf
# 1. python實(shí)現(xiàn)加法
a_py = 10.0
b_py = 10.0
c_py = a_py + b_py
print('python原生語(yǔ)言計(jì)算a+b={}'.format(c_py))
# 2. tensorflow實(shí)現(xiàn)加法
a = tf.constant(10.0)
b = tf.constant(20.0)
c = tf.add(a, b)
with tf.Session() as sess:# 打印出tensor對(duì)象的值必須在會(huì)話中打印
print('tensorflow計(jì)算a+b={}'.format(sess.run(c)))
二、tensorflow結(jié)構(gòu)分析
tensorflow程序結(jié)構(gòu)就是一個(gè)數(shù)據(jù)流的執(zhí)行 過程,在tensorflow中數(shù)據(jù)會(huì)被看做一個(gè)個(gè)張量,操作會(huì)被看做一個(gè)個(gè)節(jié)點(diǎn)滔岳,tensorflow把這些操作和節(jié)點(diǎn)看構(gòu)建成一個(gè)圖,然后執(zhí)行這個(gè)圖挽牢。
1.認(rèn)識(shí)tensorflow中的圖
圖包含了一組tf.Operation代表的計(jì)算單元對(duì)象和tf.Tensor代表的計(jì)算單元之間流動(dòng)的數(shù)據(jù)谱煤。
2.圖的相關(guān)操作
(1)默認(rèn)圖tensorflow會(huì)為我們的程序創(chuàng)建一張默認(rèn)的圖:tf.get_default_graph()
import tensorflow as tf
a = tf.constant(10.0)
b = tf.constant(20.0)
c = tf.add(a, b)
graph = tf.get_default_graph()
print("graph:", graph)
print("a_graph:", a.graph)
print("b_graph:", b.graph)
print("c_graph:", c.graph)
with tf.Session() as sess:
res = sess.run(c)
print("sess_graph:", sess.graph)
print(res)
查看打印結(jié)果可以發(fā)現(xiàn),所有的節(jié)點(diǎn)操作會(huì)話的地址都和默認(rèn)圖的地址是一樣的
(2)創(chuàng)建圖:tf.Graph()
def graph_demo():
# 圖的演示
a_t = tf.constant(10)
b_t = tf.constant(20)
# 不提倡直接運(yùn)用這種符號(hào)運(yùn)算符進(jìn)行計(jì)算
# 更常用tensorflow提供的函數(shù)進(jìn)行計(jì)算
# c_t = a_t + b_t
c_t = tf.add(a_t, b_t)
print("tensorflow實(shí)現(xiàn)加法運(yùn)算:\n", c_t)
# 獲取默認(rèn)圖
default_g = tf.get_default_graph()
print("獲取默認(rèn)圖:\n", default_g)
# 數(shù)據(jù)的圖屬性
print("a_t的graph:\n", a_t.graph)
print("b_t的graph:\n", b_t.graph)
# 操作的圖屬性
print("c_t的graph:\n", c_t.graph)
# 自定義圖
new_g = tf.Graph()
print("自定義圖:\n", new_g)
# 在自定義圖中去定義數(shù)據(jù)和操作
with new_g.as_default():
new_a = tf.constant(30)
new_b = tf.constant(40)
new_c = tf.add(new_a, new_b)
# 數(shù)據(jù)的圖屬性
print("new_a的graph:\n", new_a.graph)
print("new_b的graph:\n", new_b.graph)
# 操作的圖屬性
print("new_c的graph:\n", new_c.graph)
# 開啟會(huì)話
with tf.Session() as sess:
sum_t = sess.run(c_t)
print("在sess當(dāng)中的sum_t:\n", sum_t)
# 會(huì)話的圖屬性
print("會(huì)話的圖屬性:\n", sess.graph)
# 不同的圖之間不能互相訪問
# sum_new = sess.run(new_c)
# print("在sess當(dāng)中的sum_new:\n", sum_new)
with tf.Session(graph=new_g) as sess2:
sum_new = sess2.run(new_c)
print("在sess2當(dāng)中的sum_new:\n", sum_new)
print("會(huì)話的圖屬性:\n", sess2.graph)
# 很少會(huì)同時(shí)開啟不同的圖禽拔,一般用默認(rèn)的圖就夠了
return None
3.圖的可視化學(xué)習(xí):tensorbroad的使用
首先需要下載好tensorbroad刘离,在虛擬環(huán)境中選擇pip安裝即可。
使用tf.summary.Filewriter(arg1,arg2);第一個(gè)參數(shù)傳保存位置睹栖,第二個(gè)參數(shù)傳遞指定的圖
import tensorflow as tf
a = tf.constant(10.0)
b = tf.constant(20.0)
c = tf.add(a, b)
graph = tf.get_default_graph()
print("graph:", graph)
print("a_graph:", a.graph)
print("b_graph:", b.graph)
print("c_graph:", c.graph)
with tf.Session() as sess:
res = sess.run(c)
print("sess_graph:", sess.graph)
tf.summary.FileWriter('./tmp/summary/', graph=sess.graph)
print(res)
運(yùn)行之后可以發(fā)現(xiàn)在指定的目錄下多了個(gè)文件硫惕,我們進(jìn)入該目錄下執(zhí)行
進(jìn)入指定的端口:
三、tensorflow幾個(gè)名詞
1.會(huì)話:會(huì)話是用來執(zhí)行定義好的運(yùn)算野来,會(huì)話擁有并管理TensorFlow程序運(yùn)行時(shí)的所有資源恼除,所有計(jì)算完成之后需要關(guān)閉會(huì)話來幫助系統(tǒng)回收資源,否則就可能出現(xiàn)資源泄露的問題曼氛,所以我們常用上下文with來使用會(huì)話如:
with tf.Session() as sess:
"""開啟會(huì)話使用資源"""
ps:會(huì)話的run()方法可以傳入一個(gè)數(shù)組進(jìn)去豁辉,一次執(zhí)行很多的計(jì)算結(jié)果
import tensorflow as tf
a = tf.constant(10.0)
b = tf.constant(20.0)
c = tf.add(a, b)
graph = tf.get_default_graph()
with tf.Session() as sess:
sess = tf.Session(config=tf.ConfigProto(allow_soft_placement=True,
log_device_placement=True))#打印出設(shè)備信息
a_res,b_res,c_res = sess.run([a,b,c])
print("sess_graph:", sess.graph)
tf.summary.FileWriter('./tmp/summary/', graph=sess.graph)
print(f"a:{a_res},b:{b_res},c:{c_res}")
同時(shí)我們可以使用placeholder占位符,一開始不給對(duì)象設(shè)置舀患,在會(huì)話內(nèi)執(zhí)行的時(shí)候設(shè)值:
a = tf.placeholder(tf.float32)
b = tf.placeholder(tf.float32)
c = tf.add(a, b)
with tf.Session() as sess:
sess = tf.Session(config=tf.ConfigProto(allow_soft_placement=True,
log_device_placement=True))
res = sess.run(c, feed_dict={a: 10.0, b: 20.0})
print(res)
2.張量:TensorFlow用張量這種數(shù)據(jù)結(jié)構(gòu)來表示所有的數(shù)據(jù).你可以把一個(gè)張量想象成一個(gè)n維的數(shù)組或列表.一個(gè)張量有一個(gè)靜態(tài)類型和動(dòng)態(tài)類型的維數(shù).張量可以在圖中的節(jié)點(diǎn)之間流通.其實(shí)張量更代表的就是一種多位數(shù)組徽级。
利用placeholder傳入數(shù)組進(jìn)行加法
a = tf.placeholder(tf.float32)
b = tf.placeholder(tf.float32)
c = tf.add(a, b)
with tf.Session() as sess:
sess = tf.Session(config=tf.ConfigProto(allow_soft_placement=True,
log_device_placement=True))
res = sess.run(c, feed_dict={a: [10.0, 20.0], b: [20.0, 30.0]})
print(res)
這里不做過多的贅述,只學(xué)習(xí)幾個(gè)創(chuàng)建張量的指令:
(1)tf.ones(shape,dtype,name):創(chuàng)建一個(gè)所有元素均為一的張量
(2)tf.zeros(shape,dtype,name):創(chuàng)建一個(gè)所有元素均為零的張量
(3)tf.constant(value,dtype,name):創(chuàng)建一個(gè)所有常數(shù)的張量
(4)tf.random_normal(shape,mean,stdddv,dtype,seed,name):創(chuàng)建一個(gè)隨機(jī)張量
3.變量op:TensorFlow變量是表示程序處理的共享持久狀態(tài)的最佳方法聊浅。變量通過 tf.Variable OP類以及tf.get_variable()類進(jìn)行操作餐抢。ps變量需要顯式初始化,才能運(yùn)行值
a = tf.Variable(initial_value=10.0, trainable=True)
b = tf.Variable(initial_value=20.0, trainable=True)
c = tf.add(a, b)
# 一定要顯示的初始化
init = tf.global_variables_initializer()
with tf.Session() as sess:
res = sess.run(init)
print(res)
四低匙、案例一:使用tensorflow訓(xùn)練一個(gè)簡(jiǎn)單的邏輯回歸旷痕,并使用tensorbroad展示出來
首先定義一個(gè)類,然后隨機(jī)初始化一組數(shù)據(jù)努咐,并按照某種線性規(guī)則生成一組真實(shí)值:
import tensorflow as tf
class MyLinearRegression(object):
"""手動(dòng)實(shí)現(xiàn)邏輯回歸"""
def __init__(self):
pass;
def input(self):
# 自己先手動(dòng)輸入一組數(shù)據(jù)
x_train = tf.random_normal(shape=[100,1],mean=0,stddev=1,dtype=tf.float32,name="x_train");
y_true = tf.matmul(x_train,[[0.7]]) + 0.8
return x_train,y_true
給定輸入計(jì)算出預(yù)測(cè)值:
def run(self, x_data):
"""為給定的輸入與輸出擬合出w和b"""
# 1.首先隨機(jī)生成一個(gè)w
self.weight = tf.Variable(tf.random_normal(shape=[1, 1], mean=0, stddev=1), name="weight")
self.bias = tf.Variable(tf.random_normal(shape=[1, 1], mean=0, stddev=1), name="bias")
# 2.計(jì)算預(yù)測(cè)值
y_pre = tf.matmul(x_data,self.weight) + self.bias
return y_pre
將每一次計(jì)算的w苦蒿,b和loss收集起來,方便我們?cè)趖ensorbroad中顯示
def merge_summary(self,loss):
"""收集張量值"""
tf.summary.scalar("losses",loss)
tf.summary.histogram("w", self.weight)
tf.summary.histogram("b", self.bias)
# 收集了之后記得合并
merged = tf.summary.merge_all()
return merged
使用梯度下降優(yōu)化一次
def sgd_op(self,loss):
"""使用梯度下降來訓(xùn)練"""
optimizer = tf.train.GradientDescentOptimizer(0.1).minimize(loss)# 0.1是學(xué)習(xí)率
return optimizer
開始迭代訓(xùn)練
def train(self):
"""訓(xùn)練模型"""
# 1.獲得默認(rèn)圖
g = tf.get_default_graph()
with g.as_default():
# 隨機(jī)生成一組數(shù)
x_data, y_true = self.input()
# 計(jì)算出預(yù)測(cè)值
y_pre = self.run(x_data)
# 計(jì)算損失
loss = self.loss(y_pre=y_pre, y_true=y_true)
# 最優(yōu)化一次
train_op = self.sgd_op(loss)
# 收集結(jié)果
merged = self.merge_summary(loss)
# 保存參數(shù)
saver = tf.train.Saver()
# 開啟會(huì)話
with tf.Session() as sess:
# 初始化變量op
init = tf.global_variables_initializer()
sess.run(init)
#print("初始化的權(quán)重:%f, 偏置:%f" % (self.weight.eval(), self.bias.eval()))
# 開啟訓(xùn)練
for i in range(100):
sess.run(train_op)
# print("訓(xùn)練第%d步之后的損失:%f, 權(quán)重:%f, 偏置:%f" % (
# i,
# loss.eval(),
# self.weight.eval(),
# self.bias.eval()))
file_writer = tf.summary.FileWriter("./tmp/summary/", graph=sess.graph)
# 收集計(jì)算結(jié)果
summary = sess.run(merged)
# 添加到文件
file_writer.add_summary(summary, i)
運(yùn)行程序后在tensorboard中查看損失的變化