在TensorFlow中,主要使用tf.train.Saver()来完成模型的保存。主要的步骤如下:
1、设置保存模型的目录。
我们在本地设置一个叫做ckpt的文件夹来保存模型CKPT_DIR='ckpt'
2、在模型保存文件中读取状态ckpt = tf.train.get_checkpoint_state(CKPT_DIR)
3、定义一个saver,即保存模型的对象。saver=tf.train.Saver()
4、如果在保存模型里已经有一部分训练模型结果,那么恢复出来。
if ckpt and ckpt.model_checkpoint_path:
saver.restore(sess,ckpt.model_checkpoint_path)
5、经过一定轮数的训练后保存训练模型
saver.save(sess,CKPT_DIR+'/model',global_step=i)
如此这样,我们就可以把训练模型结果保存在ckpt文件夹了。
下面我们通过实例展示一下如何保存训练模型,我们使用多隐层来训练手写数字识别,其具体算法可以见之前的博客https://blog.csdn.net/weixin_45690272/article/details/102964406的"多隐藏层神经网络手写数字识别"一节。那么,在保存训练模型中,根据前一节步骤具体代码如下:
import warnings
warnings.filterwarnings('ignore')
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
CKPT_DIR='ckpt'
mnist_data=input_data.read_data_sets('mnist_data/',one_hot=True) #获取mnist数据
#设置超参数
batch_size=100 #每一轮数据量大小
learning_rate=0.8 #初始学习率
learning_rate_decay=0.999 #学习率的衰减
max_steps=1000 #最大训练步数
training_step=tf.Variable(0,trainable=False)
#定义隐藏层函数
def hidden_layer(input_tensor,weights1,biases1,weights2,biases2,layer_name):
layer1=tf.nn.relu(tf.matmul(input_tensor,weights1)+biases1) #第一层隐藏层采用了relu激活函数
return tf.matmul(layer1,weights2)+biases2 #第二层没有采用激活函数,即输出层
x=tf.placeholder(tf.float32,[None,784]) #训练数据集的输入,有784维个特征
y_=tf.placeholder(tf.float32,[None,10]) #训练数据的标签,10分类
weights1=tf.Variable(tf.truncated_normal([784,500],stddev=0.1),name='weight1') #权重1
biases1=tf.Variable(tf.truncated_normal([1,500],stddev=0.1),name='biases1' ) #偏值1
weights2=tf.Variable(tf.truncated_normal([500,10],stddev=0.1),name='weight2') #权重2
biases2=tf.Variable(tf.truncated_normal([1,10],stddev=0.1),name='biases2') #偏值2
y=hidden_layer(x,weights1,biases1,weights2,biases2,'y') #训练数据经过计算之后的结果。
#参数更新
averages_class=tf.train.ExponentialMovingAverage(0.99,training_step)
averages_op=averages_class.apply(tf.trainable_variables())
average_y=hidden_layer(x,averages_class.average(weights1),
averages_class.average(biases1),
averages_class.average(weights2),
averages_class.average(biases2),
'average_y')
#交叉熵
cross_entropy=tf.nn.sparse_softmax_cross_entropy_with_logits(logits=y,labels=tf.argmax(y_,1))
#正则化
regular=tf.contrib.layers.l2_regularizer(0.0001)
regulation=regular(weights1)+regular(weights2)
#总的损失函数
loss=tf.reduce_mean(cross_entropy)+regulation
#学习率更新
learning_rate=tf.train.exponential_decay(learning_rate,training_step,mnist_data.train.num_examples/batch_size,learning_rate_decay)
train_step=tf.train.GradientDescentOptimizer(learning_rate).minimize(loss,global_step=training_step)
# train_op=tf.group(train_step)
with tf.control_dependencies([train_step,averages_op]):
train_op=tf.no_op(name='train')
#评估模型
init=tf.global_variables_initializer()
correct_prediction = tf.equal(tf.argmax(average_y, 1), tf.argmax(y_, 1)) # 这行代码的目的是对比预测值y与标签y_是否匹配
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
# 这行代码会给我们一组布尔值。为了确定正确预测项的比例,我们可以把布尔值转换成浮点数,然后取平均值。例如,[True, False, True, True] 会变成 [1,0,1,1] ,取平均值后得到 0.75.
with tf.Session() as sess:
sess.run(init)
validate_feed={
x:mnist_data.validation.images,y_:mnist_data.validation.labels}
test_feed={
x:mnist_data.test.images,y_:mnist_data.test.labels}
ckpt = tf.train.get_checkpoint_state(CKPT_DIR)
saver=tf.train.Saver()
if ckpt and ckpt.model_checkpoint_path:
saver.restore(sess,ckpt.model_checkpoint_path)
for i in range(max_steps):
if i % 100 == 0:
validate_accuracy=sess.run(accuracy, feed_dict=validate_feed)
print('validate_accuracy',validate_accuracy)
saver.save(sess,CKPT_DIR+'/model',global_step=i)
batch_x,batch_y=mnist_data.train.next_batch(batch_size)
sess.run(train_op,feed_dict={
x:batch_x, y_:batch_y})
print(' accuracy is ',sess.run(accuracy, feed_dict=test_feed)) # 评估模型准确率
可以在代码中寻找步骤所添加的代码。运行结果准确率达到98%。accuracy is 0.9809
。而模型的保存情况见如下目录:
保存了训练模型之后,是用来具体使用的那么如何使用呢。具体步骤是
1、读取训练模型
ckpt = tf.train.get_checkpoint_state(CKPT_DIR)
saver = tf.train.Saver()
if ckpt and ckpt.model_checkpoint_path:
saver.restore(sess, ckpt.model_checkpoint_path)
2、加载被预测信息
image_path='D:/AITFPy/tfLearing/test_images/4.png'
img=Image.open(image_path).convert('L')
flatten_img=np.reshape(img,784)
x_predict=np.array([1-flatten_img])
3、把被预测信息放入到模型计算,然后获得结果
y_predict=sess.run(y,feed_dict={
x:x_predict})
4、对比试验结果。
现在我们来测试如下手写数字识别的0和4
具体代码如下
from PIL import Image
import numpy as np
import tensorflow as tf
CKPT_DIR='ckpt'
def hidden_layer(input_tensor,weights1,biases1,weights2,biases2,layer_name):
layer1=tf.nn.relu(tf.matmul(input_tensor,weights1)+biases1) #第一层隐藏层采用了relu激活函数
return tf.matmul(layer1,weights2)+biases2 #第二层没有采用激活函数,即输出层
x=tf.placeholder(tf.float32,[None,784]) #训练数据集的输入,有784维个特征
y_=tf.placeholder(tf.float32,[None,10]) #训练数据的标签,10分类
weights1=tf.Variable(tf.truncated_normal([784,500],stddev=0.1),name='weight1') #权重1
biases1=tf.Variable(tf.truncated_normal([1,500],stddev=0.1),name='biases1' ) #偏值1
weights2=tf.Variable(tf.truncated_normal([500,10],stddev=0.1),name='weight2') #权重2
biases2=tf.Variable(tf.truncated_normal([1,10],stddev=0.1),name='biases2') #偏值2
y=hidden_layer(x,weights1,biases1,weights2,biases2,'y') #训练数据经过计算之后的结果。
init=tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init)
ckpt = tf.train.get_checkpoint_state(CKPT_DIR)
saver = tf.train.Saver()
if ckpt and ckpt.model_checkpoint_path:
saver.restore(sess, ckpt.model_checkpoint_path)
else:
raise FileNotFoundError("未保存任何模型")
image_path='D:/AITFPy/tfLearing/test_images/4.png'
img=Image.open(image_path).convert('L')
flatten_img=np.reshape(img,784)
x_predict=np.array([1-flatten_img])
y_predict=sess.run(y,feed_dict={
x:x_predict})
print(image_path)
print("predict number is ",np.argmax(y_predict[0]))
运行结果如下:
D:/AITFPy/tfLearing/test_images/4.png
predict number is 4
同样的,我们对0进行预测,结果也很理想。