Posted on

TensorFlow Extended (TFX) 介紹

功能介紹

TensorFlow Extended (TFX) 是Google 開發的一個開源框架,用於在TensorFlow 中構建機器學習管道。TFX 的目標是簡化機器學習管道的構建過程,使其能夠更容易地部署和維護。

其中TFX 管道是TFX 中的一個重要部分,它是一種用於組織和管理機器學習工作流的方式。TFX 管道由多個組件組成,每個組件負責執行特定的任務,如數據預處理、訓練、評估等。TFX 管道中的組件可以由TFX 提供的組件使用,也可以使用自定義組件。

TFX 管道通過使用Apache Airflow 或Kubeflow Pipelines 在組件之間傳遞數據來實現自動化的機器學習工作流。這樣可以在一個可視化的界面上監控和管理管道執行過程,並且在管道中的每個步驟之間自動傳遞數據。

強大的資料處理工具

TFDV 結合開源的 Facets ,是可以幫助理解和分析機器學習數據集的開源可視化工具,在 Google AI Blog 中展示了透過 Facets 視覺化抓出 CIFAR-10 資料集中一個錯誤分為貓咪的青蛙的圖片。

TFDV 容許兩個資料及之間的分布對照,例如訓練資料與測試資料,迅速抓出資料飄移與偏斜情形,而 TFDV 更進一步可以做到修正與納入新特徵,以及整合在筆記本及 TFX 之中。

PS: 以上資料來自於Day 14 : 資料驗證 TensorFlow Data Validation (TFDV)

安裝TFX

pip install tfx
pip install -i https://pypi-nightly.tensorflow.org/simple --pre tfx

上文命令會安裝 TFX 的主要依賴項的軟件包,例如 TensorFlow 模型分析 (TFMA)、TensorFlow 數據驗證 (TFDV)、TensorFlow 轉換 (TFT)、TFX 基本共享庫 (TFX-BSL)、ML 元數據 ( MLMD)。

這些組件之間的數據流


下圖說明了TFX庫與流水線組之間的關係:

研究感想

這個工具組裡面的TFDV非常的吸引我,但是後來發現若要使用TFDV去驗證資料,前面還是需要把資料集先經過前面FTX的流水線處理過後,才有辦法使用Facets去可視化已經經過驗證後的資料結果。Facets並沒有辦法直接讀入未經TFX流水線處理過的原始資料集,而FTX對現在的我還有一點複雜,所以先大概知道有這個工具,然後以後再來慢慢摸索。

Posted on

用兩張圖片來偵測圖像是否在靜止狀態

實踐概念

使用 TensorFlow 的圖像處理函數,將兩張圖片讀入並進行比對。

比如您可以使用 OpenCV 庫將圖片讀入,然後使用 TensorFlow 庫對兩張圖片進行比對。 您可以使用 TensorFlow 的圖像處理函數,例如圖像縮放、旋轉和鏡像轉換等,對兩張圖片進行預處理。接著您可以使用 TensorFlow 中的數值計算函數,例如 mean square error (MSE) 或 structural similarity index (SSIM)等,對兩張圖片進行比對。

如果比對結果的值非常小,則可以認為兩張圖片非常相似,反之則表示兩張圖片不相似。

Structural Similarity Index (SSIM)

Structural Similarity Index (SSIM) 是一種用於評估圖像相似度的指標。它是基於人眼視覺系統的特性,模擬人眼對圖像質量的敏感度,並使用三個要素來評估圖像相似度:亮度、對比度和結構。

亮度(luma): 表示圖像中所有像素的平均亮度
對比度(contrast): 表示圖像中各像素亮度值的差異程度
結構(structure): 表示圖像中各像素之間的相關性
SSIM 使用這三個要素的加權和來計算圖像之間的相似度,其值介於 -1 到 1 之間,值越大則表示圖像相似度越高。

SSIM 有很好的相似度表示能力,在圖像壓縮、還原和質量評估等領域有著廣泛的應用。

使用Tensorflow實現SSIM的簡單範例

以下是使用 TensorFlow 實現 SSIM 的簡單範例,該範例使用兩張圖片來比較它們的相似度:

import tensorflow as tf

# 讀入兩張圖片
img1 = tf.io.read_file('image1.jpg')
img2 = tf.io.read_file('image2.jpg')
img1 = tf.image.decode_jpeg(img1, channels=3)
img2 = tf.image.decode_jpeg(img2, channels=3)

# 計算兩張圖片的 SSIM
ssim = tf.image.ssim(img1, img2, max_val=255)

# 顯示 SSIM 值
print(ssim)

這個範例中,我們使用 TensorFlow 的 I/O 函數來讀入兩張圖片,使用 decode_jpeg 函數將圖片解碼為 Tensor,然後使用 ssim 函數對兩張圖片進行比對,最終顯示 SSIM 值。

注意: 這個範例中,由於是在計算兩張圖片的 SSIM,所以需要兩張圖片大小相同,如果不同需要先對兩張圖片進行resize或pad。

Posted on

Tensorflow裡Estimator介紹

tf.estimator.Estimator 介紹

官方介紹頁面: https://www.tensorflow.org/guide/estimator
tf.estimator.Estimator tf.keras.Model 類似,estimator是模型級別的抽象。tf.estimator提供了一些目前仍在為 tf.keras 開發中的功能。包括:

  • 基於參數服務器的訓練
  • 完整的TFX集成

