TensorFlow 基礎(chǔ)概念

本章將對(duì)TensorFlow的基本概念做簡(jiǎn)介表鳍,每節(jié)會(huì)對(duì)一個(gè)大概念做一個(gè)概論--你可以在每節(jié)末尾找到更詳細(xì)的鏈接地址秤茅。
TensorFlow是機(jī)器學(xué)習(xí)的一個(gè)端對(duì)端平臺(tái),支持以下操作:

  • 多維數(shù)組的數(shù)字計(jì)算
  • GPU和分布式運(yùn)算
  • 自動(dòng)微分
  • 模型構(gòu)建、訓(xùn)練和導(dǎo)出
  • 以及其他

Tensors

TensorFlow的運(yùn)算是基于多維數(shù)組或張量帆吻,這些運(yùn)算對(duì)象在TensorFlow中被標(biāo)識(shí)為tf.Tensor對(duì)象普泡。下面的代碼描述了一個(gè)二維張量:

import tensorflow as tf
x = tf.constant([[1., 2., 3. ], [4., 5., 6. ]])

print(x)
print(x.shape)
print(x.dtype)

運(yùn)行結(jié)果為:

tf.Tensor(
[[1. 2. 3.]
 [4. 5. 6.]], shape=(2, 3), dtype=float32)
(2, 3)
<dtype: 'float32'>

對(duì)于Tensor來(lái)說(shuō)播掷,這里有兩個(gè)相當(dāng)重要的概念shape和dtype:

  • Tensor.shape: 表示獲取張量在各個(gè)維度的大小。
  • Tensor.dtype: 表示張量中所有元素的類型撼班。
    TensorFlow在實(shí)現(xiàn)了基于張量的標(biāo)準(zhǔn)數(shù)字操作符的同時(shí)也實(shí)現(xiàn)了機(jī)器學(xué)習(xí)中常用的專用的運(yùn)算符歧匈。如:
x + x

結(jié)果為:

tf.Tensor(
[[ 2.  4.  6.]
 [ 8. 10. 12.]], shape=(2, 3), dtype=float32)
5 * x

結(jié)果為:

tf.Tensor(
[[ 5. 10. 15.]
 [20. 25. 30.]], shape=(2, 3), dtype=float32)
x @ tf.transpose(x)

結(jié)果為:

tf.Tensor(
[[14. 32.]
 [32. 77.]], shape=(2, 2), dtype=float32)
tf.concat([x, x, x], axis=0)

結(jié)果為:

tf.Tensor(
[[1. 2. 3.]
 [4. 5. 6.]
 [1. 2. 3.]
 [4. 5. 6.]
 [1. 2. 3.]
 [4. 5. 6.]], shape=(6, 3), dtype=float32)
tf.concat([x, x, x], axis=1)

結(jié)果為:

tf.Tensor(
[[1. 2. 3. 1. 2. 3. 1. 2. 3.]
 [4. 5. 6. 4. 5. 6. 4. 5. 6.]], shape=(2, 9), dtype=float32)
tf.nn.softmax(x, axis=1)

結(jié)果為:

tf.Tensor(
[[0.09003057 0.24472848 0.66524094]
 [0.09003057 0.24472848 0.66524094]], shape=(2, 3), dtype=float32)
tf.reduce_sum(x)

結(jié)果為:

tf.Tensor(21.0, shape=(), dtype=float32)

在CPU上執(zhí)行大規(guī)模計(jì)算時(shí),效率并不高砰嘁。在進(jìn)行配置之后件炉,TensorFlow可以運(yùn)行在如GPU之類的硬件之上執(zhí)行運(yùn)行操作勘究,效率很高。

if tf.config.list_physical_devices('GPU'):
  print("TensorFlow **IS** using the GPU")
else:
  print("TensorFlow **IS NOT** using the GPU")

結(jié)果為:

TensorFlow **IS NOT** using the GPU

更多細(xì)節(jié)參考Tensor Guide

變量

tf.Tensor類型是不可變類型斟冕,當(dāng)需要保存如模型參數(shù)之類的變量時(shí)口糕,可以使用tf.Variable類型

var = tf.Variable([0.0, 0.0, 0.0])
var.assign([1, 2, 3])
<tf.Variable 'Variable:0' shape=(3,) dtype=float32, numpy=array([1., 2., 3.], dtype=float32)>
var.assign_add([1, 1, 1])
<tf.Variable 'Variable:0' shape=(3,) dtype=float32, numpy=array([2., 3., 4.], dtype=float32)>

更多細(xì)節(jié)參閱Variables guide

自動(dòng)微分

梯度下降法及相關(guān)算法是現(xiàn)代機(jī)器學(xué)習(xí)的重要基礎(chǔ)。
TensorFlow實(shí)現(xiàn)了基于微積分學(xué)的自動(dòng)微分磕蛇,可以幫助你自動(dòng)計(jì)算梯度景描。通常你會(huì)使用這個(gè)功能來(lái)計(jì)算模型的loss關(guān)于其參數(shù)的梯度。

