模型保存


import tensorflow as tf import os
import pandas as pd import numpy as np import matplotlib.pyplot as plt %matplotlib inline

print("Tensorflow Version:{}".format(tf.__version__))
print(tf.test.is_gpu_available())
(train_image,train_label),(test_image,test_label) = tf.keras.datasets.fashion_mnist.load_data()
## 归一化
train_image = train_image/255
test_image = test_image/255
model = tf.keras.Sequential()
model.add(tf.keras.layers.Flatten(input_shape=(28,28)))
model.add(tf.keras.layers.Dense(128,activation='relu'))
model.add(tf.keras.layers.Dense(10,activation='softmax'))
model.compile(optimizer=tf.optimizers.Adam(),
             loss=tf.losses.sparse_categorical_crossentropy,
             metrics=['acc']
)
model.fit(train_image,train_label,epochs=10)
model.evaluate(test_image,test_label,verbose=0)#verbose 是否显示提示,  0:显示所有提示     1:显示最主要提示      2:不显示提示

保存整个模型(保存了模型框架、权重、优化器配置)

整个模型可以保存到一个文件中,其中包含权重值、模型配置乃至优化器配置。这样,您就可以为模型设置检查点,并稍后从完全相同的状态继续训练,而无需访问原始代码。

在 Keras 中保存完全可正常使用的模型非常有用,您可以在 TensorFlow.js 中加载它们,然后在网络浏览器中训练和运行它们。

Keras 使用 HDF5 标准提供基本的保存格式。

此方法保存以下所有内容:

1.权重值
2.模型配置(架构)
3.优化器配置

保存:model.save('less_model.h5')

model.save('less_model.h5')

加载:tf.keras.models.load_model('less_model.h5')

new_model = tf.keras.models.load_model('less_model.h5')

仅保存架构

有时我们只对模型的架构感兴趣,而无需保存权重值或优化器。在这种情况下,可以仅保存模型的“配置” 。

保存:model.to_json()json文件,json的读和写

json_config = model.to_json()
#写入json文件
import json
with open('json_config.json','w') as f:
    json.dump(json_config,f)

读取:tf.keras.models.model_from_json(json_config)json文件,json的读和写

#读取json文件
import json
with open('json_config.json','r') as f:
    json_config = json.load(f)
reinitialized_model = tf.keras.models.model_from_json(json_config)

仅保存权重(权重Array)

有时我们只需要保存模型的状态(其权重值),而对模型架构不感兴趣。在这种情况下,可以通过get_weights()获取权重值,并通过set_weights()设置权重值

获取模型权重:model.get_weights()

weighs = model.get_weights()

设置模型权重:model.set_weights(weighs)

reinitialized_model.set_weights(weighs)#设置权重

保存权重:model.save_weights('less_weights.h5')

model.save_weights('less_weights.h5')

加载权重:model.load_weights('less_weights.h5')

reinitialized_model.load_weights('less_weights.h5')

ValueError: Unable to load weights saved in HDF5 format into a subclassed Model which has not created its variables yet. Call the Model first, then load the weights.

model.build(input_shape =(None,256,256,3))

在训练期间保存检查点

在训练期间或训练结束时自动保存检查点。这样一来,您便可以使用经过训练的模型,而无需重新训练该模型,或从上次暂停的地方继续训练,以防训练过程中断。

回调函数:tf.keras.callbacks.ModelCheckpoint

设置检查点保存路径

cheakpoint_path = 'training_cp/cp.ckpt'

使用callbacks.ModelCheckpoint回调函数:tf.keras.callbacks.ModelCheckpoint(检查点保存路径,save_weights_only=True)

cp_callback = tf.keras.callbacks.ModelCheckpoint(cheakpoint_path,#检查点保存路径    cheakpoint_path = 'training_cp/cp.ckpt'
                                                 save_weights_only=True)#是否仅保存权重#回调函数
tf.keras.callbacks.ModelCheckpoint(
 filepath,
 monitor='val_loss',
 verbose=0,
 save_best_only=False,
 save_weights_only=False,
 mode='auto',
 save_freq='epoch',
 options=None,
 **kwargs,
)

训练中传入callbacks.ModelCheckpoint回调函数

