本节涉及点:

  1. 保存训练过程
  2. 载入保存的训练过程并继续训练
  3. 通过命令行参数控制是否强制重新开始训练
  4. 训练过程中的手动保存
  5. 保存训练过程前,程序征得同意

一、保存训练过程

以下方代码为例:

import tensorflow as tf
import random random.seed()
x = tf.placeholder(tf.float32)
yTrain = tf.placeholder(tf.float32)
w1 = tf.Variable(tf.random_normal([4, 8], mean=0.5, stddev=0.1), dtype=tf.float32)
b1 = tf.Variable(0, dtype=tf.float32)
xr = tf.reshape(x, [1, 4])
n1 = tf.nn.tanh(tf.matmul(xr, w1) + b1)
w2 = tf.Variable(tf.random_normal([8, 2], mean=0.5, stddev=0.1), dtype=tf.float32)
b2 = tf.Variable(0, dtype=tf.float32)
n2 = tf.matmul(n1, w2) + b2
y = tf.nn.softmax(tf.reshape(n2, [2]))
loss = tf.reduce_mean(tf.square(y - yTrain))
optimizer = tf.train.RMSPropOptimizer(0.01)
train = optimizer.minimize(loss)
sess = tf.Session()
sess.run(tf.global_variables_initializer())
lossSum = 0.0 for i in range(5):
xDataRandom = [int(random.random() * 10), int(random.random() * 10), int(random.random() * 10), int(random.random() * 10)]
if xDataRandom[2] % 2 == 0:
yTrainDataRandom = [0, 1]
else:
yTrainDataRandom = [1, 0]
result = sess.run([train, x, yTrain, y, loss], feed_dict={x: xDataRandom, yTrain: yTrainDataRandom})
lossSum = lossSum + float(result[len(result) - 1])
print("i: %d, loss: %10.10f, avgLoss: %10.10f" % (i, float(result[len(result) - 1]), lossSum / (i + 1)))
trainResultPath = "./save/idcard2" print("saving...")
tf.train.Saver().save(sess, save_path=trainResultPath)
i: 0, loss: 0.2790884972, avgLoss: 0.2790884972
i: 1, loss: 0.2675500214, avgLoss: 0.2733192593
i: 2, loss: 0.2441657931, avgLoss: 0.2636014372
i: 3, loss: 0.2675784826, avgLoss: 0.2645956986
i: 4, loss: 0.2452606559, avgLoss: 0.2607286900
saving...
'./save/idcard2'

解析:

首先用一个变量 trainResultPath 来指定保存训练过程数据的目录

这是一个字符串类型的变量,其中的小数点 “ . ” 表示 Python 程序执行的当前目录, “ / ” 用于分隔目录和子目录(windows 中一般用反斜杠 " \ " 来分隔 ),一般采用Linux 目录中的写法,兼容性更好

./save/idcard2 表示 保存的位置是 执行程序 idcard2.py 的目录的 save 的子目录下以 idcard2 为基本名称的一系列文件

下方图片中,以 idcard2 开头的文件分别保存了 模型和可变参数的信息,checkpoint 文件保存了一些基础信息

  • “.meta”文件:包含图形结构。
  • “.data”文件:包含变量的值。
  • “.index”文件:标识检查点。
  • “checkpoint”文件:具有最近检查点列表的协议缓冲区。

tf.train.Saver().save(sess, save_path=trainResultPath) 

调用 tensorflow 下的train 包中的 saver 对象的 save 成员函数进行保存,第一个参数 纯如当前的会话对象(本程序中 是 sess),第二个参数 save_path 传入保存位置

二、载入保存的训练过程并继续训练

如果已经保存了训练数据,就可以用下面的代码 载入训练数据并继续训练

注意:如果使用的是 jupyter ,请再运行完毕 上方的代码 并保存结果到 ./save/idcard2 之后

重启服务再运行下方的代码,以免报错 NotFoundError: Key Variable_10 not found in checkpoint

