MNIST 数字识别和数据持久化--step by step 入门TensorFlow(三)

时间:2022-02-12 22:04:26

MNIST 数字识别和数据持久化–step by step 入门TensorFlow(三)

标签:tensorflow


我们将采用Jupyter notebook交互式编程的方式,通过一步步代码的讲解,学习Tensorflow 编程。推荐使用Jupyter notebook作为开发环境按照文中的代码step by step 的学习。

文章列表:
Tensorflow基础知识与神经网络构建–step by step 入门TensorFlow(一)
深层神经网络实现–step by step 入门TensorFlow(二)
MNIST 数字识别和数据持久化–step by step 入门TensorFlow(三)

一个完整的MNIST 数字识别代码

import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
# 数据集参数
input_dim = 784
output_dim = 104
# 神经网络参数
h1_dim = 500
batch_size = 100
learning_rate_base = 0.8
learning_rate_decay = 0.99 # 学习率的衰减率
regularization_rate = 0.0001 # 正则化项系数
training_step = 30000
moving_average_decay = 0.99 # 滑动平均衰减率

def net(input_tensor, avg_class, w1,b1,w2,b2):
# 不使用滑动平均类
if avg_class == None:
h1 = tf.nn.relu(tf.matmul(input_tensor, w1) + b1)
output = tf.matmul(h1, w2) + b2
return output
# 使用滑动平均类
else:
h1 = tf.nn.relu(tf.matmul(input_tensor, avg_class.average(w1) + avg_class.average(b1)))
return tf.matmul(h1,avg_class.average(w2) + avg_class.average(b2))

def train(mnist):
x = tf.placeholder(tf.float32, shape=[None,784], name="x_input")
y_ = tf.placeholder(tf.float32, shape=[None, 10], name="y_input")

w1 = tf.Variable(tf.truncated_normal([input_dim, h1_dim], stddev=0.1))
b1 = tf.Variable(tf.constant(0.1, shape=[h1_dim]))
w2 = tf.Variable(tf.truncated_normal([h1_dim, output_dim], stddev=0.1))
b2 = tf.Variable(tf.constant(0.1, shape=[output_dim]))

y = net(x, None, w1, b1, w2, b2)
# 使用滑动平均
global_step = tf.Variable(0, trainable=False)
variable_averages = tf.train.ExponentialMovingAverage(moving_average_decay,global_step)
variable_averages_op = variable_averages.apply(tf.trainable_variables())

average_y = net(x, variable_averages, w1, b1, w2, b2)

# argmax(y_, 1) 提取第1维度最大的,即为1的那个,即把10个数的向量变为1个数的答案
cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=y, labels=tf.argmax(y_, 1))
cross_entropy_mean = tf.reduce_mean(cross_entropy)

# 计算L2正则化损失函数
regularizer = tf.contrib.layers.l2_regularizer(regularization_rate)
regularization =regularizer(w1) + regularizer(w2)

# 总损失
loss = cross_entropy_mean + regularization
learning_rate = tf.train.exponential_decay(learning_rate_base,
global_step,
mnist.train.num_examples / batch_size,
learning_rate_decay)
train_step = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss, global_step=global_step)
train_op = tf.group(train_step, variable_averages_op)
# average是batch*10的二维数组,tf.argmax选取第1维最大的坐标,也就识别结果,得到一个长度为batch的数组,equal判断数组的每一维是否相等,,相等则该维结果为True
correct_prediction = tf.equal(tf.argmax(average_y,1), tf.argmax(y_,1))
accuarcy = tf.reduce_mean(tf.cast(correct_prediction,tf.float32))
with tf.Session() as sess:
tf.global_variables_initializer().run()
#tf.global_variables_initialize().run()
validate_feed = {x:mnist.validation.images, y_:mnist.validation.labels}
test_feed = {x:mnist.test.images, y_:mnist.test.labels}
for i in range(training_step):
# 每1000轮测试一次
if i % 1000 == 0:
# 用全部的数据集验证
validata_acc = sess.run(accuarcy, feed_dict=validate_feed)
print("%d step vali accuarcy %g" % (i, validata_acc))
xs, ys = mnist.train.next_batch(batch_size)
sess.run(train_op, feed_dict={x:xs, y_:ys})

test_acc = sess.run(accuarcy, feed_dict = test_feed)
print("test accuarcy %d " % test_acc)