model.fit(train_image,train_label,epochs=10,callbacks=[cp_callback])

使用检查点

save_weights_only=True:model.load_weights(cheakpoint_path)

model.load_weights(cheakpoint_path)#加载保存的检查点  因为只保存了权重用load_weights   cheakpoint_path = 'training_cp/cp.ckpt'

save_weights_only=False:tf.keras.models.load_model(cheakpoint_path)

model = tf.keras.models.load_model(cheakpoint_path)

自定义训练中保存检查点

自定义模型构建

model = tf.keras.Sequential()
model.add(tf.keras.layers.Flatten(input_shape=(28,28)))
model.add(tf.keras.layers.Dense(128,activation='relu'))
model.add(tf.keras.layers.Dense(10))

dataset = tf.data.Dataset.from_tensor_slices((train_image,train_label))
dataset = dataset.shuffle(10000).batch(32)

optimizer = tf.keras.optimizers.Adam()
loss_fun = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)

train_loss = tf.keras.metrics.Mean('train_loss',dtype=tf.float32)
train_accuracy = tf.keras.metrics.SparseCategoricalAccuracy('train_accuracy')

test_loss = tf.keras.metrics.Mean('test_loss',dtype=tf.float32)
test_accuracy = tf.keras.metrics.SparseCategoricalAccuracy('test_accuracy')

def loss(model,x,y):
    y_ = model(x)
    return loss_fun(y,y_)
    
def train_step(model,images,labels):
    with tf.GradientTape() as t:
        pred = model(images)
        loss_step = loss_fun(labels,pred)
    grads = t.gradient(loss_step,model.trainable_variables)
    optimizer.apply_gradients(zip(grads,model.trainable_variables))
    train_loss(loss_step)
    train_accuracy(labels,pred) 

设置检查点路径

cp_dir = './customtrain_cp'
cp_prefix = os.path.join(cp_dir,'ckpt')#ckpt表示文件名

设置checkpoint:tf.train.Checkpoint(optimizer=optimizer,model=model)

checkpoint = tf.train.Checkpoint(#
    optimizer=optimizer,
    model=model#训练发生变化优化器Adam自适应 和 model
)

保存了模型优化器、model、权重(整个模型)

恢复根据模型中所有的权重、优化器所有的参数对应name名称

训练函数调用:checkpoint.save(file_prefix = cp_prefix)

def train():
    for epoch in range(10):
        for (batch, (images, labels)) in enumerate(dataset):
            train_step(model, images, labels)
        print('Epoch{} loss is {}'.format(epoch, train_loss.result()))
        print('Epoch{} Accuracy is {}'.format(epoch, train_accuracy.result()))
        train_loss.reset_states()
        train_accuracy.reset_states()
        if (epoch + 1) % 2 == 0:
            checkpoint.save(file_prefix = cp_prefix)   #cp_dir = './customtrain_cp'    cp_prefix = os.path.join(cp_dir,'ckpt')#ckpt表示文件名

查看检查点目录下最新的检查点:tf.train.latest_checkpoint(cp_dir)

tf.train.latest_checkpoint(cp_dir)#取出检查点目录下最新的检查点
#'./customtrain_cp\\ckpt-5'

恢复checkpoint:checkpoint.restore(tf.train.latest_checkpoint(cp_dir))

恢复根据模型中所有的权重、优化器所有的参数对应name名称

model = tf.keras.Sequential()
model.add(tf.keras.layers.Flatten(input_shape=(28,28)))
model.add(tf.keras.layers.Dense(128,activation='relu'))
model.add(tf.keras.layers.Dense(10))

optimizer = tf.keras.optimizers.Adam()
checkpoint = tf.train.Checkpoint(
    optimizer=optimizer,#优化器
    model=model#训练发生变化优化器Adam自适应 和 model
)
checkpoint.restore(tf.train.latest_checkpoint(cp_dir))#恢复检查点 

计算模型的准确率

(tf.argmax(model(train_image,training=False),axis=-1).numpy() == train_label).sum()/len(train_label)

模型判断和真实label做bool,累计True值再除以label个数

posted @ 2023-02-22 22:19  YuKiFuHaNe  阅读(273)  评论(0)    收藏  举报