import tensorflow as tf
import random
import os trainResultPath = "./save/idcard2" random.seed() x = tf.placeholder(tf.float32)
yTrain = tf.placeholder(tf.float32) w1 = tf.Variable(tf.random_normal([4, 8], mean=0.5, stddev=0.1), dtype=tf.float32)
b1 = tf.Variable(0, dtype=tf.float32) xr = tf.reshape(x, [1, 4]) n1 = tf.nn.tanh(tf.matmul(xr, w1) + b1) w2 = tf.Variable(tf.random_normal([8, 2], mean=0.5, stddev=0.1), dtype=tf.float32)
b2 = tf.Variable(0, dtype=tf.float32) n2 = tf.matmul(n1, w2) + b2 y = tf.nn.softmax(tf.reshape(n2, [2])) loss = tf.reduce_mean(tf.square(y - yTrain)) optimizer = tf.train.RMSPropOptimizer(0.01) train = optimizer.minimize(loss) sess = tf.Session()
# 因为数据文件不只一个,所以随便挑选一个文件判断数据是否存在
# 但是不要挑选 checkpoint ,因为这个文件不随我们指定的前缀名而变化
if os.path.exists(trainResultPath + ".index"):
print("loading: %s" % trainResultPath)
tf.train.Saver().restore(sess, save_path=trainResultPath)
else:
print("train result path not exists: %s" % trainResultPath)
sess.run(tf.global_variables_initializer()) lossSum = 0.0 for i in range(5): xDataRandom = [int(random.random() * 10), int(random.random() * 10), int(random.random() * 10), int(random.random() * 10)]
if xDataRandom[2] % 2 == 0:
yTrainDataRandom = [0, 1]
else:
yTrainDataRandom = [1, 0] result = sess.run([train, x, yTrain, y, loss], feed_dict={x: xDataRandom, yTrain: yTrainDataRandom}) lossSum = lossSum + float(result[len(result) - 1]) print("i: %d, loss: %10.10f, avgLoss: %10.10f" % (i, float(result[len(result) - 1]), lossSum / (i + 1))) print("saving...")
tf.train.Saver().save(sess, save_path=trainResultPath)
loading: ./save/idcard2
INFO:tensorflow:Restoring parameters from ./save/idcard2
i: 0, loss: 0.2710282207, avgLoss: 0.2710282207
i: 1, loss: 0.2567882836, avgLoss: 0.2639082521
i: 2, loss: 0.2574761510, avgLoss: 0.2617642184
i: 3, loss: 0.2574799955, avgLoss: 0.2606931627
i: 4, loss: 0.2419599444, avgLoss: 0.2569465190
saving...
'./save/idcard2'

原因详情见博客:

https://blog.csdn.net/haiqingonly/article/details/80921802

摘要如下:

问题1:TensorFlow:Unsuccessful TensorSliceReader constructor: Failed to find any matching files
问题2:NotFoundError: Key Variable_10 not found in checkpoint山重水复疑无路,柳暗花明又一村。
问题1:多次遇到训练模型save之后,重新restore提示Failed to find any matching files。
分析原因:因为自定义的绝对路径报错,我的自定义路径(D:\\test\\pictures\\faces),这个问题算是tensorflow的bug。
修改方法:所有路径全部用当前运行路径上一级路径形式(.\\faces):
保存训练模型:
saver = tf.train.Saver()
sess = tf.Session()
save_path=saver.save(sess, '.\\save_net.ckpt')
恢复训练模型:
saver=tf.train.Saver()
sess = tf.Session() saver.restore(sess,tf.train.latest_checkpoint('.')) 至于我自定义的绝对路径为什么不能追踪找到,下一步再探索。 问题2:保存后模型恢复出来用于测试:NotFoundError: Key Variable_10 not found in checkpoint
分析原因:如果模型训练完保存后直接加载,相当于变量在前后定义了两次,第一次创建的变量name="weight",测试时
创建的变量虽然name="weight",但是实际上name会变成"weight_1"(weight_n-1),我们在保存的checkpoint中搜索的就是
weight_n-1,因为搜索不到所以会报错。 网上各种查找后有两种解决方法:
(1)在加载过程中,定义 name 相同的变量前面加 tf.reset_default_graph() 清除默认图的堆栈,并设置全局图为默认图 ;
(2)保存模型后,不马上加载,或 restart kernel后,再加载测试,又不会出错。 我自己尝试了第二种方法,因为第二种方法简单,确实可行。 希望能够帮到遇到和我一样问题的朋友。

Tensorflow save&restore遇到问题及解决

代码解读:

  • 载入训练数据的时候需要用到数据文件保存位置的信息,所以把 定义 trainResultPath 语句提前
  • 定义完会话变量 sess 后,不是像以前马上调用 sess.run(tf.global_variables_initializer()) 来对可变参数进行初始化,因为要载入训练数据,就不能做初始化操作,否则所有的可变参数又被复原成初始值了。
  • 之后,加了一个代码判断该目录下是否存有保存了的训练过程文件,有就载入,没有就初始化变量。
  • 使用 tf.train.Saver().restore(sess,save_path = trainResultPath)  载入训练数据,与保存时的 save 函数一样,都是传入 会话变量和保存路径两个参数。save 是保存,restore 是载入训练过程
  • 判断是否存在已保存的训练过程数据文件,使用 os 包中的 os.path.exists 函数。

