日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

TensorFlow 2.0 快速上手教程与手写数字识别例子讲解

發布時間:2023/12/19 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 TensorFlow 2.0 快速上手教程与手写数字识别例子讲解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • TensorFlow 基礎
    • 自動求導機制
    • 參數優化
  • TensorFlow 模型建立、訓練與評估
    • 通用模型的類結構
    • 多層感知機手寫數字識別
  • Keras Pipeline *

TensorFlow 2.0 出來后不久就有人整理了一份簡潔高效的中文指導手冊: 簡單粗暴 TensorFlow 2,本文對其中一些重點內容加以梳理,方便快速上手。

如果你還沒裝上 TensorFlow 2.0 ,或者希望對 TensorFlow 2.0 的新特性有個大概的了解,可以查看我之前的文章:tensorflow2.0 GPU 版本安裝測試教程及新特性初探

TensorFlow 基礎

自動求導機制

TensorFlow 提供了強大的 自動求導機制 來計算導數。在即時執行模式(eager execution)下,TensorFlow 引入了 tf.GradientTape() 這個 “求導記錄器” 來實現自動求導。以線性回歸為例子,假設其損失函數為:
L(w,b)=∣∣Xw+b?y∣∣2L(w, b) = ||Xw+b-y||^2 L(w,b)=Xw+b?y2
我們用下面的代碼計算給定 X 與 y 后, L(w,b)L(w,b)L(w,b)w=(1,2)T,b=1w=(1,2)^T, \; b=1w=(1,2)T,b=1 時對 w,bw,bw,b 的偏導數。

import tensorflow as tfX = tf.constant([[1., 2.], [3., 4.]]) y = tf.constant([[1.], [2.]]) # 初始化要學習的參數 w = tf.Variable(initial_value=[[1.], [2.]]) b = tf.Variable(initial_value=1.)# 在 tf.GradientTape() 的上下文內,所有計算步驟都會被記錄以用于求導 with tf.GradientTape() as tape:L = tf.reduce_sum(tf.square(tf.matmul(X, w) + b - y))# 計算L(w, b)關于w, b的偏導數 w_grad, b_grad = tape.gradient(L, [w, b]) print(L, w_grad, b_grad)

輸出:

tf.Tensor(125.0, shape=(), dtype=float32) tf.Tensor( [[ 70.] [100.]], shape=(2, 1), dtype=float32) tf.Tensor(30.0, shape=(), dtype=float32)

從輸出結果可見 TensorFlow 幫我們計算出了梯度值。

上面的代碼中,變量 w 和 b 使用 tf.Variable() 申明,通過這種方式得到的變量默認能夠被 TensorFlow 的自動求導機制所求導,因此往往被用于定義機器學習模型的參數。tf.GradientTape() 是一個自動求導的記錄器。只要進入了 with tf.GradientTape() as tape 的上下文環境,則在該環境中計算步驟都會被自動記錄。比如在上面的示例中,計算步驟 L = tf.reduce_sum(tf.square(tf.matmul(X, w) + b - y)) 即被自動記錄。離開上下文環境后,記錄將停止,但記錄器 tape 依然可用,因此可以通過 w_grad, b_grad = tape.gradient(L, [w, b]) 求張量 L 對變量 w,b 的導數。

TIPS: tf.square() 操作代表對輸入張量的每一個元素求平方,不改變張量形狀。 tf.reduce_sum() 操作代表對輸入張量的所有元素求和,輸出一個形狀為空的純量張量(可以通過 axis 參數來指定求和的維度,不指定則默認對所有元素求和)。TensorFlow 中有大量的張量操作 API,包括數學運算、張量形狀操作(如 tf.reshape())、切片和連接(如 tf.concat())等多種類型

參數優化

本節以 TensorFlow 下的線性回歸示例展開,講解如何進行參數優化。

首先,我們定義數據,進行基本的歸一化操作:

import numpy as npX_raw = np.array([2013, 2014, 2015, 2016, 2017], dtype=np.float32) y_raw = np.array([12000, 14000, 15000, 16500, 17500], dtype=np.float32)X = (X_raw - X_raw.min()) / (X_raw.max() - X_raw.min()) y = (y_raw - y_raw.min()) / (y_raw.max() - y_raw.min())

TensorFlow 的 即時執行模式提供了更快速的GPU運算、自動求導、優化器等一系列對深度學習非常重要的功能。以下展示了如何使用 TensorFlow 計算線性回歸:

X = tf.constant(X) y = tf.constant(y)a = tf.Variable(initial_value=0.) b = tf.Variable(initial_value=0.) variables = [a, b]num_epoch = 10000 optimizer = tf.keras.optimizers.SGD(learning_rate=5e-4) for e in range(num_epoch):# 使用tf.GradientTape()記錄損失函數的梯度信息with tf.GradientTape() as tape:y_pred = a * X + bloss = tf.reduce_sum(tf.square(y_pred - y))# TensorFlow自動計算損失函數關于自變量(模型參數)的梯度grads = tape.gradient(loss, variables)# TensorFlow自動根據梯度更新參數optimizer.apply_gradients(grads_and_vars=zip(grads, variables))