import tensorflow as tf

x = tf.Variable(1.0)


def f(x):
    y = x ** 2 + 2 * x -5
    return y


f(x)

結(jié)果為:

tf.Tensor(-2.0, shape=(), dtype=float32)

在x=1.0孤里,y=f(x) = -2伏伯,其導(dǎo)數(shù)為y' = 2 * x + 2 = 4。TensorFlow可以自動(dòng)計(jì)算出導(dǎo)數(shù)

with tf.GradientTape() as tape:
    y = f(x)

g_x = tape.gradient(y, x)

g_x

運(yùn)行結(jié)果為:

tf.Tensor(4.0, shape=(), dtype=float32)

這是一個(gè)對(duì)簡(jiǎn)單標(biāo)量x求導(dǎo)數(shù)的例子捌袜。TensorFlow可以對(duì)任意數(shù)量的張量同時(shí)計(jì)算梯度说搅。
參考自動(dòng)微分獲得更多的詳情。

圖和tf.function

TensorFlow可以讓你像使用其他python庫(kù)一樣交互式地使用TensorFlow虏等,TensorFlow還提供了一些工具:

  • 性能優(yōu)化:加速訓(xùn)練和推算過(guò)程
  • 導(dǎo)出:在訓(xùn)練結(jié)束之后保存模型
    這需要你使用tf.function讓TensorFlow代碼與Python代碼分離弄唧。
@tf.function
def my_func(x):
    print('Tracing')
    return tf.reduce_sum(x)


x = tf.constant([1, 2, 3])

print(my_func(x))

結(jié)果為:

Tracing
tf.Tensor(6, shape=(), dtype=int32)

在接下來(lái)的調(diào)用中,TensorFlow只會(huì)運(yùn)行優(yōu)化過(guò)的圖代碼霍衫,跳過(guò)非TensorFlow代碼候引。下面的代碼中my_func不會(huì)打印“Tracing”字符,因?yàn)閜rint是一個(gè)純python代碼敦跌,不是TensorFlow的函數(shù)澄干。

x = tf.constant([10, 9, 8])
my_func(x)

結(jié)果為:

tf.Tensor(27, shape=(), dtype=int32)

一個(gè)圖方法會(huì)為不同的入?yún)㈩愋?shape and dtype)創(chuàng)建不同的實(shí)例,即下面的代碼會(huì)生成一個(gè)新的圖柠傍。

x = tf.constant([10.0, 9.1, 8.2], dtype=tf.float32)
my_func(x)

這種圖快照提供了兩個(gè)優(yōu)點(diǎn):

  • 很多情況下圖快照可以提供顯著的計(jì)算加速效果
  • 你可以使用tf.saved_model導(dǎo)出圖麸俘,并將其運(yùn)行在其他系統(tǒng)上(如服務(wù)器和移動(dòng)設(shè)備),而無(wú)需Python環(huán)境惧笛。

Modules, Layers 和models

tf.Module是用于管理tf.Variables對(duì)象以及基于這些對(duì)象的tf.function對(duì)象的類从媚。tf.Module類是實(shí)現(xiàn)如下兩個(gè)重要功能特性的必要條件:

  • 使用tf.train.CheckPoint實(shí)現(xiàn)變量保存的功能,可以快速保存在訓(xùn)練過(guò)程中的模型狀態(tài)
  • 使用tf.saved_model來(lái)導(dǎo)入導(dǎo)出tf.Variable的值和tf.function的圖患整,這使得你可以脫離Python環(huán)境而在任意的設(shè)備上運(yùn)行你的模型拜效。
    下面是一個(gè)簡(jiǎn)單卻又完整的tf.Module導(dǎo)出過(guò)程:
import tensorflow as tf


class MyModule(tf.Module):
    def __init__(self, value):
        self.weight = tf.Variable(value)

    @tf.function
    def multiply(self, x):
        return x * self.weight


mod = MyModule(3)
mod.multiply(tf.constant([1, 2, 3]))

save_path = './saved'
tf.saved_model.save(mod, save_path)


reload = tf.saved_model.load(save_path)
print(reload.multiply(tf.constant([1, 2, 3])))

保存結(jié)果SavedModel獨(dú)立于創(chuàng)建時(shí)的代碼。你可以重新載入SavedModel至Python各谚、其他支持TensorFlow的編程語(yǔ)言或TensorFlow Serving紧憾。你也可以將其運(yùn)行在 TensorFlow LiteTensorFlow JS
基于tf.Module的tf.keras.layers.Layer和tf.keras.Model類提供了更多的功能和便捷的方法用于編譯、訓(xùn)練和保存模型嘲碧,這些將在下一節(jié)提及稻励。
更多細(xì)節(jié)請(qǐng)參考Intro to modules

Training Loops