代码的执行结果如上,可见已成功载入了指定位置的训练过程数据,并且接下来的误差值逐渐变小,可见,载入成功

三、通过命令行参数控制是否强制重新开始训练

如何强制重新开始训练?

  1. 可以把保存的数据和文件都删除
  2. 命令行参数控制

命令行参数:

python xxx.py

对于整个命令,"python" 就是 命令体,后面的程序名称就是它的命令行参数

命令体与命令行参数用空格隔开,命令行参数可有多个,其中也是用空格隔开

如果命令行参数自身就带空格:

python "c:\my documents\xxx\xxx.py"

导入 sys包 --->   sys.argv  获得命令行参数,返回一个 一维数组

载入训练过程前,通过判断命令行参数决定是否强制重新训练:

import tensorflow as tf
import random
import os
import sys ifRestartT = False argt = sys.argv[1:]
# [1:] 切片,返回从数组下标1开始到数组最后一项的子数组
for v in argt:
if v == "-restart":
ifRestartT = True
# 用一个循环判断 命令行参数数组是否有“-restart” ,有就是 ifRestartT = true
# 来控制之后 强制执行初始化可变参数 trainResultPath = "./save/idcard2" random.seed() x = tf.placeholder(tf.float32)
yTrain = tf.placeholder(tf.float32) w1 = tf.Variable(tf.random_normal([4, 8], mean=0.5, stddev=0.1), dtype=tf.float32)
b1 = tf.Variable(0, dtype=tf.float32) xr = tf.reshape(x, [1, 4]) n1 = tf.nn.tanh(tf.matmul(xr, w1) + b1) w2 = tf.Variable(tf.random_normal([8, 2], mean=0.5, stddev=0.1), dtype=tf.float32)
b2 = tf.Variable(0, dtype=tf.float32) n2 = tf.matmul(n1, w2) + b2 y = tf.nn.softmax(tf.reshape(n2, [2])) loss = tf.reduce_mean(tf.square(y - yTrain)) optimizer = tf.train.RMSPropOptimizer(0.01) train = optimizer.minimize(loss) sess = tf.Session() if ifRestartT == True:
print("force restart...")
sess.run(tf.global_variables_initializer()) #可变参数强制初始化,重新开始训练
elif os.path.exists(trainResultPath + ".index"):
print("loading: %s" % trainResultPath)
tf.train.Saver().restore(sess, save_path=trainResultPath)
else:
print("train result path not exists: %s" % trainResultPath)
sess.run(tf.global_variables_initializer()) lossSum = 0.0 for i in range(5): xDataRandom = [int(random.random() * 10), int(random.random() * 10), int(random.random() * 10), int(random.random() * 10)]
if xDataRandom[2] % 2 == 0:
yTrainDataRandom = [0, 1]
else:
yTrainDataRandom = [1, 0] result = sess.run([train, x, yTrain, y, loss], feed_dict={x: xDataRandom, yTrain: yTrainDataRandom}) lossSum = lossSum + float(result[len(result) - 1]) print("i: %d, loss: %10.10f, avgLoss: %10.10f" % (i, float(result[len(result) - 1]), lossSum / (i + 1))) print("saving...")
tf.train.Saver().save(sess, save_path=trainResultPath)

四、训练过程中的手动保存

在训练中,随时随地的保存训练数据:

