簡(jiǎn)介
tensorflow 是谷歌于2015年11月開(kāi)源的通用計(jì)算框架,由谷歌大腦團(tuán)隊(duì)基于谷歌內(nèi)部第一代深度學(xué)習(xí)框架 DistBelief 改進(jìn)而來(lái)。雖然 DistBelief 已經(jīng)被谷歌內(nèi)部很多產(chǎn)品使用,但他過(guò)于依賴(lài)谷歌內(nèi)部的系統(tǒng)架構(gòu),較難對(duì)外開(kāi)源。谷歌大腦團(tuán)隊(duì)對(duì)其進(jìn)行了改造,使得 tensorflow 的計(jì)算模型更加通過(guò),計(jì)算速度更快、支持平臺(tái)更多等。
2019年10月 tensorflow 2.0 正式版發(fā)布,新版本加入了提升易用性的諸多新特性,例如以 tf.keras 為核心的統(tǒng)一高層 API、使用 tf.function 構(gòu)建圖模型、默認(rèn)使用即時(shí)執(zhí)行模式等。 TensorFlow 已經(jīng)形成了一個(gè)擁有龐大版圖的生態(tài)系統(tǒng)。TensorFlow Lite、TensorFlow.js、TensorFlow for Swift、TPU 等各種組件日益成熟。
安裝
從 tensorflow 2.0 開(kāi)始不再支持 Python 2,最終支持版本到1.15
# tensorflow 2.0 只需要安裝一次
pip install tensorflow
GPU版本的安裝(僅對(duì)1.x版本)
pip install tensorflow-gpu
基礎(chǔ)概念
tensorflow 采用了計(jì)算圖模型,hw = h + w 僅是定義了相加的操作,不會(huì)真正執(zhí)行計(jì)算。計(jì)算的執(zhí)行需要放在 session 當(dāng)中。
張量
TensorFlow 使用 張量 (Tensor)作為數(shù)據(jù)的基本單位。TensorFlow 的張量在概念上等同于多維數(shù)組,我們可以使用它來(lái)描述數(shù)學(xué)中的標(biāo)量(0 維數(shù)組)、向量(1 維數(shù)組)、矩陣(2 維數(shù)組)等各種量
# 定義一個(gè)常數(shù)(標(biāo)量)
c = tf.constant(4.0)
# 定義一個(gè)有2個(gè)元素的零向量
zero_vector = tf.zeros(shape=(2))
# 定義兩個(gè)2×2的常量矩陣
A = tf.constant([[1., 2.], [3., 4.]])
B = tf.constant([[5., 6.], [7., 8.]])
張量的重要屬性是其名字、形狀和類(lèi)型??梢酝ㄟ^(guò)張量的 name、 shape 和 dtype 屬性 方法獲得。例如:
# 查看矩陣A的形狀、類(lèi)型和值
print(A.shape) # 輸出(2, 2),即矩陣的長(zhǎng)和寬均為2
print(A.dtype) # 輸出<dtype: 'float32'>
print(A.name) # 輸出[[1. 2.]
# [3. 4.]]
計(jì)算圖
tensorflow 的計(jì)算都是通過(guò)計(jì)算圖的形式進(jìn)行的,tensorflow 程序基本可以分解位兩個(gè)階段:構(gòu)造計(jì)算圖;執(zhí)行計(jì)算圖
圖的節(jié)點(diǎn)代表了 tensorflow 當(dāng)中的操作(如加、減、常亮等),而邊則代表了節(jié)點(diǎn)之間的依賴(lài)關(guān)系。
比如下面這段代碼
import tensorflow as tf
a = tf.constant(5)
b = tf.constant(2)
c = tf.constant(3)
d = tf.multiply(a,b)
e = tf.add(c,b)
f = tf.subtract(d,e)
可以用如下的圖來(lái)表示

