舉個(gè)例子:先訓(xùn)練出一個(gè)模型
import
接下來(lái)第一種方法:只保留模型的參數(shù):這個(gè)有2種方法:
- model.save_weights("adasd.h5")
- model.load_weights("adasd.h5")
- model.predict(x_test)
- model.save_weights('./checkpoints/mannul_checkpoint')
- model.load_weights('./checkpoints/mannul_checkpoint')
- model.predict(x_test)
因?yàn)檫@種方法只保留了參數(shù),而并沒(méi)有保留整個(gè)模型,所以說(shuō)在加載的時(shí)候需要使用model.load_weights。這個(gè)函數(shù)只會(huì)保留模型的權(quán)重,它不包含模型的結(jié)構(gòu),所以當(dāng)我們加載權(quán)重文件時(shí)候,需要先輸入網(wǎng)絡(luò)結(jié)構(gòu)
再第2種方法:保留h5文件,保留整個(gè)模型
這種方法已經(jīng)保存了模型的結(jié)構(gòu)和權(quán)重,以及損失函數(shù)和優(yōu)化器
- model.save('keras_model_hdf5_version.h5')
- new_model = tf.keras.models.load_model('keras_model_hdf5_version.h5')
- new_model.predict(x_test)
注意:這種方法只可以使用在keras的順序模型和函數(shù)式模型中,不能使用在子類模型和自定義模型中,否則會(huì)報(bào)錯(cuò)。
再第3種方法:保留pb文件,保留整個(gè)模型
- # Export the model to a SavedModel
- model.save('keras_model_tf_version', save_format='tf')
- # Recreate the exact same model
- new_model = tf.keras.models.load_model('keras_model_tf_version')
- new_model.predict(x_test)
這個(gè)方法沒(méi)有保留優(yōu)化器配置。
保留pb文件還有另一種方法:
tf.saved_model.save(model,'文件夾名')和 tf.saved_model.load('文件夾名')
注意:這里是文件夾名稱??!
當(dāng)我們使用這個(gè)方法后,對(duì)應(yīng)目錄下會(huì)出現(xiàn)一個(gè)文件夾,文件夾下有兩個(gè)子文件夾和一個(gè)子文件:assets、variables、save_model.pb
TensorFlow 為我們提供的SavedModel這一格式可在不同的平臺(tái)上部署模型文件,當(dāng)模型導(dǎo)出為 SavedModel 文件時(shí),無(wú)需建立。
模型的源代碼即可再次運(yùn)行模型,這使得SavedModel尤其適用于模型的分享和部署。
- tf.saved_model.save(model,'tf_saved_model_version')
- restored_saved_model = tf.saved_model.load('tf_saved_model_version')
- f = restored_saved_model.signatures["serving_default"]
注意這里加載好了以后不能直接用predict進(jìn)行預(yù)測(cè)哦。
我們這里看一下保存信息:
!saved_model_cli show --dir tf_saved_model_version --all
使用模型的命令是:
f(digits = tf.constant(x_test.tolist()) )
輸出為:
關(guān)鍵是f = restored_saved_model.signatures["serving_default"]。
注意這里要用以下命令
@tf.function(input_signature=[tf.TensorSpec([None,32], tf.float32,name='digits')])
把動(dòng)態(tài)圖變成靜態(tài)圖:
- class MyModel(tf.keras.Model):
- def __init__(self, num_classes=10):
- super(MyModel, self).__init__(name='my_model')
- self.num_classes = num_classes
- # 定義自己需要的層
- self.dense_1 = tf.keras.layers.Dense(32, activation='relu')
- self.dense_2 = tf.keras.layers.Dense(num_classes)
- @tf.function(input_signature=[tf.TensorSpec([None,32], tf.float32,name='digits')])
- def call(self, inputs):
- #定義前向傳播
- # 使用在 (in `__init__`)定義的層
- x = self.dense_1(inputs)
- return self.dense_2(x)
- import numpy as np
- x_train = np.random.random((1000, 32))
- y_train = np.random.random((1000, 10))
- x_val = np.random.random((200, 32))
- y_val = np.random.random((200, 10))
- x_test = np.random.random((200, 32))
- y_test = np.random.random((200, 10))
- # 優(yōu)化器
- optimizer = tf.keras.optimizers.SGD(learning_rate=1e-3)
- # 損失函數(shù)
- loss_fn = tf.keras.losses.CategoricalCrossentropy(from_logits=True)
- # 準(zhǔn)備metrics函數(shù)
- train_acc_metric = tf.keras.metrics.CategoricalAccuracy()
- val_acc_metric = tf.keras.metrics.CategoricalAccuracy()
- # 準(zhǔn)備訓(xùn)練數(shù)據(jù)集
- batch_size = 64
- train_dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train))
- train_dataset = train_dataset.shuffle(buffer_size=1024).batch(batch_size)
- # 準(zhǔn)備測(cè)試數(shù)據(jù)集
- val_dataset = tf.data.Dataset.from_tensor_slices((x_val, y_val))
- val_dataset = val_dataset.batch(64)
- model = MyModel(num_classes=10)
- epochs = 3
- for epoch in range(epochs):
- print('Start of epoch %d' % (epoch,))
- # 遍歷數(shù)據(jù)集的batch_size
- for step, (x_batch_train, y_batch_train) in enumerate(train_dataset):
- with tf.GradientTape() as tape:
- logits = model(x_batch_train)
- loss_value = loss_fn(y_batch_train, logits)
- grads = tape.gradient(loss_value, model.trainable_weights)
- optimizer.apply_gradients(zip(grads, model.trainable_weights))
- # 更新訓(xùn)練集的metrics
- train_acc_metric(y_batch_train, logits)
- # 每200 batches打印一次.
- if step % 200 == 0:
- print('Training loss (for one batch) at step %s: %s' % (step, float(loss_value)))
- print('Seen so far: %s samples' % ((step + 1) * 64))
- # 在每個(gè)epoch結(jié)束時(shí)顯示metrics。
- train_acc = train_acc_metric.result()
- print('Training acc over epoch: %s' % (float(train_acc),))
- # 在每個(gè)epoch結(jié)束時(shí)重置訓(xùn)練指標(biāo)
- train_acc_metric.reset_states()
- # 在每個(gè)epoch結(jié)束時(shí)運(yùn)行一個(gè)驗(yàn)證集。
- for x_batch_val, y_batch_val in val_dataset:
- val_logits = model(x_batch_val)
- # 更新驗(yàn)證集merics
- val_acc_metric(y_batch_val, val_logits)
- val_acc = val_acc_metric.result()
- val_acc_metric.reset_states()
- print('Validation acc: %s' % (float(val_acc),))
模型保存方法一:保存weight:
- model.save_weights("adasd.h5")
- model.load_weights("adasd.h5")
- model.predict(x_test)
- model.save_weights('./checkpoints/mannul_checkpoint')
- model.load_weights('./checkpoints/mannul_checkpoint')
- model.predict(x_test)
模型保存方法二:保留h5,方法失敗,因?yàn)樽远x模型無(wú)法保留h5:
#model.save('my_saved_model.h5')
模型保存方法三:pb格式:
- model.save('path_to_my_model',save_format='tf')
- new_model = tf.keras.models.load_model('path_to_my_model')
- new_model.predict(x_test)
輸出為:
或者:
- tf.saved_model.save(model,'my_saved_model')
- restored_saved_model = tf.saved_model.load('my_saved_model')
- f = restored_saved_model.signatures["serving_default"]
- f(digits = tf.constant(x_test.tolist()) )
!saved_model_cli show --dir my_saved_model --all
注意前面模型定義時(shí)候:
@tf.function(input_signature=[tf.TensorSpec([None,32], tf.float32,name='digits')])
這個(gè)digits,對(duì)應(yīng)的就是input['digits'],也對(duì)應(yīng)的是f函數(shù)中的自變量digits。
注意第2種方法h5格式只可以使用在keras的順序模型和函數(shù)式模型中,不能使用在子類模型和自定義模型中。
聯(lián)系客服