在這里,我們使用了前文的方式計算了損失函數關于參數的偏導數。同時,使用 tf.keras.optimizers.SGD(learning_rate=5e-4) 聲明了一個梯度下降 優化器 (Optimizer),其學習率為 5e-4。優化器可以幫助我們根據計算出的求導結果更新模型參數,從而最小化某個特定的損失函數,具體使用方式是調用其 apply_gradients() 方法。

注意到 optimizer.apply_gradients() 需要提供參數 grads_and_vars,即待更新的變量(如上述代碼中的 variables )及損失函數關于這些變量的偏導數(如上述代碼中的 grads )。具體而言,這里需要傳入一個 Python 列表(List),列表中的每個元素是一個 (變量的偏導數,變量) 對。比如上例中需要傳入的參數是 [(grad_a, a), (grad_b, b)] 。我們通過 grads = tape.gradient(loss, variables) 求出 tape 中記錄的 loss 關于 variables = [a, b] 中每個變量的偏導數,也就是 grads = [grad_a, grad_b],再使用 Python 的 zip() 函數將 grads = [grad_a, grad_b] 和 variables = [a, b] 拼裝在一起,就可以組合出所需的參數了。

接下來的部分,是一個更正式的例子。

TensorFlow 模型建立、訓練與評估

在 TensorFlow2.0 中,比較推薦使用 Keras( tf.keras )構建模型。Keras 在 tf.keras.layers 下內置了深度學習中大量常用的的預定義層(例如基本的全連接層,CNN 的卷積層、池化層等),同時也允許我們自定義層。

通用模型的類結構

Keras 模型以類的形式呈現,我們可以通過繼承 tf.keras.Model 這個 Python 類來定義自己的模型。在繼承類中,我們需要重寫 __init__() (構造函數,初始化)和 call(input) (模型調用)兩個方法,同時也可以根據需要增加自定義的方法。

常見的結構如下:

class MyModel(tf.keras.Model):def __init__(self):super().__init__()# 此處添加初始化代碼(包含 call 方法中會用到的層),例如# layer1 = tf.keras.layers.BuiltInLayer(...)# layer2 = MyCustomLayer(...)def call(self, input):# 此處添加模型調用的代碼(處理輸入并返回輸出),例如# x = layer1(input)# output = layer2(x)return output# 還可以添加自定義的方法

繼承 tf.keras.Model 后,我們同時可以使用父類的若干方法和屬性,例如在實例化類 model = Model() 后,可以通過 model.variables 這一屬性直接獲得模型中的所有變量,免去我們一個個顯式指定變量的麻煩。

TIPS:前面的文章說到,在計算梯度的時候,需要傳遞要計算梯度的變量,這些變量可以通過 model.variables 一次性獲取。

多層感知機手寫數字識別

下面以多層感知機實現手寫數字識別為例子,講解如何構建模型、如何訓練、如何評估結果。

首先定義一個類,完成數據的加載:

class MNISTLoader():def __init__(self):mnist = tf.keras.datasets.mnist(self.train_data, self.train_label), (self.test_data, self.test_label) = mnist.load_data()# 在 TensorFlow 中,圖像數據集的一種典型表示是 [圖像數目,長,寬,色彩通道數]# MNIST中的圖像默認為uint8(0-255的數字)。以下代碼將其歸一化到0-1之間的浮點數,并在最后增加一維作為顏色通道self.train_data = np.expand_dims(self.train_data.astype(np.float32) / 255.0, axis=-1) # [60000, 28, 28, 1]self.test_data = np.expand_dims(self.test_data.astype(np.float32) / 255.0, axis=-1) # [10000, 28, 28, 1]self.train_label = self.train_label.astype(np.int32) # [60000]self.test_label = self.test_label.astype(np.int32) # [10000]self.num_train_data, self.num_test_data = self.train_data.shape[0], self.test_data.shape[0]def get_batch(self, batch_size):# 從數據集中隨機取出batch_size個元素并返回index = np.random.randint(0, self.num_train_data, batch_size)return self.train_data[index, :], self.train_label[index]

接下來是模型的構建:

class MLP(tf.keras.Model):def __init__(self):super().__init__()# Flatten層將除第一維(batch_size)以外的維度展平self.flatten = tf.keras.layers.Flatten() self.dense1 = tf.keras.layers.Dense(units=100, activation=tf.nn.relu)self.dense2 = tf.keras.layers.Dense(units=10)def call(self, inputs): # [batch_size, 28, 28, 1]x = self.flatten(inputs) # [batch_size, 784]x = self.dense1(x) # [batch_size, 100]x = self.dense2(x) # [batch_size, 10]output = tf.nn.softmax(x)return output

