zoukankan      html  css  js  c++  java
  • 4、tensorflow 模型保存和载入

    checkpoint -save

    # 定义Saver用于保存模型
    saver = tf.train.Saver()
     # 训练结束后,在session中保存模型,后缀一般用ckpt,其他的也可以
     
     saver.save(sess,'models/my_model.ckpt')
    保存模型的时候一定要定义好名字,只有这样才可以在载入的时候用
    
    生成四个文件
    checkpoint  用于记录网络参数
    my_model.ckpt.data-00000-00001
    my_model.ckpt.index
    my_model.ckpt.meta #用于记录网络的结构
    import tensorflow as tf
    from tensorflow.examples.tutorials.mnist import input_data
    
    # 载入数据集
    mnist = input_data.read_data_sets("MNIST_data",one_hot=True)
    
    # 每个批次64张照片
    batch_size = 64
    # 计算一共有多少个批次
    n_batch = mnist.train.num_examples // batch_size
    
    # 定义两个placeholder
    # 给模型数据输入的入口起名为x-input
    x = tf.placeholder(tf.float32,[None,784], name='x-input')
    # 给模型标签输入的入口起名为y-input
    y = tf.placeholder(tf.float32,[None,10], name='y-input')
    
    # 创建一个简单的神经网络,输入层784个神经元,输出层10个神经元
    W = tf.Variable(tf.truncated_normal([784,10],stddev=0.1))
    b = tf.Variable(tf.zeros([10])+0.1)
    # 给模型输出起名为output
    prediction = tf.nn.softmax(tf.matmul(x,W)+b, name='output')
    
    # 交叉熵代价函数
    loss = tf.losses.softmax_cross_entropy(y,prediction)
    # 使用Adam优化器,给优化器operation起名为train
    train_step = tf.train.AdamOptimizer(0.001).minimize(loss, name='train')
    
    # 初始化变量
    init = tf.global_variables_initializer()
    
    # 求准确率
    # tf.argmax(y,1)中的1表示取y中第1个维度中最大值所在的位置
    # tf.equal表示比较两个值是否相等,相等返回True,不相等返回False
    # 最后correct_prediction是一个布尔型的列表
    correct_prediction = tf.equal(tf.argmax(y,1),tf.argmax(prediction,1))
    # tf.cast表示数据格式转换,把布尔型转为float类型,True变成1.0,False变成0.0
    # tf.reduce_mean求平均值
    # 最后accuracy为准确率
    # 给准确率tensor起名为accuracy
    accuracy = tf.reduce_mean(tf.cast(correct_prediction,tf.float32), name='accuracy')
    
    # 定义Saver用于保存模型
    saver = tf.train.Saver()
    
    with tf.Session() as sess:
        # 变量初始化
        sess.run(init)
        # 运行11个周期
        for epoch in range(11):
            for batch in range(n_batch):
                # 获取一个批次的数据和标签
                batch_xs,batch_ys =  mnist.train.next_batch(batch_size)
                # 喂到模型中做训练
                sess.run(train_step,feed_dict={x:batch_xs,y:batch_ys})
            # 每个周期计算一次测试集准确率
            acc = sess.run(accuracy,feed_dict={x:mnist.test.images,y:mnist.test.labels})
            # 打印信息
            print("Iter " + str(epoch) + ",Testing Accuracy " + str(acc))
        # 保存模型
        saver.save(sess,'models/my_model.ckpt')
        
        

    checkpoint 载入结构和参数

    在会话中载入模型结构
    saver = tf.train.import_meta_graph('models/my_model.ckpt.meta')
    载入模型的参数
    saver.restore(sess,'models/my_model.ckpt')
    获取要输出的张量以及op的名字(也就是要run的)
    output = sess.graph.get_tensor_by_name('output:0')
    accuracy = sess.graph.get_tensor_by_name('accuracy:0')
    train_step = sess.graph.get_operation_by_name('train')
    预测
    sess.run(accuracy,feed_dict={'x-input:0':mnist.test.images,'y-input:0':mnist.test.labels})
    feed字典里面的名字,都是保存的时候定义的名字,
    训练
    sess.run(train_step,feed_dict={'x-input:0':batch_xs,'y-input:0':batch_ys})
    import tensorflow as tf
    from tensorflow.examples.tutorials.mnist import input_data
    
    # 载入数据集
    mnist = input_data.read_data_sets("MNIST_data",one_hot=True)
    # 定义批次大小
    batch_size = 64
    # 计算一共有多少个批次
    n_batch = mnist.train.num_examples // batch_size
    
    
    with tf.Session() as sess:
        # 载入模型结构
        saver = tf.train.import_meta_graph('models/my_model.ckpt.meta')
        # 载入模型参数
        saver.restore(sess,'models/my_model.ckpt')
        # 根据tensor的名字获取到对应的tensor
        # 之前保存模型的时候模型输出保存为output,":0"是保存模型参数时自动加上的,所以这里也要写上
        output = sess.graph.get_tensor_by_name('output:0')
        # 根据tensor的名字获取到对应的tensor
        # 之前保存模型的时候准确率计算保存为accuracy,":0"是保存模型参数时自动加上的,所以这里也要写上
        accuracy = sess.graph.get_tensor_by_name('accuracy:0')
        # 之前保存模型的时候模型训练保存为train,注意这里的train是operation不是tensor
        train_step = sess.graph.get_operation_by_name('train')
    
        # 把测试集喂到网络中计算准确率
        # x-input是模型数据的输入,":0"是保存模型参数时自动加上的,所以这里也要写上
        # y-input是模型标签的输入,":0"是保存模型参数时自动加上的,所以这里也要写上
        print(sess.run(accuracy,feed_dict={'x-input:0':mnist.test.images,'y-input:0':mnist.test.labels}))
        
        # 在原来模型的基础上再训练11个周期
        for epoch in range(11):
            for batch in range(n_batch):
                # 获取一个批次的数据和标签
                batch_xs,batch_ys =  mnist.train.next_batch(batch_size)
                # 训练模型
                sess.run(train_step,feed_dict={'x-input:0':batch_xs,'y-input:0':batch_ys})
            # 计算测试集准确率
            acc = sess.run(accuracy,feed_dict={'x-input:0':mnist.test.images,'y-input:0':mnist.test.labels})
            # 打印信息
            print("Iter " + str(epoch) + ",Testing Accuracy " + str(acc))
            

    checkpoint-无网络文件(需要自己书写)载入

    我们不知道网络的结构,所以我们要自己定义一下。这种情况一般是网络上只有checkpoint文件没有meta文件。
    1、在Graph中定义网络结构
    2、在session中载入参数
    saver.restore(sess,'models/my_model.ckpt')
    3、预测
    print(sess.run(accuracy,feed_dict={x:mnist.test.images,y:mnist.test.labels}))
    4、训练
    sess.run(train_step,feed_dict={x:batch_xs,y:batch_ys})
    import tensorflow as tf
    from tensorflow.examples.tutorials.mnist import input_data
    
    # 载入数据集
    mnist = input_data.read_data_sets("MNIST_data",one_hot=True)
    # 定义批次大小
    batch_size = 64
    # 计算一共有多少个批次
    n_batch = mnist.train.num_examples // batch_size
    
    # 定义两个placeholder
    x = tf.placeholder(tf.float32,[None,784])
    y = tf.placeholder(tf.float32,[None,10])
    
    # 创建一个简单的神经网络,输入层784个神经元,输出层10个神经元
    # 这里的模型参数需要跟之前训练好的模型参数一样
    W = tf.Variable(tf.zeros([784,10]))
    b = tf.Variable(tf.zeros([10]))
    prediction = tf.nn.softmax(tf.matmul(x,W)+b)
    
    # 计算准确率
    correct_prediction = tf.equal(tf.argmax(y,1),tf.argmax(prediction,1))
    accuracy = tf.reduce_mean(tf.cast(correct_prediction,tf.float32))
    
    # 定义saver用于载入模型
    # max_to_keep=5,在指定路径下最多保留5个模型,超过5个模型就会删除老的模型
    saver = tf.train.Saver(max_to_keep=5)
    
    # 交叉熵代价函数
    loss = tf.losses.softmax_cross_entropy(y,prediction)
    # 使用Adam优化器
    train_step = tf.train.AdamOptimizer(0.001).minimize(loss)
    
    # 定义会话
    with tf.Session() as sess:
        # 变量初始化
        sess.run(tf.global_variables_initializer())
        # 计算测试集准确率
        print(sess.run(accuracy,feed_dict={x:mnist.test.images,y:mnist.test.labels}))
        # 载入训练好的参数
        saver.restore(sess,'models/my_model.ckpt')
        # 再次计算测试集准确率
        print(sess.run(accuracy,feed_dict={x:mnist.test.images,y:mnist.test.labels}))
        
        # 在原来模型的基础上再训练11个周期
        for epoch in range(11):
            for batch in range(n_batch):
                # 获取一个批次的数据和标签
                batch_xs,batch_ys =  mnist.train.next_batch(batch_size)
                # 训练模型
                sess.run(train_step,feed_dict={x:batch_xs,y:batch_ys})
            # 计算测试集准确率
            acc = sess.run(accuracy,feed_dict={x:mnist.test.images,y:mnist.test.labels})
            # 打印信息
            print("Iter " + str(epoch) + ",Testing Accuracy " + str(acc))
            # 保存模型,global_step可以用来表示模型的训练次数或者训练周期数
            saver.save(sess,'models/my_model.ckpt',global_step=epoch)
            
            

    protocal buffer save pb格式


    网络训练完毕后进行pb方式的保存
    # 保存模型参数和结构,把变量变成常量 # output_node_names设置可以输出的tensor # 这个网络预测的时候指定输出。

    再次加载后就不能进行训练了,只能进行预测。适用于手机端部署
    output_graph_def = tf.graph_util.convert_variables_to_constants(sess, sess.graph_def, output_node_names=['output','accuracy']) # 保存模型到目录下的models文件夹中 with tf.gfile.FastGFile('pb_models/my_model.pb',mode='wb') as f: f.write(output_graph_def.SerializeToString())
    import tensorflow as tf
    from tensorflow.examples.tutorials.mnist import input_data
    
    # 载入数据集
    mnist = input_data.read_data_sets("MNIST_data",one_hot=True)
    
    # 每个批次64张照片
    batch_size = 64
    # 计算一共有多少个批次
    n_batch = mnist.train.num_examples // batch_size
    
    # 定义两个placeholder
    # 给模型数据输入的入口起名为x-input
    x = tf.placeholder(tf.float32,[None,784], name='x-input')
    # 给模型标签输入的入口起名为y-input
    y = tf.placeholder(tf.float32,[None,10], name='y-input')
    
    # 创建一个简单的神经网络,输入层784个神经元,输出层10个神经元
    W = tf.Variable(tf.truncated_normal([784,10],stddev=0.1))
    b = tf.Variable(tf.zeros([10])+0.1)
    # 给模型输出起名为output
    prediction = tf.nn.softmax(tf.matmul(x,W)+b, name='output')
    
    # 交叉熵代价函数
    loss = tf.losses.softmax_cross_entropy(y,prediction)
    # 使用Adam优化器,给优化器operation起名为train
    train_step = tf.train.AdamOptimizer(0.001).minimize(loss, name='train')
    
    # 初始化变量
    init = tf.global_variables_initializer()
    
    # 求准确率
    # tf.argmax(y,1)中的1表示取y中第1个维度中最大值所在的位置
    # tf.equal表示比较两个值是否相等,相等返回True,不相等返回False
    # 最后correct_prediction是一个布尔型的列表
    correct_prediction = tf.equal(tf.argmax(y,1),tf.argmax(prediction,1))
    # tf.cast表示数据格式转换,把布尔型转为float类型,True变成1.0,False变成0.0
    # tf.reduce_mean求平均值
    # 最后accuracy为准确率
    # 给准确率tensor起名为accuracy
    accuracy = tf.reduce_mean(tf.cast(correct_prediction,tf.float32), name='accuracy')
    
    with tf.Session() as sess:
        # 变量初始化
        sess.run(init)
        # 运行11个周期
        for epoch in range(11):
            for batch in range(n_batch):
                # 获取一个批次的数据和标签
                batch_xs,batch_ys =  mnist.train.next_batch(batch_size)
                # 喂到模型中做训练
                sess.run(train_step,feed_dict={x:batch_xs,y:batch_ys})
            # 每个周期计算一次测试集准确率
            acc = sess.run(accuracy,feed_dict={x:mnist.test.images,y:mnist.test.labels})
            # 打印信息
            print("Iter " + str(epoch) + ",Testing Accuracy " + str(acc))
        # 保存模型参数和结构,把变量变成常量
        # output_node_names设置可以输出的tensor
        output_graph_def = tf.graph_util.convert_variables_to_constants(sess, sess.graph_def, output_node_names=['output','accuracy'])
        # 保存模型到目录下的models文件夹中
        with tf.gfile.FastGFile('pb_models/my_model.pb',mode='wb') as f:
            f.write(output_graph_def.SerializeToString())
            
            

    protocal buffer 载入

    import tensorflow as tf
    from tensorflow.examples.tutorials.mnist import input_data
    
    # 载入数据集
    mnist = input_data.read_data_sets("MNIST_data",one_hot=True)
    
    # 载入模型,
    with tf.gfile.FastGFile('pb_models/my_model.pb', 'rb') as f:
        # 创建一个图
        graph_def = tf.GraphDef()
        # 把模型文件载入到图中
        graph_def.ParseFromString(f.read())
        # 载入图到当前环境中
        tf.import_graph_def(graph_def, name='')
    #在session中如果要预测哪个结果就需要先获取这个tensor名字
    #output = sess.graph.get_tensor_by_name('output:0')
    
    with tf.Session() as sess:
        # 根据tensor的名字获取到对应的tensor
        # 之前保存模型的时候模型输出保存为output,":0"是保存模型参数时自动加上的,所以这里也要写上
        output = sess.graph.get_tensor_by_name('output:0')
        # 根据tensor的名字获取到对应的tensor
        # 之前保存模型的时候准确率计算保存为accuracy,":0"是保存模型参数时自动加上的,所以这里也要写上
        accuracy = sess.graph.get_tensor_by_name('accuracy:0')
        # 预测准确率
        print(sess.run(accuracy,feed_dict={'x-input:0':mnist.test.images,'y-input:0':mnist.test.labels}))
        
        

    saved model

    saved_model保存模型的介绍
      这是一种简单格式pb模型保存方式
      目录结构
        └── 1
        ···├── saved_model.pb
        ···└── variables
        ·········├── variables.data-00000-of-00001
        ·········└── variables.index
      特点:
        对于训练好的模型,我们都是用来进行使用的,也就是进行inference。
        这个时候就不模型变化了。这种方式就将变量的权重变成了一个常亮。
        这样方式模型会变小
        在一些嵌入式吗,用C或者C++的系统中,我们也是常用.pb格式的。
    网络训练完毕后进行pb方式的保存

    saved model svae

    from tensorflow.examples.tutorials.mnist import input_data
    import tensorflow as tf
    
    mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
    
    sess = tf.InteractiveSession()
    x = tf.placeholder(tf.float32, [None, 784])
    tf.identity(y, name="myOutput")#将identity加到y上面就表示对y进行重命名
    W = tf.Variable(tf.zeros([784, 10])) b = tf.Variable(tf.zeros([10])) y = tf.nn.softmax(tf.matmul(x, W) + b) y_ = tf.placeholder(tf.float32, [None, 10]) cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_ * tf.log(y), 1)) train_step = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy) tf.global_variables_initializer().run() for i in range(1000): batch_xs, batch_ys = mnist.train.next_batch(100) train_step.run({x: batch_xs, y_: batch_ys}) correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1)) accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
    tf.saved_model.simple_save(sess,
                 "./model",
                 inputs={"myInput": x},
                 outputs={"myOutput": y})
    print(accuracy.eval({x: mnist.test.images, y_: mnist.test.labels}))

    因为我们使用这个模型进行预测,我们肯定是输入一个东西,然后求的我们的输出。
    为了方便找到我们网络中的输入和输出,因此我们可以对我们输入的tensor 进行命名
    命名方式有两种
    x = tf.placeholder(tf.float32, [None, 784], name="myInput")#name 就是input tensor名字
    tf.identity(y, name="myOutput")#将identity加到y上面就表示对y进行重命名
    tf.saved_model.simple_save(sess,
                 "./model",
                 inputs={"myInput": x},
                 outputs={"myOutput": y})

    使用saved model格式预测

    import tensorflow as tf
    import numpy as np
    from PIL import Image
    
    with tf.Session(graph=tf.Graph()) as sess:
        tf.saved_model.loader.load(sess, ["serve"], "./model")
        #这个model下面有variable文件夹和saved_model.pb文件
        sess.run(tf.global_variables_initializer())
    
        # 获取这个模型的输入输出的tensor的名字
        input_img = sess.graph.get_tensor_by_name('map/TensorArrayStack/TensorArrayGatherV3:0')
        output_tenosr = sess.graph.get_tensor_by_name('softmax_tensor:0')
    
        # 读入一张图片,
        # shape:必须是[B, 224,224,3]
        # PNG格式的图片通道是4通道的,还有一个透明度通道,自己用Windows的绘制进行转换
        # 输入的格式必须是numpy的array格式。验证表示tf的tensor 会报错
        # 上面这几个需要根据自己的实际情况来改动。
        img = np.array(Image.open('./dog.jpg').resize((224, 224)))
        img = img[np.newaxis, :]
        print(img.shape)
    
        # 打印输出
        ret = sess.run(output_tenosr, feed_dict={input_img: img})
        print(np.array(ret).sum())

    saved model 使用tag

    为什么要使用tag
      可以自己定义tag,在签名的定义上更加灵活。
    tag的用途
        一个模型可以包含不同的MetaGraphDef,
    什么时候需要多个MetaGraphDef呢?
          也许你想保存图形的CPU版本和GPU版本,或者你想区分训练和发布版本。
        这个时候tag就可以用来区分不同的MetaGraphDef,加载的时候能够根据tag来加载模型的不同计算图。
    
      在simple_save方法中,系统会给一个默认的tag: “serve”,也可以用tag_constants.SERVING这个常量。
    tf.identity(y, name="myOutput")#将identity加到y上面就表示对y进行重命名
  • 相关阅读:
    使用WebViewJavascriptBridge与UIWebView交互
    使用UICollectionView
    UIButton中的**EdgeInsets是做什么用的?
    [翻译] CoreImage-with-EAGLContext
    [翻译] SAMCoreImageView
    [翻译] NSImage+HHTint
    使用iCarousel的旋转木马效果请求图片
    使用TFHpple解析html
    使用MapKit框架(持续更新)
    定制UITabBar显示样式
  • 原文地址:https://www.cnblogs.com/yunshangyue71/p/13611276.html
Copyright © 2011-2022 走看看