def main(argv=None):
# print("ll")
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
# print("hh")
train(mnist)

if __name__ == '__main__':
# print("kk")
tf.app.run()





变量管理

在名字为foo的空间里创建名字为v的变量

import tensorflow as tf
with tf.variable_scope("foo"):
v = tf.get_variable("v", [1], initializer=tf.constant_initializer(3.0))
print(v)
<tf.Variable 'foo/v:0' shape=(1,) dtype=float32_ref>
# 已存在不可重复创建
with tf.variable_scope("foo"):
v = tf.get_variable("v", [1])
print(v)
---------------------------------------------------------------------------

ValueError Traceback (most recent call last)

<ipython-input-30-5a42879cdb76> in <module>()
1 with tf.variable_scope("foo"):
----> 2 v = tf.get_variable("v", [1])
3 print(v)


ValueError: Variable foo/v already exists, disallowed. Did you mean to set reuse=True in VarScope? Originally defined at:
# reuse就可调用原来创建的变量
with tf.variable_scope("foo", reuse=True):
v = tf.get_variable("v",[1])
print(v)
<tf.Variable 'foo/v:0' shape=(1,) dtype=float32_ref>
# 不同变量域,变量之前未创建不可reuse=true
with tf.variable_scope("acc",reuse=True):
v = tf.get_variable("v", [1])
print(v)
---------------------------------------------------------------------------

ValueError Traceback (most recent call last)

<ipython-input-32-4a89d8c222e3> in <module>()
1 with tf.variable_scope("acc",reuse=True):
----> 2 v = tf.get_variable("v", [1])
3 print(v)


...

ValueError: Variable acc/v does not exist, or was not created with tf.get_variable(). Did you mean to set reuse=None in VarScope?
# 嵌套中的reuse
with tf.variable_scope("root"):
print(tf.get_variable_scope().reuse)
with tf.variable_scope("go", reuse=True):
print(tf.get_variable_scope().reuse)
with tf.variable_scope("went"):
print(tf.get_variable_scope().reuse)
print(tf.get_variable_scope().reuse)
False
True
True
False
# 变量管理
v1 = tf.get_variable("v", [1])
print(v1.name)
with tf.variable_scope("root"):
v2 = tf.get_variable("v",[1])
print(v2.name)
with tf.variable_scope("first"):
with tf.variable_scope("second"):
v3 = tf.get_variable("v",[1])
print(v3.name)
v4 = tf.get_variable("v",[1])
print(v4.name)

with tf.variable_scope("",reuse=True):
v5 = tf.get_variable("first/second/v")
v6 = tf.get_variable("root/v")

print(v5==v3)
print(v6==v2)


v:0
root/v:0
first/second/v:0
first/v:0
True
True

tensorflow持久化

import tensorflow as tf
v1 = tf.Variable(tf.constant(1.3), [1], name='v1')
v2 = tf.Variable(tf.constant(.5),[1], name='v2')
re = v1+v2
saver = tf.train.Saver()
init_op = tf.global_variables_initializer()

with tf.Session() as sess:
sess.run(init_op)
saver.save(sess,"checkpoint/model.ckpt")
# 读取
v1 = tf.Variable(tf.constant(1.3), [1], name='v1')
v2 = tf.Variable(tf.constant(2.5),[1], name='v2')
re = v1+v2
saver = tf.train.Saver({"v1":v1,"v2":v2})


with tf.Session() as sess:
saver.restore(sess,"checkpoint/model.ckpt")
print(re.eval())
INFO:tensorflow:Restoring parameters from checkpoint/model.ckpt
1.8
# 在滑动平均值可以运用
import tensorflow as tf
v = tf.Variable(1,dtype=tf.float32,name="v")
for i in tf.global_variables():
print(i.name)
ema = tf.train.ExponentialMovingAverage(0.99)
avg_op = ema.apply(tf.global_variables())
for i in tf.global_variables():
print(i.name)
v:0
v:0
v/ExponentialMovingAverage:0

利用convert_variables_to_constants函数将变量及其取值以常量的方式保存

