30天从入门到精通TensorFlow1.x 第七天,TensorFlow1.x 离线模型的save()和restore()

文章目录

  • 一、接前一天
  • 二、TensorFlow中模型的保存和加载方式
  • 三、模型的保存和加载`Save()`类
    • 1. 创建方法以及文件组成
    • 2. Saver类的重要参数
      • 参数:
      • `重要函数参数`:
    • 3. Saver类的主要使用函数
  • 四、keras的模型保存和加载
    • 1. Keras比较简单:一般有三种选择
    • 2. 区别
    • 3. 保存完整的好处
  • 五、基于简单线性回归的实践
    • 1. 实例化对象
    • 2. 保存
    • 3.加载
    • 4. 基于线性回归完整的保存代码
    • 5. 基于线性回归完整的加载使用代码

一、接前一天

前一天讨论了tensorboard今天讨论在TensorFlow1.x中的模型保存加载使用是在实际开发中我们不会简单的将模型上传服务器,开发api接口调用的,因为将模型放在服务器上,使用标准API接口文档编写也可以实现推理功能。但是,这种方式可能会涉及到一些额外的工作,例如:设置部署环境处理并发请求处理模型版本更新等问题。这样的工作需要进行更多的编程和配置,而且可能不够灵活和可扩展。
这里涉及的技术例如: TF服务等,今天就先不讨论,明天详细讨论这里。

二、TensorFlow中模型的保存和加载方式

  1. SavedModel 格式:SavedModel 是 TensorFlow 推荐的模型格式,可以将模型保存为一个目录,其中包含了模型结构、变量和运行时信息。SavedModel 可以跨平台、跨语言地加载模型,并支持部署到 TensorFlow Serving 等服务中。

  2. Checkpoint 文件:Checkpoint 文件是 TensorFlow 训练的中间结果,保存了所有变量和权重的值。可以使用 tf.train.Saver() 将变量保存到 Checkpoint 文件中,也可以使用 tf.train.latest_checkpoint() 加载最新的 Checkpoint 文件。

  3. Keras 模型文件:Keras 是 TensorFlow 的高级 API,可以使用 keras.models.save_model() 方法将 Keras 模型保存为 HDF5SavedModel 格式的文件。

  4. Protocol Buffer 文件:TensorFlow 使用 Protocol Buffer 格式来序列化和反序列化数据,包括模型结构、变量和运行时信息。可以使用 tf.io.write_graph() 和 tf.io.read_graph() 方法将模型保存为或加载为 GraphDef Protocol Buffer 文件。

我们只讨论 第二种第三种,以适用我们在不同场景中的使用。

三、模型的保存和加载Save()

Saver类的保存方法属于第二种方法,即Checkpoint文件。 Saver是TensorFlow提供的一个用于保存和恢复模型变量的类。它可以将训练过程中的模型参数保存到硬盘上,以便在需要的时候重新加载模型参数。

1. 创建方法以及文件组成

通过tf.train.Saver 类创建 saver对象

在这里插入图片描述

元计算图:计算图的协议缓冲区定义,扩展名为.meta

检查点:各种变量的值,包含两个文件,一个是扩展名为.index的,另一个是 文件扩展名为data-0000-of-00001

检查点(Checkpoint)是保存训练过程中模型的参数值的文件。当我们训练一个模型时,可以定期保存模型参数的当前值为一个检查点文件,以便在训练过程中出现故障或需要更改超参数时,能够从上一个检查点恢复训练,而不用重新开始训练。

通过使用检查点文件,我们可以将训练过程分成若干个阶段,每个阶段保存一个检查点文件,以便在训练过程中出现意外情况(如程序意外退出、计算机断电等)时能够快速恢复模型。检查点还可以用于在训练过程中选择最佳的模型。我们可以通过比较不同的检查点文件,选择验证集分类准确率最高或损失函数最小的模型作为最终结果。

2. Saver类的重要参数

参数:

var_list: 可选参数,表示需要保存或恢复的变量列表,默认为所有可训练变量。
reshape: 可选参数,如果为True,则载入模型时会尝试自动将变量reshape成原来的形状,默认为False。
sharded: 可选参数,如果为True,则在保存数据时将其分割成多个文件进行存储(仅当save_relative_paths=True时有效),默认为False。
max_to_keep: 可选参数,表示最多保存的检查点数量,默认为5。
keep_checkpoint_every_n_hours: 可选参数,表示每隔多少小时保存一个检查点,默认为10000个步骤保存一次。
name: 可选参数,表示Saver对象的名称。