使用預製Estimator,能夠在比基礎TensorFlow API 高很多的概念層面上工作。您無需再擔心創建計算圖或會話,因為Estimator 會替您完成所有“基礎工作”。此外,使用預製Estimator,您只需改動較少代碼就能試驗不同的模型架構。例如,tf.estimator.DNNClassifier是一個預製Estimator 類,可基於密集的前饋神經網絡對分類模型進行訓練。

它提供了一種統一的方式來實現和使用各種不同類型的機器學習模型。它提供了一些預定義的模型類型,如線性迴歸、決策樹、KNN等,可以讓開發者更輕鬆的實現常見的機器學習模型。

主要功能

tf.estimator 是 TensorFlow 的一個高級 API,它提供了一種統一的方式來實現和使用各種不同類型的機器學習模型。它的主要用途是簡化建立、訓練和使用模型的流程,使開發人員能夠更輕鬆地實現常見的機器學習模型。

其主要功能如下:

  • 提供預定義的模型類型, 如線性迴歸,決策樹和KNN等
  • 提供一組工具,可以幫助您訓練,評估和預測模型
  • 提供一個統一的界面,使得用戶能夠更容易地訓練、評估和使用模型
  • 支持模型訓練和預測的分布式計算
  • 具有模型檢查点和恢復功能,可以將模型訓練過程中的狀態保存到磁盤上

優點

  • 提供了一個統一的界面,使開發人員能夠更輕鬆地實現常見的機器學習模型
  • 提供了一組工具,可以幫助您訓練,評估和預測模型
  • 支持模型訓練和預測的分布式計算
  • 具有模型檢查点和恢復功能,可以將模

在2.0裡被標註為棄用

在官網的API文件裡可以發現這個類別旁邊被註記了【棄用標籤】

在 TensorFlow 2.0 中,tf.estimator 被宣布即將棄用是因為它與 TensorFlow 的其他部分存在一些不一致性。隨著 TensorFlow 進化,其他部分,特別是 Keras API,已經成為了更簡單,更直接的機器學習模型構建選項。

Keras API 提供了一個統一的界面,可以用於創建和調用各種不同類型的模型,並且與 TensorFlow 的其他部分(如 TensorFlow 的低級計算圖 API)更加一致。

另外,Keras API 更加易於學習和使用,並且支持更多的高級功能,如自動微調。因此,TensorFlow 的開發團隊決定將重點轉移到 Keras API 上,並將 tf.estimator 標記為即將棄用。

學習 Keras API 更簡單,並且與其他 TensorFlow 特性更加一致,因此官方才會建議將重點轉向學習 Keras API。

使用Keras API來取代tf.estimator.Estimator的範例

tf.estimator.LinearRegressor 的使用範例

import tensorflow as tf

# Define the input function
def input_fn(features, labels, batch_size):
    dataset = tf.data.Dataset.from_tensor_slices((features, labels))
    dataset = dataset.shuffle(1000).batch(batch_size)
    return dataset

# Define the feature columns
feature_columns = [tf.feature_column.numeric_column("x", shape=[1])]

# Define the LinearRegressor
regressor = tf.estimator.LinearRegressor(feature_columns=feature_columns)

# Define the training inputs
train_input_fn = lambda: input_fn(x_train, y_train, batch_size=batch_size)

# Train the model
regressor.train(input_fn=train_input_fn, steps=1000)

# Define the testing inputs
test_input_fn = lambda: input_fn(x_test, y_test, batch_size=batch_size)

# Evaluate the model
metrics = regressor.evaluate(input_fn=test_input_fn)
print("Mean squared error: ", metrics["average_loss"])

把上面的程式碼使用Keras API改寫

from tensorflow import keras

# Define the model
model = keras.Sequential()
model.add(keras.layers.Dense(1, input_shape=[1]))

# Compile the model
model.compile(optimizer='sgd', loss='mean_squared_error')

# Train the model
model.fit(x_train, y_train, epochs=100)

在上面的程式碼之中,線性回歸的設定是來自於以下compile所設定的參數
model.compile(optimizer='sgd', loss='mean_squared_error')
使用 ‘sgd’ 作為優化器和 ‘mean_squared_error’ 作為損失函數是常用於實現線性迴歸模型的設定。

‘SGD’ 是隨機梯度下降的縮寫,它是一種優化算法,用於尋找最小化損失函數的權重值。’mean_squared_error’ 是一種常用的損失函數,用於計算預測值和實際值之間的差距。

在線性迴歸中, 我們嘗試找到一組權重和偏差, 使得預測值和實際值之間的差距最小, 而 mean_squared_error 是計算預測值和實際值之間差距的常用方法, 所以使用 mean_squared_error 作為損失函數是適當的.

tf.estimator.train_and_evaluate

tf.estimator.train_and_evaluate是TensorFlow Estimator API 中的一個函數,用於在訓練和評估模型時自動管理訓練循環。

它接受兩個參數:一個是估計器對象,另一個是一個字典,其中包含訓練和評估所需的所有配置信息。

在訓練期間,該函數會自動調用估計器的train() 方法,並在訓練過程中記錄訓練步驟和損失值。在評估期間,該函數會自動調用估計器的evaluate() 方法,並在評估過程中記錄評估指標。