在訓練前需要的準備工作:

# 定義訓練參數 num_epochs = 5 batch_size = 50 learning_rate = 0.001# 實例化模型和數據讀取類 model = MLP() data_loader = MNISTLoader() # 聲明優化器 optimizer = tf.keras.optimizers.Adam(learning_rate=learning_rate) # 聲明迭代次數 num_batches = int(data_loader.num_train_data // batch_size * num_epochs)

然后來是模型的迭代與訓練:

  • 從 DataLoader 中隨機取一批訓練數據;
  • 將這批數據送入模型,計算出模型的預測值;
  • 將模型預測值與真實值進行比較,計算損失函數(loss)。這里使用 tf.keras.losses 中的交叉熵函數作為損失函數;
  • 計算損失函數關于模型變量的導數;
  • 將求出的導數值傳入優化器,使用優化器的 apply_gradients 方法更新模型參數以最小化損失函數

代碼如下:

for batch_index in range(num_batches):X, y = data_loader.get_batch(batch_size)with tf.GradientTape() as tape:y_pred = model(X)loss = tf.keras.losses.sparse_categorical_crossentropy(y_true=y, y_pred=y_pred)loss = tf.reduce_mean(loss)print("batch %d: loss %f" % (batch_index, loss.numpy()))grads = tape.gradient(loss, model.variables)optimizer.apply_gradients(grads_and_vars=zip(grads, model.variables))

TIPS:在 tf.keras.losses 中,有兩個交叉熵相關的損失函數,都需要接受真實標簽 y_true 與預測結果 y_pred 作為輸入,二者的主要區別體現在 y_true 的形式不同。

1,sparse_categorical_crossentropy :

這也是我們的代碼中使用的損失函數,需要將模型的預測值 y_pred 與真實的標簽值 y 作為函數參數傳入,由 Keras 幫助我們計算損失函數的值。其中 y_pred 是 10 維的向量,表示樣本屬于各個類別的概率值,而標簽 y 則是真實值,例如8,1,2等。

2,categorical_crossentropy:

與sparse_categorical_crossentropy 不同的是,在多分類問題中,參數 y_true 的輸入值應該是經過 onehot 編碼后的向量。也就是說:

loss = tf.keras.losses.sparse_categorical_crossentropy(y_true=y, y_pred=y_pred)

與下面的代碼等效:

loss = tf.keras.losses.categorical_crossentropy(y_true=tf.one_hot(y, depth=tf.shape(y_pred)[-1]),y_pred=y_pred )

最后是模型的評估:

sparse_categorical_accuracy = tf.keras.metrics.SparseCategoricalAccuracy() num_batches = int(data_loader.num_test_data // batch_size) for batch_index in range(num_batches):start_index, end_index = batch_index * batch_size, (batch_index + 1) * batch_sizey_pred = model.predict(data_loader.test_data[start_index: end_index])sparse_categorical_accuracy.update_state(y_true=data_loader.test_label[start_index: end_index], y_pred=y_pred) print("test accuracy: %f" % sparse_categorical_accuracy.result())

TIPS:這里,我們使用 tf.keras.metrics 中的 SparseCategoricalAccuracy 評估器來評估模型在測試集上的性能,該評估器能夠對模型預測的結果與真實結果進行比較,并輸出預測正確的樣本數占總樣本數的比例。我們迭代測試數據集,每次通過 update_state() 方法向評估器輸入兩個參數: y_pred 和 y_true ,即模型預測出的結果和真實結果。評估器具有內部變量來保存當前評估指標相關的參數數值(例如當前已傳入的累計樣本數和當前預測正確的樣本數)。迭代結束后,我們使用 result() 方法輸出最終的評估指標值(預測正確的樣本數占總樣本數的比例)。

當然,也可以把每次的預測結果轉換成numpy的形式保存起來,然后使用 sklearn 中的評估函數進行評估。

Keras Pipeline *

以上示例均使用了 Keras 的 Subclassing API 建立模型,即對 tf.keras.Model 類進行擴展以定義自己的新模型,同時手工編寫了訓練和評估模型的流程。這種方式靈活度高,且與其他流行的深度學習框架(如 PyTorch、Chainer)共通,是本手冊所推薦的方法。

不過在很多時候,我們只需要建立一個結構相對簡單和典型的神經網絡(比如上文中的 MLP 和 CNN),并使用常規的手段進行訓練。這時,Keras 也給我們提供了另一套更為簡單高效的內置方法來建立、訓練和評估模型。具體的使用方法與常規的 Keras 十分相似,這里就不展開講解了。

參考文章:

TensorFlow 基礎

TensorFlow 模型建立與訓練

總結

以上是生活随笔為你收集整理的TensorFlow 2.0 快速上手教程与手写数字识别例子讲解的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。