在機器學習中,「模型」是一個具有「可學習」參數的函式,可將輸入對應至輸出。最佳參數是透過在資料上訓練模型而取得。訓練有素的模型將提供從輸入到所需輸出的精確對應。
在 TensorFlow.js 中,有兩種建立機器學習模型的方法
- 使用 Layers API,您可以使用「層」來建構模型。
- 使用 Core API 與較低層級的運算,例如
tf.matMul()
、tf.add()
等。
首先,我們將研究 Layers API,這是用於建構模型的較高層級 API。然後,我們將示範如何使用 Core API 建構相同的模型。
使用 Layers API 建立模型
有兩種使用 Layers API 建立模型的方法:「循序」模型和「函式」模型。接下來的兩節將更仔細地探討每種模型類型。
循序模型
最常見的模型類型是 Sequential
模型,它是層的線性堆疊。您可以將層的清單傳遞至 sequential()
函式,藉此建立 Sequential
模型
const model = tf.sequential({
layers: [
tf.layers.dense({inputShape: [784], units: 32, activation: 'relu'}),
tf.layers.dense({units: 10, activation: 'softmax'}),
]
});
或透過 add()
方法
const model = tf.sequential();
model.add(tf.layers.dense({inputShape: [784], units: 32, activation: 'relu'}));
model.add(tf.layers.dense({units: 10, activation: 'softmax'}));
重要事項:模型中的第一層需要
inputShape
。提供inputShape
時,請務必排除批次大小。例如,如果您計劃將形狀為[B, 784]
的張量饋送至模型,其中B
可以是任何批次大小,則在建立模型時,請將inputShape
指定為[784]
。
您可以透過 model.layers
存取模型的層,更具體而言,可以透過 model.inputLayers
和 model.outputLayers
存取。
函式模型
建立 LayersModel
的另一種方法是透過 tf.model()
函式。tf.model()
和 tf.sequential()
之間的主要區別在於,只要層沒有週期,tf.model()
就允許您建立層的任意圖形。
以下程式碼片段使用 tf.model()
API 定義與上述相同的模型
// Create an arbitrary graph of layers, by connecting them
// via the apply() method.
const input = tf.input({shape: [784]});
const dense1 = tf.layers.dense({units: 32, activation: 'relu'}).apply(input);
const dense2 = tf.layers.dense({units: 10, activation: 'softmax'}).apply(dense1);
const model = tf.model({inputs: input, outputs: dense2});
我們在每個層上呼叫 apply()
,以便將其連線到另一個層的輸出。apply()
在此案例中的結果是 SymbolicTensor
,其作用類似於 Tensor
,但沒有任何具體值。
請注意,與循序模型不同,我們透過 tf.input()
建立 SymbolicTensor
,而不是為第一層提供 inputShape
。
如果您將具體的 Tensor
傳遞至 apply()
,則 apply()
也可以提供您具體的 Tensor
const t = tf.tensor([-2, 1, 0, 5]);
const o = tf.layers.activation({activation: 'relu'}).apply(t);
o.print(); // [0, 1, 0, 5]
當在隔離狀態下測試層並查看其輸出時,這會很有用。
就像在循序模型中一樣,您可以透過 model.layers
存取模型的層,更具體而言,可以透過 model.inputLayers
和 model.outputLayers
存取。
驗證
循序模型和函式模型都是 LayersModel
類別的執行個體。使用 LayersModel
的主要好處之一是驗證:它會強制您指定輸入形狀,並在稍後使用它來驗證您的輸入。LayersModel
也會在資料流經層時執行自動形狀推斷。預先知道形狀可讓模型自動建立其參數,並告訴您兩個連續層是否彼此不相容。
模型摘要
呼叫 model.summary()
以列印模型的實用摘要,其中包括
- 模型中所有層的名稱和類型。
- 每個層的輸出形狀。
- 每個層的權重參數數量。
- 如果模型具有一般拓撲 (如下所述),則每個層接收的輸入
- 模型的可訓練和非可訓練參數總數。
對於我們在上面定義的模型,我們在主控台上取得下列輸出
層 (類型) | 輸出形狀 | Param # |
dense_Dense1 (Dense) | [null,32] | 25120 |
dense_Dense2 (Dense) | [null,10] | 330 |
總參數:25450 可訓練參數:25450 非可訓練參數:0 |
請注意層輸出形狀中的 null
值:提醒您模型預期輸入具有批次大小作為最外層維度,在此案例中,由於 null
值,批次大小可以是彈性的。
序列化
與較低層級 API 相比,使用 LayersModel
的主要好處之一是能夠儲存和載入模型。LayersModel
知道
- 模型的架構,讓您能夠重新建立模型。
- 模型的權重
- 訓練組態 (損失、最佳化工具、指標)。
- 最佳化工具的狀態,讓您能夠繼續訓練。
儲存或載入模型只需要 1 行程式碼
const saveResult = await model.save('localstorage://my-model-1');
const model = await tf.loadLayersModel('localstorage://my-model-1');
上述範例會將模型儲存至瀏覽器中的本機儲存空間。請參閱 model.save() 文件
和儲存和載入指南,以瞭解如何儲存至不同的媒介 (例如檔案儲存空間、IndexedDB
、觸發瀏覽器下載等)。
自訂層
層是模型的建構區塊。如果您的模型正在執行自訂計算,您可以定義自訂層,使其與其餘層良好互動。以下我們定義一個自訂層,計算平方和
class SquaredSumLayer extends tf.layers.Layer {
constructor() {
super({});
}
// In this case, the output is a scalar.
computeOutputShape(inputShape) { return []; }
// call() is where we do the computation.
call(input, kwargs) { return input.square().sum();}
// Every layer needs a unique name.
getClassName() { return 'SquaredSum'; }
}
為了進行測試,我們可以使用具體張量呼叫 apply()
方法
const t = tf.tensor([-2, 1, 0, 5]);
const o = new SquaredSumLayer().apply(t);
o.print(); // prints 30
重要事項:如果您新增自訂層,您將失去序列化模型的能力。
使用 Core API 建立模型
在本指南的開頭,我們提到在 TensorFlow.js 中有兩種建立機器學習模型的方法。
一般經驗法則是始終先嘗試使用 Layers API,因為它是以廣泛採用的 Keras API 為模型,後者遵循最佳實務並降低認知負荷。Layers API 也提供各種現成的解決方案,例如權重初始化、模型序列化、監控訓練、可攜性和安全檢查。
在下列情況下,您可能會想要使用 Core API
- 您需要最大的彈性或控制權。
- 您不需要序列化,或可以實作自己的序列化邏輯。
Core API 中的模型只是接受一個或多個 Tensors
並傳回 Tensor
的函式。使用 Core API 寫入的相同模型如下所示
// The weights and biases for the two dense layers.
const w1 = tf.variable(tf.randomNormal([784, 32]));
const b1 = tf.variable(tf.randomNormal([32]));
const w2 = tf.variable(tf.randomNormal([32, 10]));
const b2 = tf.variable(tf.randomNormal([10]));
function model(x) {
return x.matMul(w1).add(b1).relu().matMul(w2).add(b2).softmax();
}
請注意,在 Core API 中,我們負責建立和初始化模型的權重。每個權重都由 Variable
支援,這向 TensorFlow.js 發出訊號,表示這些張量是可學習的。您可以使用 tf.variable() 並傳入現有的 Tensor
來建立 Variable
。
在本指南中,您已熟悉使用 Layers 和 Core API 建立模型的不同方法。接下來,請參閱訓練模型指南,以瞭解如何訓練模型。