重要函数参数

  1. save(session, save_path, global_step=None, latest_filename=None, meta_graph_suffix=‘meta’, write_meta_graph=True, write_state=True, strip_default_attrs=False, save_debug_info=False):
    保存模型参数到指定路径,其中
    session:表示当前Session,
    save_path:表示保存路径,
    global_step:表示当前模型训练的全局步数,
    latest_filename:表示保存最近检查点的文件名,默认为’checkpoint’,
    meta_graph_suffix:表示元图文件的后缀,默认为’meta’,
    write_meta_graph:表示是否写入元图(即计算图)文件,默认为True,
    write_state:表示是否写入变量文件,默认为True,
    strip_default_attrs:表示是否去除默认属性,默认为False,
    save_debug_info:表示是否保存调试信息,默认为False。
  2. restore(session, save_path, var_list=None, global_step=None, latest_filename=None, meta_graph_suffix=‘meta’, write_meta_graph=True, write_state=True, strip_default_attrs=False): 从指定路径恢复模型参数,其中
    session:表示当前Session,
    save_path:表示保存路径,
    var_list:表示需要恢复的变量列表,默认为所有可训练变量,
    global_step:表示需要恢复的全局步数,
    latest_filename:表示最近检查点的文件名,默认为’checkpoint’,
    meta_graph_suffix:表示元图文件的后缀,默认为’meta’,
    write_meta_graph:表示是否写入元图(即计算图)文件,默认为True,
    write_state:表示是否写入变量文件,默认为True,
    strip_default_attrs:表示是否去除默认属性,默认为False

TensorFlow 2.x中的Saver类被tf.train.Checkpoint取代了

3. Saver类的主要使用函数

  1. tf.train.Saver()
    该函数可以创建一个Saver对象,用于保存恢复TensorFlow模型。你可以使用saver.save()方法将模型保存到磁盘上,也可以使用saver.restore()方法从磁盘上恢复模型。

  2. saver.save(sess, save_path)
    该方法可以将当前会话(Session)的所有变量保存到磁盘上,其中参数sess是一个已经打开的会话,save_path是要保存的模型文件的路径。

  3. tf.train.import_meta_graph(meta_graph_def)
    该函数可以从.meta文件中导入图结构(Graph),其中meta_graph_def是一个包含图定义信息的.meta文件。

  4. saver.restore(sess, save_path)
    该方法可以从指定的模型文件中恢复所有变量,其中参数sess是一个已经打开的会话,save_path是之前保存的模型文件的路径。

  5. tf.get_default_graph()
    该函数可以获取默认的计算图(Graph),在加载模型时需要借助该函数来获取图中的所有节点和变量。

  6. graph.get_tensor_by_name(name)
    该方法可以根据节点名称获取计算图中的张量(Tensor)。

  7. graph.get_operation_by_name(name)
    该方法可以根据节点名称获取计算图中的操作(Operation)。

四、keras的模型保存和加载

1. Keras比较简单:一般有三种选择

  1. 仅保存模型结构(Architecture):使用 model.to_json() 方法将模型结构保存为 JSON 文件格式,使用 model_from_json() 方法加载模型结构。

  2. 保存模型结构和权重(Weights):使用 model.save_weights() 方法将模型权重保存为 HDF5 文件格式,使用 load_weights() 方法加载模型权重。此外,还可以使用 model.save() 方法保存整个模型,包括模型结构和权重也是以 HDF5 文件格式进行保存

  3. 保存完整的模型对象,包括模型结构权重编译信息等:使用 tf.keras.models.save_model() 方法将整个模型保存为 SavedModel 格式或者 HDF5 文件格式,使用 tf.keras.models.load_model() 方法加载模型。如果需要保存模型的编译信息,例如优化器、损失函数、评估指标等,则需要设置 save_format=‘tf’ 参数,以保存为 SavedModel 格式。

2. 区别

这三种方式的主要区别在于保存的内容不同。第一种方式只保存了模型的结构,无法直接使用;第二种方式保存了模型的权重,可以方便地用于继续训练或者对新数据进行预测;第三种方式保存了完整的模型对象,可以方便地复现模型,并且包含了模型的结构、权重和编译信息。

3. 保存完整的好处