通過使用tf.estimator.train_and_evaluate可以簡化訓練和評估模型的流程,避免手動管理訓練循環和評估過程中的各種細節。這樣可以讓開發人員專注於模型的構建和調優,而不必擔心訓練和評估的細節實現。

使用示例如下:

# Define the estimator
estimator = tf.estimator.LinearClassifier(feature_columns=feature_columns)

# Define the training and evaluation specs
train_spec = tf.estimator.TrainSpec(input_fn=train_input_fn, max_steps=1000)
eval_spec = tf.estimator.EvalSpec(input_fn=eval_input_fn)

# Train and evaluate the estimator
tf.estimator.train_and_evaluate(estimator, train_spec, eval_spec)

可以使用Keras API 來使用tf.estimator.train_and_evaluate。
使用TensorFlow 的Keras API 和Estimator API 來構建模型時,可以使用 tf.keras.estimator.model_to_estimator() 函數將Keras 模型轉換為Estimator,然後使用 tf.estimator.train_and_evaluate() 函數訓練和評估模型。

示例如下:

import tensorflow as tf
from tensorflow import keras

# Define the Keras model
def build_model():
    model = keras.Sequential([
        keras.layers.Dense(64, activation='relu', input_shape=(784,)),
        keras.layers.Dense(64, activation='relu'),
        keras.layers.Dense(10, activation='softmax')
    ])
    model.compile(optimizer=tf.keras.optimizers.Adam(),
                  loss=tf.keras.losses.categorical_crossentropy,
                  metrics=[tf.keras.metrics.categorical_accuracy])
    return model

# Convert the Keras model to an Estimator
estimator = tf.keras.estimator.model_to_estimator(keras_model=build_model())

# Define the input function for training
def train_input_fn():
    pass  # return training data

# Define the input function for evaluation
def eval_input_fn():
    pass  # return evaluation data

# Train and evaluate the Estimator
tf.estimator.train_and_evaluate(estimator,
                                train_spec=tf.estimator.TrainSpec(train_input_fn),
                                eval_spec=tf.estimator.EvalSpec(eval_input_fn))
Posted on

梯度下降法介紹

梯度下降法

梯度下降法(英語:Gradient descent)是一個一階最佳化算法,通常也稱為最陡下降法,但是不該與近似積分的最陡下降法(英語:Method of steepest descent)混淆。 要使用梯度下降法找到一個函數的局部極小值,必須向函數上當前點對應梯度(或者是近似梯度)的反方向的規定步長距離點進行疊代搜索。如果相反地向梯度正方向疊代進行搜索,則會接近函數的局部極大值點;這個過程則被稱為梯度上升法。

既然在變量空間的某一點處,函數沿梯度方向具有最大的變化率,那麼在優化目標函數的時候,自然是沿著負梯度方向去減小函數值,以此達到我們的優化目標。
如何沿著負梯度方向減小函數值呢?既然梯度是偏導數的集合,如下:

同時梯度和偏導數都是向量,那麼參考向量運算法則,我們在每個變量軸上減小對應變量值即可,梯度下降法可以描述如下:

描述


甚麼是梯度消失

梯度是一種數學概念,用於描述一個函數的變化率。在機器學習中,我們會使用梯度下降法來最小化損失函數。

損失函數是用來衡量模型預測結果與實際結果之間的差異的函數。通過最小化損失函數,我們可以讓模型的預測結果越來越接近實際結果。

梯度下降法是一種基於梯度的最優化算法,它會不斷計算損失函數的梯度,並根據梯度的大小和方向來更新模型的參數。當梯度越大,就意味著模型的預測結果與實際結果的差異越大,所以需要更大的步長來進行更新。當梯度越小,就意味著模型的預測結果與實際結果的差異越小,所以可以使用較小的步長來進行更新。

隨著層數的增加,梯度有可能會越來越小。這是因為在深度神經網路中,每個層的輸入都是前一層的輸出,因此如果前一層的輸出有變化,那麼這層的輸入也會有變化。如果前一層的輸出有很大的變化,那麼這層的輸入也有可能有很大的變化,導致梯度變小。而如果前一層的輸出沒有太大變化,那麼這層的輸入也不會有太大變化,梯度就不會變小。

當梯度變得非常小時,梯度下降法就無法有效地更新模型的參數、有可能陷入局部最小值,使得模型無法有效地學習。

這就是深度神經網路中的梯度消失問題。殘差網路就是為了解決這個問題而設計的。這是因為梯度下降法是通過梯度的大小和方向來決定步長的,如果梯度變得非常小,那麼步長也會變得非常小,導致更新參數的幅度非常小。

這篇文章對梯度下降法有很詳細的解釋: https://ithelp.ithome.com.tw/articles/10273302
更多關於CNN殘差學習介紹: https://zhuanlan.zhihu.com/p/31852747

Posted on

物體偵測技術介紹

取得圖片中可能的目標的位置資訊

要讓模型吐出圖片中目標的座標位置資訊,常用的方法是使用目標檢測 (object detection) 的模型,這些模型通常可以同時預測目標的類別 (class) 和座標位置 (bounding box)。

常用的目標檢測模型有 YOLO (You Only Look Once)、SSD (Single Shot MultiBox Detector) 以及 Faster R-CNN。在 TensorFlow 中,可以使用 TensorFlow Object Detection API 來訓練和使用這些模型。

訓練模型時需要給予圖片和相對應的座標位置(Annotation), 訓練好之後, 就可以得到模型預測目標的座標位置.