import tensorflow as tf
from tensorflow.python.framework import graph_util
v1 = tf.Variable(tf.constant(0.1),[1],name='v1')
v2 = tf.Variable(tf.constant(0.5),[1],name='v2')
re = v1+v2
init = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init)
graph_def = tf.get_default_graph().as_graph_def()
# 变量变为常数保存
output_graph_def = graph_util.convert_variables_to_constants(
sess, graph_def, ['add'])
# 将导出的模型存入文件
with tf.gfile.GFile("checkpoint/constant_model.pb","wb") as f:
f.write(output_graph_def.SerializeToString())

INFO:tensorflow:Froze 2 variables.
Converted 2 variables to const ops.
import tensorflow as tf
from tensorflow.python.platform import gfile

with tf.Session() as sess:
model_name = "check_point/constant_model.pb"
with gfile.FastGFile(model_name,"rb") as f:
graph_def = tf.GraphDef()
graph_def.ParseFromString(f.read())
result = tf.import_graph_def(graph_def,return_elements={"add:0"})
print(sess.run(result))

持久化原理及数据格式

import tensorflow as tf
v1 = tf.Variable(tf.constant(1.0),[1],name="v1")
v2 = tf.Variable(tf.constant(2.0),[1],name="w2")
result =v1+v2
saver = tf.train.Saver()
saver.export_meta_graph("checkpoint/model.cpk.meda.json", as_text=True)
meta_info_def {
stripped_op_list {
op {
name: "Add"
input_arg {
name: "x"
type_attr: "T"
}
input_arg {
name: "y"
type_attr: "T"
}
output_arg {
name: "z"
type_attr: "T"
}
attr {
name: "T"
type: "type"
allowed_values {
list {
type: DT_HALF
type: DT_FLOAT
type: DT_DOUBLE
type: DT_UINT8
type: DT_INT8
type: DT_INT16
type: DT_INT32
type: DT_INT64
type: DT_COMPLEX64
type: DT_COMPLEX128
type: DT_STRING
}
}
}
}
op {
name: "Assign"
input_arg {
name: "ref"
type_attr: "T"
is_ref: true
}
input_arg {
name: "value"
type_attr: "T"
}
output_arg {
name: "output_ref"
type_attr: "T"
is_ref: true
}
attr {
name: "T"
type: "type"
}
attr {
name: "validate_shape"
type: "bool"
default_value {
b: true
}
}
attr {
name: "use_locking"
type: "bool"
default_value {
b: true
}
}
allows_uninitialized_input: true
}
op {
name: "Const"
output_arg {
name: "output"
type_attr: "dtype"
}
attr {
name: "value"
type: "tensor"
}
attr {
name: "dtype"
type: "type"
}
}
op {
name: "Identity"
input_arg {
name: "input"
type_attr: "T"
}
output_arg {
name: "output"
type_attr: "T"
}
attr {
name: "T"
type: "type"
}
}
op {
name: "NoOp"
}
op {
name: "RestoreV2"
input_arg {
name: "prefix"
type: DT_STRING
}
input_arg {
name: "tensor_names"
type: DT_STRING
}
input_arg {
name: "shape_and_slices"
type: DT_STRING
}
output_arg {
name: "tensors"
type_list_attr: "dtypes"
}
attr {
name: "dtypes"
type: "list(type)"
has_minimum: true
minimum: 1
}
}
op {
name: "SaveV2"
input_arg {
name: "prefix"
type: DT_STRING
}
input_arg {
name: "tensor_names"
type: DT_STRING
}
input_arg {
name: "shape_and_slices"
type: DT_STRING
}
input_arg {
name: "tensors"
type_list_attr: "dtypes"
}
attr {
name: "dtypes"
type: "list(type)"
has_minimum: true
minimum: 1
}
}
op {
name: "VariableV2"
output_arg {
name: "ref"
type_attr: "dtype"
is_ref: true
}
attr {
name: "shape"
type: "shape"
}
attr {
name: "dtype"
type: "type"
}
attr {
name: "container"
type: "string"
default_value {
s: ""
}
}
attr {
name: "shared_name"
type: "string"
default_value {
s: ""
}
}
is_stateful: true
}
}
tensorflow_version: "1.2.1"
tensorflow_git_version: "b\'unknown\'"
}
graph_def {
node {
name: "Const"
op: "Const"
attr {
key: "_output_shapes"
value {
list {
shape {
}
}
}
}
attr {
key: "dtype"
value {
type: DT_FLOAT
}
}
attr {
key: "value"
value {
tensor {
dtype: DT_FLOAT
tensor_shape {
}
float_val: 1.0
}
}
}
}
...