這就構(gòu)造了一個(gè)計(jì)算圖,如果要獲得計(jì)算結(jié)果,還需要運(yùn)行計(jì)算圖
with tf.Session() as sess:
result = sess.run(f)
從我們引入 tensorflow 的包開(kāi)始,就已經(jīng)默認(rèn)給我們創(chuàng)建了一個(gè)圖
import tensorflow as tf
print(tf.get_default_graph())
g = tf.Graph()
print(g)
Out:
<tensorflow.python.framework.ops.Graph object at 0x7fd88c3c07d0>
<tensorflow.python.framework.ops.Graph object at 0x7fd88c3c03d0>
會(huì)話(huà)
會(huì)話(huà) (session) 用于執(zhí)行構(gòu)造好的計(jì)算圖。會(huì)話(huà)擁有并管理 tensorflow 程序運(yùn)行時(shí)的所有資源,計(jì)算完成后會(huì)話(huà)關(guān)閉時(shí)會(huì)回收系統(tǒng)資源。計(jì)算結(jié)果只能在會(huì)話(huà)中獲得
命名空間
with tf.name_scope('inference') as scope:
w = tf.constant([[0,0,0]],dtype=tf.float32,name='weights')
print(w)
>>>Tensor("inference/weights:0", shape=(1, 3), dtype=float32)
- tf.name_scope()指定的區(qū)域中定義的對(duì)象,他們的“name”屬性上會(huì)增加該命名區(qū)的區(qū)域名,用以區(qū)別對(duì)象屬于哪個(gè)區(qū)域
- name_scope只決定對(duì)象屬于哪個(gè)范圍,并不會(huì)對(duì)作用域產(chǎn)生影響
其他
- Placeholders 存放輸入數(shù)據(jù)??梢钥醋鍪且粋€(gè)空的變量,在執(zhí)行計(jì)算圖的時(shí)候賦予具體的數(shù)值。一般用于定義輸入?yún)?shù)
- 變量(Variables) 在數(shù)據(jù)流圖中對(duì)于普通Tensor來(lái)說(shuō),經(jīng)過(guò)一次操作之后,就會(huì)轉(zhuǎn)化為另一個(gè)Tensor。當(dāng)前一個(gè)Tensor的使命完成之后就會(huì)被系統(tǒng)回收。- Variable 可以看作是是一個(gè)常駐內(nèi)存,不會(huì)被輕易回收的張量。可以通過(guò) tf.Variable 創(chuàng)建變量
- 優(yōu)化器 最優(yōu)化模型預(yù)測(cè)值和真實(shí)值差異的算法策略
工作流程
- 創(chuàng)建測(cè)試數(shù)據(jù)
import numpy as np
x_data = np.random.randn(2000,3)
w_real = [0.3,0.5,0.1]
b_real = -0.2
noise = np.random.randn(1,2000)*0.1
y_data = np.matmul(w_real,x_data.T) + b_real + noise

- 線(xiàn)性回歸模型
# 迭代計(jì)算次數(shù)
NUM_STEPS = 10
g = tf.Graph()
wb_ = []
with g.as_default():
# placeholder定義輸入輸出參數(shù)
x = tf.placeholder(tf.float32,shape=[None,3])
y_true = tf.placeholder(tf.float32,shape=None)
with tf.name_scope('inference') as scope:
# Variable定義模型參數(shù)
w = tf.Variable([[0,0,0]],dtype=tf.float32,name='weights')
b = tf.Variable(0,dtype=tf.float32,name='bias')
y_pred = tf.matmul(w,tf.transpose(x)) + b
- 定義損失函數(shù)
損失函數(shù)用于衡量模型預(yù)測(cè)值和真實(shí)值之間的差異,一般是通過(guò)最小化損失函數(shù)來(lái)達(dá)到優(yōu)化模型參數(shù)的目的。常見(jiàn)的損失函數(shù)有均方差(MSE) 和 交叉熵
這里選擇 MSE 作為損失函數(shù)

with tf.name_scope('loss') as scope:
loss = tf.reduce_mean(tf.square(y_true-y_pred))
- 定義優(yōu)化器
優(yōu)化器用來(lái)為損失函數(shù)尋找最小值,最常用的優(yōu)化器是梯度下降。參數(shù)會(huì)沿著梯度下降的方法進(jìn)行迭代直到達(dá)到最優(yōu)值或者設(shè)定的迭代閾值。
with tf.name_scope('train') as scope:
learning_rate = 0.5
optimizer = tf.train.GradientDescentOptimizer(learning_rate)
train = optimizer.minimize(loss)
- 會(huì)話(huà)中運(yùn)行
init = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init)
for step in range(NUM_STEPS):
sess.run(train,{x: x_data, y_true: y_data})
if (step % 5 == 0):
print(step, sess.run([w,b]))
wb_.append(sess.run([w,b]))
print(10, sess.run([w,b]))
輸出結(jié)果

和之前定義的參數(shù) w = [0.3,0.5,0.1] 和 b = -0.2 已經(jīng)比較接近了