如果你要找的目標是特定類型, 也可以使用像 RetinaNet, FPN 等特定目標檢測模型, 它們通常都能很好的偵測目標並輸出相對應的座標位置資訊。

常見的模型介紹

常見的物體偵測模型,包括:

  • Single Shot MultiBox Detector (SSD):這是一個快速的目標檢測模型,可以在計算資源有限的環境中運行。
  • You Only Look Once (YOLO):這也是一個快速的目標檢測模型,可以在實時應用中使用。
  • Faster R-CNN:這是一個經典的目標檢測模型,在准確性和效率之間取得了很好的平衡。
  • RetinaNet:這是一個新的目標檢測模型,在准確性和效率上都有很好的表現。

這些模型都是廣泛使用的,可以根據您的需求和硬體資源選擇適當的模型。

區域建議網絡(Region Proposal Network, RPN) 是一種卷積神經網絡,它的主要功能是在輸入圖像中產生候選的目標區域。這些候選區域之後可以被傳入一個分類器來預測目標的類別和座標位置。

區域建議網絡通常由兩個部分組成: 一個卷積層,負責對輸入圖像進行特徵提取;一個全卷積層,負責對每個位置產生候選區域。

Faster R-CNN介紹

Faster R-CNN 是一種目標檢測模型,其基礎概念為使用卷積神經網絡(CNN)的特徵提取器 (feature extractor) 和基於區域的建議網絡 (region-based proposal network) 來預測目標的類別和座標位置。

Faster R-CNN 的架構由三個部分組成:

  • 一個區域建議網絡 (RPN) : 這部分主要負責對圖像產生區域建議,並且預測每個建議區域中是否包含目標。
  • 一個卷積神經網絡特徵提取器 (CNN feature extractor) :這部分主要負責對輸入圖像進行預處理,提取出高維度的特徵。
  • 一個分類器 (classifier) : 這部分主要負責對建議區域進行分類,並預測每個區域中目標的類別和座標位置。

為了能夠得到目標的座標位置資訊,Faster R-CNN 首先使用 RPN 來產生區域建議,並且預測每個建議區域中是否包含目標。接著,將這些建議區域輸入分類器,並預測每個區域中目標的類別和座標位置。

RPN原理

RPN 通常使用一種稱為 anchor 的技巧,設置預先定義好的候選區域 (如長方形),在輸入圖像中做卷積運算,預測每個 anchor 是否包含目標,並且預測每個目標的座標位置。

在 RPN 中使用 anchor 的方法是:

  • 對於輸入圖像中的每個位置,預先放置一些 anchor
  • 對於每個 anchor,預測它是否包含目標,並且預測目標的座標位置。

Anchor 技巧的目的在於可以減少目標檢測的計算量,因為只需要在少數候選區域中進行目標檢測,而不是在整張圖像中進行目標檢測。 並且因為anchor的設定, 更能更好的適用不同的目標。

下圖為一個檢測流程的範例:

簡單範例

以下是使用 TensorFlow Object Detection API 訓練和使用 Faster R-CNN 的示例代碼:

# 安裝 TensorFlow Object Detection API
pip install tensorflow-object-detection-api
# 引入需要的庫
import tensorflow as tf
from object_detection import model_hparams
from object_detection import model_lib

# 設置訓練參數
hparams = model_hparams.create_hparams()
hparams.num_classes = NUM_CLASSES  # 設置類別數量
hparams.batch_size = BATCH_SIZE  # 設置批量大小

# 設置訓練路徑
train_dir = 'path/to/train'

# 建立模型
model_fn = model_lib.create_faster_rcnn_model_fn(hparams)

# 創建訓練配置
session_config = tf.ConfigProto(allow_soft_placement=True)

# 啟動訓練
tf.estimator.train_and_evaluate(
model_fn,
train_input_fn,
eval_input_fn,
train_dir,
session_config=session_config
)
Posted on

Dense全連接層介紹

Tensorflow的全連接層

對Tensorflow而言,全連接層的類別為: tf.keras.layers.Dense
相關介紹: https://www.tensorflow.org/api_docs/python/tf/keras/layers/Dense

甚麼是全連接層

在 Dense 層中,每個輸入都會對每個輸出進行綜合計算,得到一個輸出值。這個綜合計算包括了對輸入和前一層輸出的矩陣乘法,以及對輸入和輸出的加權和。計算過程中,對輸入的乘法是通過對每個輸入的加權,得到的权重矩陣就是Dense層的權重矩陣。這些权重矩陣就是Dense層所學習的模型參數。

這層的經典用途就是進行分類,把特徵轉成概率,進而做出預測, 可以實現多種不同的操作, 如全連接,激活函數等,是基礎網路結構的基礎。

Dense層中通常還會有一個偏差項, 每個輸出都有一個偏差項, 該項是Dense層的一部分參數, 也會在學習過程中更新。

最后 Dense層 還會有一個激活函數, 用於對綜合計算的結果進行非線性轉換, 增加網絡的非線性表達能力。

全連接層的優點

在多數的深度學習模型中,輸出層常常使用 Dense 層,這是因為 Dense 層具有下列優點:

1. Dense層可以實現任意的非線性轉換,而輸出層需要進行非線性轉換,因為在大多數情況下,輸出的預測結果需要進行非線性轉換。