下面,我們將上述的所有概念綜合使用起來(lái)建立一個(gè)模型,并且從頭開(kāi)始進(jìn)行訓(xùn)練望抽。
首先我們創(chuàng)建一下測(cè)試數(shù)據(jù)加矛,使用二次曲線產(chǎn)生一些數(shù)據(jù)點(diǎn)。

import tensorflow as tf

import matplotlib
from matplotlib import pyplot as plt

matplotlib.rcParams['figure.figsize'] = [9, 6]

x = tf.linspace(-2, 2, 201)
x = tf.cast(x, tf.float32)


def f(x):
    y = x ** 2 + 2 * x - 5
    return y


y = f(x) + tf.random.normal(shape=[201])

plt.plot(x.numpy(), y.numpy(), '.', label='Data')
plt.plot(x, f(x), label='Ground truth')
plt.legend()

plt.show()
Figure_1.png

然后煤篙,創(chuàng)建一個(gè)模型

class Model(tf.keras.Model):
    def __init__(self, units):
        super(Model, self).__init__()
        self.dense1 = tf.keras.layers.Dense(units=units,
                                            activation=tf.nn.relu,
                                            kernel_initializer=tf.random.normal,
                                            bias_initializer=tf.random.normal)
        self.dense2 = tf.keras.layers.Dense(1)

    def call(self, x, training=True):
        x = x[:, tf.newaxis]
        x = self.dense1(x)
        x = self.dense2(x)
        return tf.squeeze(x, axis=1)


model = Model(64)

plt.plot(x.numpy(), y.numpy(), '.', label='Data')
plt.plot(x, f(x),  label='Ground truth')
plt.plot(x, model(x), label='Untrained predictions')
plt.title('Before training')
plt.legend()
plt.show()
Figure_1.png

編寫代碼進(jìn)入訓(xùn)練階段斟览。由于tf.keras已經(jīng)集成了大多數(shù)常用的訓(xùn)練工具,因此直接調(diào)用keras自帶的功能即可辑奈。為此苛茂,你需要使用Model.compile和Model.fit方法來(lái)實(shí)現(xiàn)訓(xùn)練過(guò)程。

model.compile(loss=tf.keras.losses.MSE, optimizer=tf.keras.optimizers.SGD(learning_rate=0.01))

history = model.fit(x, y, epochs=100, batch_size=32, verbose=0)

model.save("./my_model")

將訓(xùn)練過(guò)程中的loss打印出來(lái):

plt.plot(history.history['loss'])
plt.xlabel('Epoch')
plt.ylim([0, max(plt.ylim())])
plt.ylabel('Loss [Mean Squared Error]')
plt.title('Keras training progress')
plt.show()

Figure_1.png

更多詳情請(qǐng)參考 Basic training loopsKeras guide

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末鸠窗,一起剝皮案震驚了整個(gè)濱河市妓羊,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌稍计,老刑警劉巖躁绸,帶你破解...
    沈念sama閱讀 216,544評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異臣嚣,居然都是意外死亡净刮,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門硅则,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)淹父,“玉大人,你說(shuō)我怎么就攤上這事怎虫∈钊希” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 162,764評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵大审,是天一觀的道長(zhǎng)穷吮。 經(jīng)常有香客問(wèn)我,道長(zhǎng)饥努,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 58,193評(píng)論 1 292
  • 正文 為了忘掉前任八回,我火速辦了婚禮酷愧,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘缠诅。我一直安慰自己溶浴,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,216評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布管引。 她就那樣靜靜地躺著士败,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上谅将,一...
    開(kāi)封第一講書人閱讀 51,182評(píng)論 1 299
  • 那天漾狼,我揣著相機(jī)與錄音,去河邊找鬼饥臂。 笑死逊躁,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的隅熙。 我是一名探鬼主播稽煤,決...
    沈念sama閱讀 40,063評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼囚戚!你這毒婦竟也來(lái)了酵熙?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 38,917評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤驰坊,失蹤者是張志新(化名)和其女友劉穎匾二,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體庐橙,經(jīng)...
    沈念sama閱讀 45,329評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡假勿,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,543評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了态鳖。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片转培。...
    茶點(diǎn)故事閱讀 39,722評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖浆竭,靈堂內(nèi)的尸體忽然破棺而出浸须,到底是詐尸還是另有隱情,我是刑警寧澤邦泄,帶...
    沈念sama閱讀 35,425評(píng)論 5 343
  • 正文 年R本政府宣布删窒,位于F島的核電站,受9級(jí)特大地震影響顺囊,放射性物質(zhì)發(fā)生泄漏肌索。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,019評(píng)論 3 326
  • 文/蒙蒙 一特碳、第九天 我趴在偏房一處隱蔽的房頂上張望诚亚。 院中可真熱鬧,春花似錦午乓、人聲如沸站宗。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,671評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)梢灭。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間敏释,已是汗流浹背库快。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,825評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留颂暇,地道東北人缺谴。 一個(gè)月前我還...
    沈念sama閱讀 47,729評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像耳鸯,于是被迫代替她去往敵國(guó)和親湿蛔。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,614評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容