第三种方式还支持保存为 SavedModel 格式,这是 TensorFlow 官方推荐的模型保存格式,可以方便地部署TensorFlow Serving 或者其他平台上。而 HDF5 文件格式则更加通用,可以在不同框架之间进行转换和共享。

五、基于简单线性回归的实践

1. 实例化对象

save = tf.train.Saver()

2. 保存

with tf.Session() as sess:
	...
	save.save(sess,'./')
'''
参数一:会话对象
参数二:保存的路径以及名字
'''

3.加载

with tf.Session() as sess:
	...
	save.restore(sess,'./')

4. 基于线性回归完整的保存代码

import tensorflow as tf
from tensorflow.python.client import device_lib
import os
print(device_lib.list_local_devices())




tf.reset_default_graph()

with tf.device("/device:cpu:0"):
    # create w and b init 0.0
    w = tf.Variable(0.0, name='weight')
    b = tf.Variable(0.0, name='bias')

    # create input and out
    x = tf.placeholder(dtype=tf.float32, shape=[None])
    out = tf.placeholder(dtype=tf.float32, shape=[None])

    # create loss and opt
    y = w * x + b

    loss = tf.reduce_mean(tf.square(y - out))
    optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.01)
    train_op = optimizer.minimize(loss)

config = tf.ConfigProto()
config.log_device_placement=True

output_scalar = tf.reduce_mean(y)  # 将 y 变量转换为标量
loss_scalar = tf.reduce_mean(loss)
# 记录标量数据(输出结果和损失值)
tf.summary.scalar('output', output_scalar)
tf.summary.scalar('loss', loss_scalar)

# 记录张量数据(权重和偏置项)
tf.summary.histogram('weight', w)
tf.summary.histogram('bias', b)

# 记录网络结构
with tf.name_scope('hidden'):
    h = tf.nn.sigmoid(y)
    tf.summary.histogram('activation', h)

#实例化模型保存对象
save = tf.train.Saver()

# train model
with tf.Session(config=config) as sess:

    # 合并所有的摘要操作
    merged = tf.summary.merge_all()
    # 创建摘要写入器

    writer = tf.summary.FileWriter('./logss', sess.graph)

	#注意!!!在保存模型的时候 需要进行变量初始化
    tf.global_variables_initializer().run(session=sess)
    for i in range(100000):
        summary,_, loss_val, w_val, b_val = sess.run(
            [merged,train_op, loss, w, b],
            feed_dict={x: [1, 23, 4, 5, 7, 5, 7], out: [3, 5, 7, 9, 11, 13, 15]}
        ) #注意 输入的数据 形状要一致,避免输出与预测值得形状不一致问题
        if i % 100 == 0:
            print('Step {}: loss = {}, w = {}, b = {}'.format(i, loss_val, w_val, b_val))

            writer.add_summary(summary, i)


		#保存模型
    save_model_file = save.save(sess,'./model.ckpt')

5. 基于线性回归完整的加载使用代码

其实:加载模型进行预测就是使用训练的模型变量对会话进行初始化。一般我们训练的时候会对变量进行全局初始化,在加载模型的时候改为 训练好的模型变量。

import tensorflow as tf
from tensorflow.python.client import device_lib
import os
print(device_lib.list_local_devices())




tf.reset_default_graph()

with tf.device("/device:cpu:0"):
    # create w and b init 0.0
    w = tf.Variable(0.0, name='weight')
    b = tf.Variable(0.0, name='bias')

    # create input and out
    x = tf.placeholder(dtype=tf.float32, shape=[None])
    out = tf.placeholder(dtype=tf.float32, shape=[None])

    # create loss and opt
    y = w * x + b

    # loss = tf.reduce_mean(tf.square(y - out))
    # optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.01)
    # train_op = optimizer.minimize(loss)

config = tf.ConfigProto()
config.log_device_placement=True

#实例化保存对象
save = tf.train.Saver()

# train model
with tf.Session(config=config) as sess:


    save.restore(sess,'./')
    #加载模型的时候不需要进行变量初始化
    # tf.global_variables_initializer().run(session=sess)

    outs = sess.run(
        [y],
        feed_dict={x:[1,2,3]}
    ) #注意 输入的数据 形状要一致,避免输出与预测值得形状不一致问题

    print('outs;',outs)


你可能感兴趣的:(tensorflow,深度学习,人工智能)