2. Dense層具有較高的計算效率,對於輸出層來說,需要進行大量的運算,而 Dense 層可以高效地完成這些運算。

3. Dense層 可以通過學習來自動調整權重和偏差,而且可以將輸入特徵在輸出層進行組合, 獲得高維度且有用的輸出.

因此, Dense層 是輸出層的選擇之一,並且被廣泛使用。

簡單的圖片介紹

下圖第二和第三層,與全部前一層相連接,便為Dense層

我們可以單純使用Dense來建構一個MNIST的分類器,其格式如下:

import tensorflow as tf
# Import TensorFlow Datasets
import tensorflow_datasets as tfds
tfds.disable_progress_bar()

# Helper libraries
import math
import numpy as np
import matplotlib.pyplot as plt
import logging
logger = tf.get_logger()
logger.setLevel(logging.ERROR)
dataset, metadata = tfds.load('fashion_mnist', as_supervised=True, with_info=True)
train_dataset, test_dataset = dataset['train'], dataset['test']
class_names = metadata.features['label'].names
print("Class names: {}".format(class_names))
num_train_examples = metadata.splits['train'].num_examples
num_test_examples = metadata.splits['test'].num_examples
print("Number of training examples: {}".format(num_train_examples))
print("Number of test examples:     {}".format(num_test_examples))
def normalize(images, labels):
  images = tf.cast(images, tf.float32)
  images /= 255
  return images, labels

# The map function applies the normalize function to each element in the train
# and test datasets
train_dataset =  train_dataset.map(normalize)
test_dataset  =  test_dataset.map(normalize)

# The first time you use the dataset, the images will be loaded from disk
# Caching will keep them in memory, making training faster
train_dataset =  train_dataset.cache()
test_dataset  =  test_dataset.cache()
# Take a single image, and remove the color dimension by reshaping
for image, label in test_dataset.take(1):
  break
image = image.numpy().reshape((28,28))

model = tf.keras.Sequential([
    tf.keras.layers.Flatten(input_shape=(28, 28, 1)),
    tf.keras.layers.Dense(128, activation=tf.nn.relu),
    tf.keras.layers.Dense(10, activation=tf.nn.softmax)
])
model.compile(optimizer='adam',
              loss=tf.keras.losses.SparseCategoricalCrossentropy(),
              metrics=['accuracy'])
BATCH_SIZE = 32
train_dataset = train_dataset.cache().repeat().shuffle(num_train_examples).batch(BATCH_SIZE)
test_dataset = test_dataset.cache().batch(BATCH_SIZE)
model.fit(train_dataset, epochs=5, steps_per_epoch=math.ceil(num_train_examples/BATCH_SIZE))

test_loss, test_accuracy = model.evaluate(test_dataset, steps=math.ceil(num_test_examples/32))
print('Accuracy on test dataset:', test_accuracy)

for test_images, test_labels in test_dataset.take(1):
  test_images = test_images.numpy()
  test_labels = test_labels.numpy()
  predictions = model.predict(test_images)
np.argmax(predictions[0])

實踐概念

Dense層是使用線性代數裡的矩陣運算概念實現的。

具體地說,Dense層的計算過程包括了對輸入和前一層輸出的矩陣乘法,以及對輸入和輸出的加權和。 這個綜合計算可以用下面這個矩陣的形式來表示

y = W*x + b

其中 y 是 Dense 層的輸出,x 是輸入,W 是 Dense 層的權重矩陣, b 是偏差項。

這個運算滿足矩陣乘法的性質, W 可以看成是一個 m x n 的矩陣, x 是一個 n x 1 的向量, 這樣 y 就是一個 m x 1 的向量,就是輸出。這種運算方式可以幫助網絡在運算過程中組合特徵,輸出高維度且有用的特徵。

Posted on

如何從預先訓練的模型中提取特徵

預先訓練的模型中提取特徵的一種常見方法是使用模型的中間層。例如,如果使用卷積神經網絡 (CNN) 來預訓練圖像識別模型,則可以使用 CNN 的某些中間層(如卷積層或池化層)來提取圖像的特徵。

另外,您可以將整個預先訓練的模型看作是一個特徵提取器。 一種方法是將輸入數據丟入預先訓練的模型中,然後使用模型的最後一層輸出 (通常是分類層) 作為特徵。

最後,您還可以使用深度學習框架中內置的函數(如 Keras 中的 model.predict())來提取特徵。

在使用預先訓練的模型提取特徵時,重要的是要注意模型是否符合您的任務,並且選擇適當的層和方法。

Posted on

二元分類器 (binary classification) 介紹

甚麼是二元分類器

二元分類 (binary classification) 是一種機器學習中常見的任務,其目的是從兩個不同類別中將每個數據樣本歸類為其中之一。這種分類方式只有兩個類別,因此其結果是二元的。例如,對於圖像分類問題,二元分類可能用於識別猫和狗的圖像,或者用於識別垃圾郵件和非垃圾郵件的電子郵件。

在二元分類中,我們通常使用一些算法來建立一個模型,如 logistic regression, decision tree, SVM, Random forest, neural network等 來預測每個輸入數據樣本屬於哪個類別。 當我們對新數據進行預測時,該模型將輸出預測類別 (0 或 1)。

在訓練階段,通常需要提供已經標註好類別的數據來訓練模型。並在測試階段使用該模型來預測新的數據的類別,並使用常見的度量指標來評估模型的效果如精確度, AUC-ROC, F1 score等

