可以在訓(xùn)練期間和訓(xùn)練后保存模型進(jìn)度刻获。 這意味著模型可以從中斷的地方恢復(fù)蜀涨,并避免長時(shí)間的訓(xùn)練。 保存也意味著您可以共享您的模型将鸵,而其他人可以重新創(chuàng)建您的工作勉盅。 在發(fā)布研究模型和技術(shù)時(shí),大多數(shù)機(jī)器學(xué)習(xí)從業(yè)者分享:
- 用于創(chuàng)建模型的代碼
- 模型的訓(xùn)練權(quán)重或參數(shù)
共享此數(shù)據(jù)有助于其他人了解模型的工作原理顶掉,并使用新數(shù)據(jù)自行嘗試草娜。
注意:小心不受信任的代碼 - TensorFlow模型是代碼。 有關(guān)詳細(xì)信息痒筒,請(qǐng)參閱安全使用TensorFlow宰闰。
選項(xiàng)
保存TensorFlow模型有多種方法 - 取決于您使用的API茬贵。 本指南使用tf.keras,一個(gè)高級(jí)API移袍,用于在TensorFlow中構(gòu)建和訓(xùn)練模型解藻。 有關(guān)其他方法,請(qǐng)參閱TensorFlow保存和還原指南或保存在急切中葡盗。
安裝
安裝和引用
安裝和導(dǎo)入TensorFlow和依賴項(xiàng)螟左,有下面兩種方式:
- 命令行:pip install -q h5py pyyaml
- 在Anaconda Navigator中安裝;
下載樣本數(shù)據(jù)集
from __future__ import absolute_import, division, print_function
import os
import tensorflow as tf
from tensorflow import keras
tf.__version__
'1.11.0'
(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
定義模型
讓我們構(gòu)建一個(gè)簡單的模型觅够,我們將用它來演示保存和加載權(quán)重胶背。
# Returns a short sequential model
def create_model():
model = tf.keras.models.Sequential([
keras.layers.Dense(512, activation=tf.nn.relu, input_shape=(784,)),
keras.layers.Dropout(0.2),
keras.layers.Dense(10, activation=tf.nn.softmax)
])
model.compile(optimizer=tf.keras.optimizers.Adam(),
loss=tf.keras.losses.sparse_categorical_crossentropy,
metrics=['accuracy'])
return model
# Create a basic model instance
model = create_model()
model.summary()
在訓(xùn)練期間保存檢查點(diǎn)
主要用例是在訓(xùn)練期間和訓(xùn)練結(jié)束時(shí)自動(dòng)保存檢查點(diǎn)。 通過這種方式喘先,您可以使用訓(xùn)練有素的模型钳吟,而無需重新訓(xùn)練,或者在您離開的地方接受訓(xùn)練 - 以防止訓(xùn)練過程中斷窘拯。
tf.keras.callbacks.ModelCheckpoint是執(zhí)行此任務(wù)的回調(diào)红且。 回調(diào)需要幾個(gè)參數(shù)來配置檢查點(diǎn)。
檢查點(diǎn)回調(diào)使用情況
訓(xùn)練模型并將模型傳遞給ModelCheckpoint:
checkpoint_path = "training_1/cp.ckpt"
checkpoint_dir = os.path.dirname(checkpoint_path)
# Create checkpoint callback
cp_callback = tf.keras.callbacks.ModelCheckpoint(checkpoint_path,
save_weights_only=True,
verbose=1)
model = create_model()
model.fit(train_images, train_labels, epochs = 10,
validation_data = (test_images,test_labels),
callbacks = [cp_callback]) # pass callback to training
這將創(chuàng)建一個(gè)TensorFlow檢查點(diǎn)文件集合涤姊,這些文件在每個(gè)時(shí)期結(jié)束時(shí)更新:
!ls {checkpoint_dir}
checkpoint cp.ckpt.data-00000-of-00001 cp.ckpt.index
創(chuàng)建一個(gè)新的未經(jīng)訓(xùn)練的模型暇番。 僅從權(quán)重還原模型時(shí),必須具有與原始模型具有相同體系結(jié)構(gòu)的模型砂轻。 由于它是相同的模型架構(gòu)奔誓,我們可以共享權(quán)重,盡管它是模型的不同實(shí)例搔涝。
現(xiàn)在重建一個(gè)新的未經(jīng)訓(xùn)練的模型厨喂,并在測(cè)試集上進(jìn)行評(píng)估。 未經(jīng)訓(xùn)練的模型將在偶然水平上執(zhí)行(準(zhǔn)確度約為10%):
model = create_model()
loss, acc = model.evaluate(test_images, test_labels)
print("Untrained model, accuracy: {:5.2f}%".format(100*acc))
然后從檢查點(diǎn)加載權(quán)重庄呈,并重新評(píng)估:
model.load_weights(checkpoint_path)
loss,acc = model.evaluate(test_images, test_labels)
print("Restored model, accuracy: {:5.2f}%".format(100*acc))
1000/1000 [==============================] - 0s 40us/step
Restored model, accuracy: 87.60%
檢查點(diǎn)回調(diào)選項(xiàng)
回調(diào)提供了幾個(gè)選項(xiàng)蜕煌,可以為生成的檢查點(diǎn)提供唯一的名稱,并調(diào)整檢查點(diǎn)頻率诬留。
訓(xùn)練一個(gè)新模型斜纪,每5個(gè)時(shí)期保存一次唯一命名的檢查點(diǎn):
# include the epoch in the file name. (uses `str.format`)
checkpoint_path = "training_2/cp-{epoch:04d}.ckpt"
checkpoint_dir = os.path.dirname(checkpoint_path)
cp_callback = tf.keras.callbacks.ModelCheckpoint(
checkpoint_path, verbose=1, save_weights_only=True,
# Save weights, every 5-epochs.
period=5)
model = create_model()
model.fit(train_images, train_labels,
epochs = 50, callbacks = [cp_callback],
validation_data = (test_images,test_labels),
verbose=0)
現(xiàn)在,查看生成的檢查點(diǎn)并選擇最新的檢查點(diǎn):
! ls {checkpoint_dir}
checkpoint cp-0030.ckpt.data-00000-of-00001
cp-0005.ckpt.data-00000-of-00001 cp-0030.ckpt.index
cp-0005.ckpt.index cp-0035.ckpt.data-00000-of-00001
cp-0010.ckpt.data-00000-of-00001 cp-0035.ckpt.index
cp-0010.ckpt.index cp-0040.ckpt.data-00000-of-00001
cp-0015.ckpt.data-00000-of-00001 cp-0040.ckpt.index
cp-0015.ckpt.index cp-0045.ckpt.data-00000-of-00001
cp-0020.ckpt.data-00000-of-00001 cp-0045.ckpt.index
cp-0020.ckpt.index cp-0050.ckpt.data-00000-of-00001
cp-0025.ckpt.data-00000-of-00001 cp-0050.ckpt.index
cp-0025.ckpt.index
latest = tf.train.latest_checkpoint(checkpoint_dir)
latest
'training_2/cp-0050.ckpt'
注意:默認(rèn)的tensorflow格式僅保存最近的5個(gè)檢查點(diǎn)文兑。
要測(cè)試盒刚,請(qǐng)重置模型并加載最新的檢查點(diǎn):
model = create_model()
model.load_weights(latest)
loss, acc = model.evaluate(test_images, test_labels)
print("Restored model, accuracy: {:5.2f}%".format(100*acc))
1000/1000 [==============================] - 0s 96us/step
Restored model, accuracy: 86.80%
這些文件是什么?
上述代碼將權(quán)重存儲(chǔ)到檢查點(diǎn)格式的文件集合中绿贞,這些文件僅包含二進(jìn)制格式的訓(xùn)練權(quán)重因块。 檢查點(diǎn)包含:*一個(gè)或多個(gè)包含模型權(quán)重的分片。 *索引文件籍铁,指示哪些權(quán)重存儲(chǔ)在哪個(gè)分片中涡上。
如果您只在一臺(tái)機(jī)器上訓(xùn)練模型趾断,那么您將有一個(gè)帶有后綴的分片:.data-00000-of-00001
# Save the weights
model.save_weights('./checkpoints/my_checkpoint')
# Restore the weights
model = create_model()
model.load_weights('./checkpoints/my_checkpoint')
loss,acc = model.evaluate(test_images, test_labels)
print("Restored model, accuracy: {:5.2f}%".format(100*acc))
保存整個(gè)模型
整個(gè)模型可以保存到包含權(quán)重值,模型配置甚至優(yōu)化器配置的文件中吩愧。 這允許您檢查模型并稍后從完全相同的狀態(tài)恢復(fù)培訓(xùn) - 無需訪問原始代碼芋酌。
在Keras中保存功能齊全的模型非常有用 - 您可以在TensorFlow.js中加載它們,然后在Web瀏覽器中訓(xùn)練和運(yùn)行它們雁佳。
Keras使用HDF5標(biāo)準(zhǔn)提供基本保存格式脐帝。 出于我們的目的,可以將保存的模型視為單個(gè)二進(jìn)制blob甘穿。
model = create_model()
model.fit(train_images, train_labels, epochs=5)
# Save entire model to a HDF5 file
model.save('my_model.h5')
Epoch 1/5
1000/1000 [==============================] - 0s 395us/step - loss: 1.1260 - acc: 0.6870
Epoch 2/5
1000/1000 [==============================] - 0s 135us/step - loss: 0.4136 - acc: 0.8760
Epoch 3/5
1000/1000 [==============================] - 0s 138us/step - loss: 0.2811 - acc: 0.9280
Epoch 4/5
1000/1000 [==============================] - 0s 153us/step - loss: 0.2078 - acc: 0.9480
Epoch 5/5
1000/1000 [==============================] - 0s 154us/step - loss: 0.1452 - acc: 0.9750
現(xiàn)在從該文件重新創(chuàng)建模型:
# Recreate the exact same model, including weights and optimizer.
new_model = keras.models.load_model('my_model.h5')
new_model.summary()
檢查其準(zhǔn)確性:
loss, acc = new_model.evaluate(test_images, test_labels)
print("Restored model, accuracy: {:5.2f}%".format(100*acc))
這項(xiàng)技術(shù)可以保存以下:
- 權(quán)重值
- 模型的配置(架構(gòu))
- 優(yōu)化器配置
Keras通過檢查架構(gòu)來保存模型腮恩。 目前,它無法保存TensorFlow優(yōu)化器(來自tf.train)温兼。 使用這些時(shí),您需要在加載后重新編譯模型武契,并且您將失去優(yōu)化器的狀態(tài)募判。
下一步是什么
這是使用tf.keras保存和加載的快速指南。
tf.keras指南顯示了有關(guān)使用tf.keras保存和加載模型的更多信息咒唆。
請(qǐng)參閱在急切執(zhí)行期間保存以備保存届垫。
“保存和還原”指南包含有關(guān)TensorFlow保存的低級(jí)詳細(xì)信息。
完整代碼:
from __future__ import absolute_import,division,print_function
import os
import tensorflow as tf
from tensorflow import keras
print(tf.__version__)
# Download dataset
(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
# Define a model
# Returns a short sequential model
def create_model():
model = tf.keras.models.Sequential([
keras.layers.Dense(512,activation=tf.nn.relu,input_shape=(784,)),
keras.layers.Dropout(0.2),
keras.layers.Dense(10,activation=tf.nn.softmax)
])
model.compile(optimizer=tf.keras.optimizers.Adam(),
loss=tf.keras.losses.sparse_categorical_crossentropy,
metrics=['accuracy'])
return model
# Create a basic model instance
model = create_model()
model.summary()
# Checkpoint callback usage
checkpoint_path = "training_1/cp.ckpt"
checkpoint_dir = os.path.dirname(checkpoint_path)
# Create checkpoint callback
cp_callback = tf.keras.callbacks.ModelCheckpoint(checkpoint_path,
save_weights_only=True,
verbose=1)
model = create_model()
model.fit(train_images,train_labels,epochs=10,
validation_data=(test_images,test_labels),
callbacks=[cp_callback]) # pass callback to training
# Create a new, untrained model.
model = create_model()
loss,acc = model.evaluate(test_images,test_labels)
print("Untrained model, accuracy: {:5.2f}%".format(100*acc))
# Load the weights from chekpoint, and re-evaluate.
model.load_weights(checkpoint_path)
loss,acc = model.evaluate(test_images,test_labels)
print("Restored model, accuracy: {:5.2f}%".format(100*acc))
# Train a new model, and save uniquely named checkpoints once every 5epochs
# include the epoch in the file name. (uses 'str.format')
checkpoint_path = 'training_2/cp-{epoch:04d}.ckpt'
checkpoint_dir = os.path.dirname(checkpoint_path)
cp_callback = tf.keras.callbacks.ModelCheckpoint(
checkpoint_path, verbose=1,save_weights_only=True,
# Save weights, every 5-epochs
period=5)
model = create_model()
model.fit(train_images,train_labels,
epochs=50,callbacks = [cp_callback],
validation_data = (test_images,test_labels),
verbose=0)
latest = tf.train.latest_checkpoint(checkpoint_dir)
print(latest)
# To test, reset the model and load the latest checkpoint
model = create_model()
model.load_weights(latest)
loss, acc = model.evaluate(test_images,test_labels)
print("Restored model, accuracy: {:5.2f}%".format(100*acc))
# Manually save weights
# Save the weights
model.save_weights('./checkpoints/my_checkpoint')
# Restore the weights
model = create_model()
model.load_weights('./checkpoints/my_checkpoint')
loss, acc = model.evaluate(test_images,test_labels)
print("Restored model, accuracy: {:5.2f}%".format(100*acc))
# Save the entire model
model = create_model()
model.fit(train_images,train_labels,
epochs=5)
# Save entire model to a HDF5 file
model.save('my_model.h5')
# Recreate the exact same model, including weights and optimizer.
new_model = keras.models.load_model('my_model.h5')
new_model.summary()
loss, acc = new_model.evaluate(test_images,test_labels)
print("Restored model, accuracy: {:5.2f}%".format(100*acc))