import tensorflow as tf
import random
import os
import sys ifRestartT = False argt = sys.argv[1:] for v in argt:
if v == "-restart":
ifRestartT = True trainResultPath = "./save/idcard2" random.seed() x = tf.placeholder(tf.float32)
yTrain = tf.placeholder(tf.float32) w1 = tf.Variable(tf.random_normal([4, 8], mean=0.5, stddev=0.1), dtype=tf.float32)
b1 = tf.Variable(0, dtype=tf.float32) xr = tf.reshape(x, [1, 4]) n1 = tf.nn.tanh(tf.matmul(xr, w1) + b1) w2 = tf.Variable(tf.random_normal([8, 2], mean=0.5, stddev=0.1), dtype=tf.float32)
b2 = tf.Variable(0, dtype=tf.float32) n2 = tf.matmul(n1, w2) + b2 y = tf.nn.softmax(tf.reshape(n2, [2])) loss = tf.reduce_mean(tf.square(y - yTrain)) optimizer = tf.train.RMSPropOptimizer(0.01) train = optimizer.minimize(loss) sess = tf.Session() if ifRestartT == True:
print("force restart...")
sess.run(tf.global_variables_initializer())
elif os.path.exists(trainResultPath + ".index"):
print("loading: %s" % trainResultPath)
tf.train.Saver().restore(sess, save_path=trainResultPath)
else:
print("train result path not exists: %s" % trainResultPath)
sess.run(tf.global_variables_initializer()) lossSum = 0.0 for i in range(500000): xDataRandom = [int(random.random() * 10), int(random.random() * 10), int(random.random() * 10), int(random.random() * 10)]
if xDataRandom[2] % 2 == 0:
yTrainDataRandom = [0, 1]
else:
yTrainDataRandom = [1, 0] result = sess.run([train, x, yTrain, y, loss], feed_dict={x: xDataRandom, yTrain: yTrainDataRandom}) lossSum = lossSum + float(result[len(result) - 1]) print("i: %d, loss: %10.10f, avgLoss: %10.10f" % (i, float(result[len(result) - 1]), lossSum / (i + 1))) if os.path.exists("save.txt"):
os.remove("save.txt")
print("saving...")
tf.train.Saver().save(sess, save_path=trainResultPath)
print("saving...")
tf.train.Saver().save(sess, save_path=trainResultPath)

可以随时保存代码的核心: 

通过 os.path.exists("save.txt") 判断是否存在一个文件 save.txt ,如果存在,将该文件删除【防止一直保存】,保存训练数据。

五、保存训练过程前,程序征得同意

实现每次训练完毕后,如果结果不满意,希望可以不要保存这一回训练的结果,实现程序可以在保存前询问一下,再执行是否保存训练结果

import tensorflow as tf
import random
import os
import sys ifRestartT = False argt = sys.argv[1:] for v in argt:
if v == "-restart":
ifRestartT = True trainResultPath = "./save/idcard2" random.seed() x = tf.placeholder(tf.float32)
yTrain = tf.placeholder(tf.float32) w1 = tf.Variable(tf.random_normal([4, 8], mean=0.5, stddev=0.1), dtype=tf.float32)
b1 = tf.Variable(0, dtype=tf.float32) xr = tf.reshape(x, [1, 4]) n1 = tf.nn.tanh(tf.matmul(xr, w1) + b1) w2 = tf.Variable(tf.random_normal([8, 2], mean=0.5, stddev=0.1), dtype=tf.float32)
b2 = tf.Variable(0, dtype=tf.float32) n2 = tf.matmul(n1, w2) + b2 y = tf.nn.softmax(tf.reshape(n2, [2])) loss = tf.reduce_mean(tf.square(y - yTrain)) optimizer = tf.train.RMSPropOptimizer(0.01) train = optimizer.minimize(loss) sess = tf.Session() if ifRestartT == True:
print("force restart...")
sess.run(tf.global_variables_initializer())
elif os.path.exists(trainResultPath + ".index"):
print("loading: %s" % trainResultPath)
tf.train.Saver().restore(sess, save_path=trainResultPath)
else:
print("train result path not exists: %s" % trainResultPath)
sess.run(tf.global_variables_initializer()) lossSum = 0.0 for i in range(5): xDataRandom = [int(random.random() * 10), int(random.random() * 10), int(random.random() * 10), int(random.random() * 10)]
if xDataRandom[2] % 2 == 0:
yTrainDataRandom = [0, 1]
else:
yTrainDataRandom = [1, 0] result = sess.run([train, x, yTrain, y, loss], feed_dict={x: xDataRandom, yTrain: yTrainDataRandom}) lossSum = lossSum + float(result[len(result) - 1]) print("i: %d, loss: %10.10f, avgLoss: %10.10f" % (i, float(result[len(result) - 1]), lossSum / (i + 1))) if os.path.exists("save.txt"):
os.remove("save.txt")
print("saving...")
tf.train.Saver().save(sess, save_path=trainResultPath) resultT = input('Would you like to save? (y/n)')
# 提示语句,输出: Would you like to save? (y/n) 并将输入保存至 resultT
if resultT == "y":
print("saving...")
tf.train.Saver().save(sess, save_path=trainResultPath)

运行结果如下:

也可以配合 Ctrl + C 终止 Python 程序的运行,避免低效率的训练