如果您需要分類多於兩個類別的數據,則需要使用多元分類 (multiclass classification)。

和多元分類器的不同

在 TensorFlow 中,實現二元分類和多元分類器主要有兩個不同之處:

  • 損失函數: 二元分類器通常使用二元交叉熵 (binary cross-entropy) 作為損失函數。而多元分類器則常使用交叉熵 (cross-entropy) 作為損失函數。
  • 輸出層的激活函數: 二元分類器的輸出層通常使用 sigmoid 激活函數。而多元分類器的輸出層則通常使用 softmax 激活函數。

除了上述兩點的不同之外,實現二元分類器和多元分類器在 TensorFlow 中沒有太大差別。
如果使用Keras, 可以直接使用其封裝好的model,
例如:
keras.models.Sequential() 中的binary_crossentropy適用於二元分類問題

model.compile(loss='binary_crossentropy',optimizer='adam',metrics=['accuracy']) 

而 categorical_crossentropy則適用於多元分類問題.

model.compile(loss='categorical_crossentropy',optimizer='adam',metrics=['accuracy']) 

但是要注意在訓練和測試階段,多元分類需要對每個類別進行單熱編碼 ( one-hot encoding)。在 TensorFlow 中,可以使用 tf.keras.utils.to_categorical() 函數將標籤轉換為 one-hot 編碼。

優缺點比較

使用二元分類器和使用多元分類器並將其限制為兩個類別的方式之間有以下優缺點:

優點:

  • 使用二元分類器可以較為簡單地對兩個類別進行分類,而無需考慮額外的類別。
  • 如果模型使用二元交叉熵作為損失函數,則可以較容易地解釋分類結果,因為輸出層輸出的值是概率值,可以用來表示一個類別的可能性。

缺點:

  • 如果類別數量超過兩個,則無法使用二元分類器。
  • 將多元分類器限制為兩個類別可能會使模型的複雜度增加,因為必須考慮額外的類別,即使這些類別不需要分類。
  • 如果將多元分類器限制為兩個類別,則無法充分利用模型的能力,可能無法在更大范圍內解決問題。
  • 在某些情況下,使用二元分類器可能不能提供足夠的信息來解釋分類結果,因為只提供了兩個類別之間的信息。

總之, 如果您有兩個類別並且需要將數據標記為其中之一,則使用二元分類器可能是最佳選擇。如果類別數量超過兩個或者需要更多的信息來解釋分類結果,則使用多元分類器可能是更佳選擇。

Posted on

Tensorflow裡ResNet(殘差網路)的介紹

殘差網路ResNet

殘差網路(Residual Network,簡稱 ResNet)是一種深度卷積神經網路,它被設計用來解決深度神經網路中的梯度消失問題。

在深度神經網路中,隨著層數的增加,梯度有可能會越來越小,導致模型無法有效地學習。殘差網路通過在每一層中引入一個「殘差块」來解決這個問題。殘差块包含兩個卷積層和一個殘差路徑,殘差路徑將輸入數據直接加到輸出數據上。這樣,當殘差块的輸出數據與輸入數據相加時,梯度就不會被消失。

這邊是別人的文章介紹: https://ithelp.ithome.com.tw/articles/10264843?sc=hot

與Conv2D關鍵的不同

Conv2D就是一個提取圖片裡的特徵的方式,他是可以讓圖片也可以丟進Dense去找到共通特徵的一個關鍵,但是,Conv2D一定會需要與其他像是池化層、全連接層、輸出層等一起使用。
而殘差網路就是某個對ML非常熟的神人,所使用像是卷積層、池化層、連接層等,可有效降低梯度消失的問題的一個【已經建立好的模型】
例如: 以下為一個原始的TF模型的建立方式

model = tf.keras.Sequential([
    tf.keras.layers.Rescaling(1./255),
    tf.keras.layers.Conv2D(32, 3, activation='relu'),
    tf.keras.layers.MaxPooling2D(),
    tf.keras.layers.Conv2D(32, 3, activation='relu'),
    tf.keras.layers.MaxPooling2D(),
    tf.keras.layers.Conv2D(32, 3, activation='relu'),
    tf.keras.layers.MaxPooling2D(),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(128, activation='relu'),
    tf.keras.layers.Dense(num_classes)
])

ResNet使用範例

而使用ResNet非常的簡單,就使用別人已建立好的ResNet就可以了,以下範例中的 ResNet 使用了 20 個 ResidualBlock,每個 ResidualBlock 中使用了 64 個濾波器,卷積核大小為 3×3,步長為 2。

import tensorflow as tf
from tensorflow.keras import layers

class ResidualBlock(layers.Layer):
    def __init__(self, filters, kernel_size, strides, use_projection=False):
        super(ResidualBlock, self).__init__()
        self.use_projection = use_projection
        self.conv1 = layers.Conv2D(filters, kernel_size, strides=strides, padding='same')
        self.bn1 = layers.BatchNormalization()
        self.relu = layers.ReLU()
        self.conv2 = layers.Conv2D(filters, kernel_size, strides=1, padding='same')
        self.bn2 = layers.BatchNormalization()
        if use_projection:
            self.projection = layers.Conv2D(filters, 1, strides=strides, padding='same')

    def call(self, inputs, training=False):
        x = self.conv1(inputs)
        x = self.bn1(x, training=training)
        x = self.relu(x)
        x = self.conv2(x)
        x = self.bn2(x, training=training)
        if self.use_projection:
            shortcut = self.projection(inputs)
        else:
            shortcut = inputs
        x += shortcut
        x = self.relu(x)
        return x

