tensorflow 模型的儲存與加載
代碼
# -*- coding: utf-8 -*-
"""
Created on 2020/11/20 9:41
@Author: CY
@email: [email protected]
"""
# pip install -q pyyaml h5py # 以 HDF5 格式儲存模型所必須
import os
import tensorflow as tf
from tensorflow import keras
print(tf.version.VERSION)
print("# 1 資料集")
(train_images, train_labels), (test_images, test_labels) = tf.keras.datasets.mnist.load_data()
train_labels = train_labels[:1000]
test_labels = test_labels[:1000]
train_images = train_images[:1000].reshape(-1, 28 * 28) / 255.0
test_images = test_images[:1000].reshape(-1, 28 * 28) / 255.0
print("# 2 模型")
# 定義一個簡單的序列模型
def create_model():
model = tf.keras.models.Sequential([
keras.layers.Dense(512, activation='relu', input_shape=(784,)),
keras.layers.Dropout(0.2),
keras.layers.Dense(10)
])
model.compile(optimizer='adam',
loss=tf.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=['accuracy'])
return model
# 建立一個基本的模型執行個體
model = create_model()
# 顯示模型的結構
model.summary()
print("#3. 在訓練期間儲存模型(以 checkpoints 形式儲存)")
# 您可以使用訓練好的模型而無需從頭開始重新訓練,或在您打斷的地方開始訓練,以防止訓練過程沒有儲存。
# tf.keras.callbacks.ModelCheckpoint 允許在訓練的過程中和結束時回調儲存的模型。
# Checkpoint 回調用法
# 建立一個隻在訓練期間儲存權重的 tf.keras.callbacks.ModelCheckpoint 回調:
checkpoint_path = "tmp/training_1/cp.ckpt"
checkpoint_dir = os.path.dirname(checkpoint_path)
# 建立一個儲存模型權重的回調
cp_callback = tf.keras.callbacks.ModelCheckpoint(filepath=checkpoint_path,
save_weights_only=True,
verbose=1)
# 使用新的回調訓練模型
model.fit(train_images,
train_labels,
epochs=10,
validation_data=(test_images, test_labels),
callbacks=[cp_callback]) # 通過回調訓練
# 這可能會生成與儲存優化程式狀态相關的警告。
# 這些警告(以及整個筆記本中的類似警告)
# 是防止過時使用,可以忽略。
print("#4 建立一個未訓練的模型")
# 建立一個新的未經訓練的模型。僅恢複模型的權重時,必須具有與原始模型具有相同網絡結構的模型。
# 由于模型具有相同的結構,您可以共享權重,盡管它是模型的不同執行個體。
# 現在重建一個新的未經訓練的模型,并在測試集上進行評估。未經訓練的模型将在機會水準(chance levels)上執行(準确度約為10%):
# 建立一個基本模型執行個體
model = create_model()
# 評估模型
loss, acc = model.evaluate(test_images, test_labels, verbose=2)
print("Untrained model, accuracy: {:5.2f}%".format(100 * acc))
print("#4. 加載權重...")
# 加載權重
model.load_weights(checkpoint_path)
# 重新評估模型
loss, acc = model.evaluate(test_images, test_labels, verbose=2)
print("Restored model, accuracy: {:5.2f}%".format(100 * acc))
# checkpoint 回調選項
## 為 checkpoint 提供唯一名稱并調整 checkpoint 頻率。
## 訓練一個新模型,每五個 epochs 儲存一次唯一命名的 checkpoint :
# 在檔案名中包含 epoch (使用 `str.format`)
checkpoint_path = "tmp/training_2/cp-{epoch:04d}.ckpt"
checkpoint_dir = os.path.dirname(checkpoint_path)
# 建立一個回調,每 5 個 epochs 儲存模型的權重
cp_callback = tf.keras.callbacks.ModelCheckpoint(
filepath=checkpoint_path,
verbose=1,
save_weights_only=True,
period=5)
# 建立一個新的模型執行個體
model = create_model()
# 使用 `checkpoint_path` 格式儲存權重
model.save_weights(checkpoint_path.format(epoch=0))
# 使用新的回調訓練模型
model.fit(train_images,
train_labels,
epochs=50,
callbacks=[cp_callback],
validation_data=(test_images, test_labels),
verbose=0)
## 預設的 tensorflow 格式僅儲存最近的5個 checkpoint 。
## 如果要進行測試,請重置模型并加載最新的 checkpoint :
latest = tf.train.latest_checkpoint(checkpoint_dir)
# 建立一個新的模型執行個體
model = create_model()
# 加載以前儲存的權重
model.load_weights(latest)
# 重新評估模型
loss, acc = model.evaluate(test_images, test_labels, verbose=2)
print("Restored model, accuracy: {:5.2f}%".format(100 * acc))
## 檔案内容:
#### 代碼将權重存儲到 checkpoint—— 格式化檔案的集合中,這些檔案僅包含二進制格式的訓練權重
#### Checkpoints 包含
######## 一個或多個包含模型權重的分片。
######## 索引檔案,訓示哪些權重存儲在哪個分片中。
### 如果你隻在一台機器上訓練一個模型,你将有一個帶有字尾的碎片: .data-00000-of-00001
print("# 5.手動儲存權重")
# 使用 Model.save_weights 方法手動儲存它們
# 預設情況下, tf.keras 和 save_weights 特别使用 TensorFlow checkpoints 格式 .ckpt 擴充名和 ( 儲存在 HDF5 擴充名為 .h5 儲存并序列化模型 ):
# 儲存權重
model.save_weights('./tmp/checkpoints/my_checkpoint')
# 建立模型執行個體
model = create_model()
# 恢複權重
model.load_weights('./tmp/checkpoints/my_checkpoint')
# 評估模型
loss, acc = model.evaluate(test_images, test_labels, verbose=2)
print("Restored model, accuracy: {:5.2f}%".format(100 * acc))
print("#6 儲存整個模型")
# 調用 model.save 将儲存模型的結構,權重和訓練配置儲存在單個檔案/檔案夾中。
# 這可以讓您導出模型,以便在不通路原始 Python 代碼*的情況下使用它。
# 因為優化器狀态(optimizer-state)已經恢複,您可以從中斷的位置恢複訓練。
# 整個模型可以以兩種不同的檔案格式(SavedModel 和 HDF5)進行儲存。
# 需要注意的是 TensorFlow 的 SavedModel 格式是 TF2.x. 中的預設檔案格式。
# 但是,模型仍可以以 HDF5 格式儲存。下面介紹了以兩種檔案格式儲存整個模型的更多詳細資訊。
# 儲存完整模型會非常有用——您可以在 TensorFlow.js(Saved Model, HDF5)加載它們,
# 然後在 web 浏覽器中訓練和運作它們,或者使用 TensorFlow Lite 将它們轉換為在移動裝置上運作(Saved Model, HDF5)
# *自定義對象(例如,子類化模型或層)在儲存和加載時需要特别注意。請參閱下面的儲存自定義對象部分
# SavedModel 格式
## SavedModel 格式是序列化模型的另一種方法。以這種格式儲存的模型,可以使用 tf.keras.models.load_model 還原,
## 并且模型與 TensorFlow Serving 相容。SavedModel 指南詳細介紹了如何提供/檢查 SavedModel。以下部分說明了儲存和還原模型的步驟。
# 建立并訓練一個新的模型執行個體。
model = create_model()
model.fit(train_images, train_labels, epochs=5)
# 将整個模型另存為 SavedModel。
# !mkdir -p saved_model
# SavedModel 格式是一個包含 protobuf 二進制檔案和 Tensorflow 檢查點(checkpoint)的目錄
model.save('tmp/saved_model/my_model')
print("#7. 從儲存的模型重新加載新的 Keras 模型")
new_model = tf.keras.models.load_model('tmp/saved_model/my_model')
# 檢查其架構
new_model.summary()
# 評估還原的模型
loss, acc = new_model.evaluate(test_images, test_labels, verbose=2)
print('Restored model, accuracy: {:5.2f}%'.format(100*acc))
print(new_model.predict(test_images).shape)
print("#8 使用HDF5 格式 儲存 模型 恢複模型")
# 建立并訓練一個新的模型執行個體
model = create_model()
model.fit(train_images, train_labels, epochs=5)
# 将整個模型儲存為 HDF5 檔案。
# '.h5' 擴充名訓示應将模型儲存到 HDF5。
model.save('tmp/my_model.h5')
# 重新建立完全相同的模型,包括其權重和優化程式
new_model = tf.keras.models.load_model('tmp/my_model.h5')
# 顯示模型的結構
new_model.summary()