Tensorflow 保存和载入训练过程的更多相关文章

  1. TensorFlow保存和载入模型

    首先定义一个tf.train.Saver类: saver = tf.train.Saver(max_to_keep=1) 其中,max_to_keep参数设定只保存最后一个参数,默认值是5,即保存最后 ...

  2. tensorflow笔记:模型的保存与训练过程可视化

    tensorflow笔记系列: (一) tensorflow笔记:流程,概念和简单代码注释 (二) tensorflow笔记:多层CNN代码分析 (三) tensorflow笔记:多层LSTM代码分析 ...

  3. tensorflow:模型的保存和训练过程可视化

    在使用tf来训练模型的时候,难免会出现中断的情况.这时候自然就希望能够将辛辛苦苦得到的中间参数保留下来,不然下次又要重新开始. 保存模型的方法: #之前是各种构建模型graph的操作(矩阵相乘,sig ...

  4. TensorFlow从1到2(七)线性回归模型预测汽车油耗以及训练过程优化

    线性回归模型 "回归"这个词,既是Regression算法的名称,也代表了不同的计算结果.当然结果也是由算法决定的. 不同于前面讲过的多个分类算法或者逻辑回归,线性回归模型的结果是 ...

  5. 『TensorFlow』模型保存和载入方法汇总

    『TensorFlow』第七弹_保存&载入会话_霸王回马 一.TensorFlow常规模型加载方法 保存模型 tf.train.Saver()类,.save(sess, ckpt文件目录)方法 ...

  6. (原)tensorflow保存模型及载入保存的模型

    转载请注明出处: http://www.cnblogs.com/darkknightzh/p/7198773.html 参考网址: http://stackoverflow.com/questions ...

  7. Tensorflow 从文件中载入训练数据

    本节包含: 用纯文本文件准备训练数据 加载文件中的训练数据 一.用纯文本文件准备训练数据 1.数据的数字化 比如,“是” —— “1”,“否” —— “0” “优”,“中”,“差” —— 1 2 3  ...

  8. TensorFlow之tf.nn.dropout():防止模型训练过程中的过拟合问题

    一:适用范围: tf.nn.dropout是TensorFlow里面为了防止或减轻过拟合而使用的函数,它一般用在全连接层 二:原理: dropout就是在不同的训练过程中随机扔掉一部分神经元.也就是让 ...

  9. tensorflow训练过程中内存溢出

    罪魁祸首是训练过程中给模型传值时的如下语句:

随机推荐

  1. Zabbix Server安装指南

    监控模板网站 在https://share.zabbix.com/,提供了各种各样的监控模板,可以自行搜索,套用.

  2. Java程序中实现 MySQL数据库的备份与还原

    案例代码: 数据库备份 //mysqldump -h端口号 -u用户 -p密码 数据库 > d:/test.sql --备份D盘 //备份 public static void dataBase ...

  3. hive常用日期函数-模板

    已知日期 要求日期 语句 结果 本周任意一天 本周一 select date_sub(next_day('2016-11-29','MO'),7) ; 2016-11-28 本周任意一天 上周一 se ...

  4. [人物存档]【AI少女】【捏脸数据】1222今日份的推荐

    AISChaF_20191030183624290.png

  5. Linux内核概述

    概述 1. 多数服务器都是Linux,Windows只在PC方面应用. 2. .NET只能在Windows中应用,适用于中小型项目,在大型项目中应用很少.现在出现了Windows服务器(外围的服务器) ...

  6. 【BZOJ4176】 Lucas的数论

    Description 去年的Lucas非常喜欢数论题,但是一年以后的Lucas却不那么喜欢了. 在整理以前的试题时,发现了这样一道题目“求Sigma(f(i)),其中1<=i<=N”,其 ...

  7. HFUUOJ1023 闷声发大财 概率dp

    题意 xyq有\(n\)个骰子,第\(i\)个骰子有\(a_i\)面,每次xyq都会把\(n\)个骰子搞一遍,其中的最小值作为结果,问最终结果的期望\(\mod (10^9+7 )\). 分析 lfx ...

  8. BZOJ 5267 特工 (类FWT)

    题意 题解 从大到小枚举\(l\), 把一个序列从\(2^{l+1}\)分成两个独立的\(2^l\),去除两半的影响. 设去除前的序列为\(b\), 去除后序列为\(b'\) 则有\(b_{2^{l+ ...

  9. Vue_(组件通讯)单项数据流

    Vue单项数据流 传送门 单向数据流:父组件值的更新,会影响到子组件,反之则不行 修改子组件的值: 局部数据:在子组件中定义新的数据,将父组件传过来的值赋值给新定义的数据,之后操作这个新数据 如果对数 ...

  10. JavaWeb-SpringBoot(抖音)_二、服务器间通讯

    JavaWeb-SpringBoot(抖音)_一.抖音项目制作 传送门 JavaWeb-SpringBoot(抖音)_二.服务器间通讯 传送门 JavaWeb-SpringBoot(抖音)_三.抖音项 ...