class ResNet(layers.Layer):
    def __init__(self, blocks, filters, kernel_size, strides):
        super(ResNet, self).__init__()
        self.conv = layers.Conv2D(filters, kernel_size, strides=strides, padding='same')
        self.bn = layers.BatchNormalization()
        self.relu = layers.ReLU()
        self.blocks = blocks
        self.res_blocks = [ResidualBlock(filters, kernel_size, strides) for _ in range(blocks)]

    def call(self, inputs, training=False):
        x = self.conv(inputs)
        x = self.bn(x, training=training)
        x = self.relu(x)
        for res_block in self.res_blocks:
            x = res_block(x, training=training)
        return x

inputs = tf.keras.Input(shape=(224, 224, 3))
resnet = ResNet(20, 64, 3, 2)(inputs)
outputs = layers.Dense(10, activation='softmax')(resnet)
model = tf.keras.Model(inputs, outputs)

官方介紹文件

V1版本: https://www.tensorflow.org/api_docs/python/tf/keras/applications/resnet
V2版本: https://www.tensorflow.org/api_docs/python/tf/keras/applications/resnet_v2

好多種ResNet,有甚麼差?

ResNet50, ResNet101, ResNet152 是 TensorFlow 中原始版本的 ResNet 模型,而 ResNet50V2, ResNet101V2, ResNet152V2 是 V2 版本的 ResNet 模型。以下是這些模型之間的主要區別:

  • 深度: ResNet50 的深度為 50 層,ResNet101 的深度為 101 層,ResNet152 的深度為 152 層,V2 版本的深度分別為 50 層,101 層和 152 層。
  • 架構: V2 版本的 ResNet 模型在原始版本的基礎上增加了許多改進,包括使用非常深的層 (bottleneck layer) 來減少參數數量,並在輸入層和輸出層之間使用高密度連接 (dense connection)。
  • 參數數量: V2版本的 ResNet 模型通常具有較少的參數數量,因為它們使用了更高效的架構。
  • 效能: V2版本的 ResNet 模型通常具有更好的效能,因為它們使用了更高效的架構和更少的參數。

總之, 如果要在效能和參數數量之間取得平衡, 使用 V2 版本的 ResNet 模型是個好選擇。
如果效能是優先考量,則可以使用原始版本的 ResNet 模型。

設定ResNet模型超參數

在建立殘差網路 ResNet 的模型時,有一些重要的超參數可以考慮調整,例如:

  • 卷積層數量 (num_blocks):通常來說,越多的卷積層能夠讓模型的表現更好,但也會使模型變得越大且訓練時間越長。因此可以根據實際的情況決定卷積層的數量。
  • 初始濾波器數量 (initial_filters):通常來說,使用較大的濾波器能夠讓模型的表現更好,但也會使模型變得越大且訓練時間越長。因此可以根據實際的情況決定初始濾波器的數量。
  • 激活函數 (activation):激活函數可以對輸入的數據施加非線性轉換,以便讓模型能夠學習更複雜的模式。常見的激活函數包括 ReLU、Sigmoid 和 tanh 等。
  • 優化器 (optimizer):優化器是用來更新模型參數的算法,通常會使用常見的優化器如 SGD、Adam 和 RMSprop 等。
  • 學習率 (learning rate):學習率決定了優化器更新參數的速度。如果學習率過大,則優化器可能會震蕩,無法有效地學習;如果學習率過小,則優化器可能會過慢,學習效率較低。因此可以根據實際的情況選擇合適的學習率。
  • 批次大小 (batch size):批次大小決定了每次更新參數時使用的數據數量。如果批次大小過大,則更新參數的速度會較快,但也有可能導致模型的表現變差;如果批次大小過小,則更新參數的速度會較慢,但也有可能會使模型的表現更好。因此可以根據實際的情況選擇合適的批次大小。
  • 訓練輪數 (epochs):訓練輪數決定了模型在訓練集上訓練的次數。如果訓練輪數過多,則模型有可能會對訓練集過擬合,導致在驗證集上的表現變差;如果訓練輪數過少,則模型可能無法充分學習到訓練集中的模式,導致整體的表現較差。因此可以根據實際的情況選擇合適的訓練輪數。
  • 正規化 (regularization):正規化是指在訓練過程中加入額外的限制,以防止模型過度擬合。常見的正規化方法包括 L1 正規化和 L2 正規化。
  • 丟棄率 (dropout rate):丟棄率是指在訓練過程中隨機丟棄一定比例的神經元,以防止模型過度擬合。
  • 濾波器數量 (filters):濾波器數量決定了每個卷積層使用的濾波器數量。通常來說,使用較多的濾波器能夠讓模型的表現更好,但也會使模型變得越大且訓練時間越長。因此可以根據實際的情況決定濾波器的數量。
  • 卷積層的濾波器大小 (filter size):卷積層的濾波器大小決定了每個卷積層使用的濾波器的大小。通常來說,使用較大的濾波器能夠讓模型的表現更好,但也會使模型變得越大且訓練時間越長。因此可以根據實際的情況決定濾波器的大小。

使用TunableResNet

GitHub位置: https://github.com/keras-team/keras-tuner
官方網站: https://keras.io/keras_tuner/

Posted on

TensorFlow 開發者認證計劃介紹

TensorFlow認證計劃課程

以下為介紹網頁
https://www.tensorflow.org/certificate
在這個網頁當中,他們推薦了幾個課程

而我選擇了Udacity的課程(因為免費),而且可以有中文字幕

必備知識

為了順利完成考試,應試者應該了解以下知識:

  • 機器學習和深度學習的基本原則
  • 在TensorFlow 2.x 中構建機器學習模型
  • 使用深度神經網絡和卷積神經網絡構建圖像識別算法、對象檢測算法、文本識別算法
  • 使用不同形狀和大小的真實圖像可視化圖像的捲積過程,了解計算機如何“觀察”信息、繪製損失和準確率圖
  • 探索防止過擬合的策略,包括增強和丟棄策略
  • 在TensorFlow 中使用神經網絡解決自然語言處理問題

認證考試使用的工具

PyCharm
因此應熟悉在PyCharm中撰寫Python程式、Debug及Compiler。
此為社區版連結: https://www.jetbrains.com/pycharm/download/#section=windows
若是仍有學生的email信箱,則可以免費申請專業版: https://www.jetbrains.com/community/education/#students

認證考試的內容

雖然我們不一定要去獲得認證,但是從認證考試範圍可以了解,要學習Tensorflow有那些東西是官方認為必備的知識,以下為官方的認證說明文件:
TF_Certificate_Candidate_Handbook

TensorFlow開發技能

  • 在PyCharm中寫程式Python的知識,解決Python問題,並編譯和執行Python程式。
  • 了解如何查找有關 TensorFlow API 的信息,包括如何查找指南和 API(tensorflow.org 上的參考資料)。
  • 知道如何從TensorFlow API中除錯、調查和解決錯誤訊息。
  • 知道如何在tensorflow.org 之外搜尋必要知識來解決在tensorflow遇到的問題
  • 知道如何使用TensorFlow建立ML模型,其中模型大小對正在解決的問題來說是合理的。
  • 知道如何儲存ML模型並檢查模型
  • 了解不同版本的Tensorflow的相容性差異

使用TensorFlow 2.x構建和訓練神經網路模型

  • 使用TensorFlow 2.x。
  • 使用TensorFlow構建、編譯和訓練機器學習(ML)模型。
  • 預處理資料,使其準備好在模型中使用。
  • 使用模型來預測結果。
  • 為二元分類 (binary classification) 構建和訓練模型
  • 為多元分類器建構和訓練模型
  • 繪製經過訓練的模型的損失和準確性。
  • 了解如何防止過度擬合,包括資料增強(augmentation)和dropout
  • 使用預先訓練的模型(轉移學習)。
  • 從預先訓練的模型中提取特徵。
  • 確保模型的輸入處於正確的形狀。
  • 確保您可以將測試資料與神經網路的輸入形狀匹配。
  • 確保您可以將神經網絡的輸出數據與測試數據的指定輸入形狀相匹配。
  • 瞭解資料的批次載入
  • 使用回撥來觸發訓練週期的結束
  • 使用不同的來源的資料集
  • 使用不同格式的資料集,包括CSV和JSON
  • 使用tf.data.datasets裡的資料集

影像分類

瞭解如何使用TensorFlow 2.x使用深度神經網路和卷積神經網路構建影象識別和物件檢測模型。 您需要知道如何:

  • 使用 Conv2D 和池化層定義卷積神經網絡。
  • 構建和訓練模型來處理真實世界的圖像數據集。
  • 了解如何使用卷積來改進您的神經網絡。
  • 使用不同形狀和大小的真實世界圖像。
  • 使用圖像增強來防止過度擬合。
  • 使用 ImageDataGenerator。
  • 了解 ImageDataGenerator 如何根據目錄結構標記圖像。

自然語言處理(NLP)

你需要了解如何使用神經網絡張量流來解決自然語言處理問題。

您需要知道如何:

  • 使用 TensorFlow 構建自然語言處理系統。
  • 準備要在 TensorFlow 模型中使用的文本。
  • 構建使用二元分類識別一段文本類別的模型
  • 構建使用多類分類識別一段文本類別的模型
  • 在您的 TensorFlow 模型中使用詞嵌入。
  • 在您的模型中使用 LSTM 對文本進行分類以進行二分類或多分類。
  • 將 RNN 和 GRU 層添加到您的模型中。
  • 在處理文本的模型中使用 RNNS、LSTM、GRU 和 CNN。
  • 在現有文本上訓練 LSTM 以生成文本(例如歌曲和詩歌)

時間序列、序列和預測

您需要瞭解如何在TensorFlow中解決時間序列和預測問題。 您需要知道如何:

  • 訓練、調整和使用時間序列、序列和預測模型。
  • 訓練模型來預測單變數和多變數時間序列的值。
  • 為時間序列學習準備資料。
  • 瞭解平均絕對誤差(MAE)以及如何將其用於評估序列模型的準確性。
  • 使用RNN和CNN進行時間序列、序列和預測模型。
  • 確定何時使用尾隨視窗與居中視窗。
  • 使用TensorFlow進行預測。
  • 準備功能和標籤。
  • 識別和補償序列偏差。
  • 動態調整時間序列、序列和預測模型的學習率。