您的位置:首页 > 其它

tensorflow学习(4):保存模型Saver.save()的参数命名机制以及restore并创建手写字体识别引擎

2017-03-26 22:20 761 查看

前言

上一章中我们讲到如何训练一个网络,点击查看博客,这章我们来讲tensorflow在保存网络的时候是怎么给不同的参数命名的,以及怎么将保存的参数重新restore到重构的网络结构中的。最后利用重构的网络去预测一张包含数字(0-9)的图片(任意像素)。

代码主要参考github:github地址

正文

一、如何查看保存到二进制文件中保存的参数

tensorflow同样提供了以下方法来查看保存的参数,将保存的参数读取到字典中。

from tensorflow.python import pywrap_tensorflow
reader2 = pywrap_tensorflow.NewCheckpointReader('./model2/mnistModel2-2')

dic2 = reader2.get_variable_to_shape_map()
for i in dic2:
print(i,':',dic2[i])
print(len(dic2))


可以看到上面代码的输出如下:

('Variable_7/Adam', ':', [10])
('Variable_7', ':', [10])
('Variable_6', ':', [1024, 10])
('Variable_5', ':', [1024])
('Variable_4', ':', [3136, 1024])
('Variable/Adam', ':', [5, 5, 1, 32])
('Variable_2', ':', [5, 5, 32, 64])
('Variable_1', ':', [32])
('Variable_5/Adam_1', ':', [1024])
('Variable_4/Adam_1', ':', [3136, 1024])
('Variable_2/Adam', ':', [5, 5, 32, 64])
('Variable_7/Adam_1', ':', [10])
('Variable', ':', [5, 5, 1, 32])
('Variable_5/Adam', ':', [1024])
('Variable_4/Adam', ':', [3136, 1024])
('Variable_1/Adam_1', ':', [32])
('Variable_6/Adam_1', ':', [1024, 10])
('beta2_power', ':', [])
('Variable_1/Adam', ':', [32])
('beta1_power', ':', [])
('Variable_3/Adam_1', ':', [64])
('Variable/Adam_1', ':', [5, 5, 1, 32])
('Variable_3/Adam', ':', [64])
('Variable_6/Adam', ':', [1024, 10])
('Variable_3', ':', [64])
('Variable_2/Adam_1', ':', [5, 5, 32, 64])


可以看出(据我猜测),如果你在定义saver的时候没有自己给tensor取名字,那么,tensorflow会按照自己的方式给你的tensor取名字。取名字的方式如下:

如果tensor是常量,那么就按规律取名:Const,Const_1,Const_2,Const_3,……

如果tensor是变量,那么就按规律取名:Variable,Variable_1,Variable_2,Variable_3,……

二,如何restore参数到重构网络中

据我所知,在restore参数时,要重新构造出与训练的网络相同的结构。如果不重构就能恢复参数,请联系我你是怎么做到的。restore很简单,只需要定义了saver后直接restore(这里就没有训练的过程啦)。下面的代码就是restore的过程,然后就能识别自己的手写字体啦(可以用画图来写一个数字)。

# encoding=utf-8
import tensorflow as tf
from PIL import Image,ImageFilter
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets('MNIST_data', one_hot=True)

def imageprepare(argv): # 该函数读一张图片,处理后返回一个数组,进到网络中预测
"""
This function returns the pixel values.
The imput is a png file location.
"""
im = Image.open(argv).convert('L')
width = float(im.size[0])
height = float(im.size[1])
newImage = Image.new('L', (28, 28), (255))  # creates white canvas of 28x28 pixels

if width > height:  # check which dimension is bigger
# Width is bigger. Width becomes 20 pixels.
nheight = int(round((20.0 / width * height), 0))  # resize height according to ratio width
if nheight == 0:  # rare case but minimum is 1 pixel
nheight = 1
# resize and sharpen
img = im.resize((20, nheight), Image.ANTIALIAS).filter(ImageFilter.SHARPEN)
wtop = int(round(((28 - nheight) / 2), 0))  # caculate horizontal pozition
newImage.paste(img, (4, wtop))  # paste resized image on white canvas
else:
# Height is bigger. Heigth becomes 20 pixels.
nwidth = int(round((20.0 / height * width), 0))  # resize width according to ratio height
if (nwidth == 0):  # rare case but minimum is 1 pixel
nwidth = 1
# resize and sharpen
img = im.resize((nwidth, 20), Image.ANTIALIAS).filter(ImageFilter.SHARPEN)
wleft = int(round(((28 - nwidth) / 2), 0))  # caculate vertical pozition
newImage.paste(img, (wleft, 4))  # paste resized image on white canvas

# newImage.save("sample.png")

tv = list(newImage.getdata())  # get pixel values

# normalize pixels to 0 and 1. 0 is pure white, 1 is pure black.
tva = [(255 - x) * 1.0 / 255.0 for x in tv]
return tva

def weight_variable(shape):
initial = tf.truncated_normal(shape, stddev=0.1)
return tf.Variable(initial)

def bias_variable(shape):
initial = tf.constant(0.1, shape=shape)
return tf.Variable(initial)

myGraph = tf.Graph()
with myGraph.as_default():  # 重构相同的网络
with tf.name_scope('inputsAndLabels'):
x_raw = tf.placeholder(tf.float32, shape=[None, 784])
y = tf.placeholder(tf.float32, shape=[None, 10])

with tf.name_scope('hidden1'):
x = tf.reshape(x_raw, shape=[-1,28,28,1])
W_conv1 = weight_variable([5,5,1,32])
b_conv1 = bias_variable([32])
l_conv1 = tf.nn.relu(tf.nn.conv2d(x,W_conv1, strides=[1,1,1,1],padding='SAME') + b_conv1)
l_pool1 = tf.nn.max_pool(l_conv1, ksize=[1,2,2,1], strides=[1,2,2,1], padding='SAME')

with tf.name_scope('hidden2'):
W_conv2 = weight_variable([5,5,32,64])
b_conv2 = bias_variable([64])
l_conv2 = tf.nn.relu(tf.nn.conv2d(l_pool1, W_conv2, strides=[1,1,1,1], padding='SAME')+b_conv2)
l_pool2 = tf.nn.max_pool(l_conv2, ksize=[1,2,2,1],strides=[1,2,2,1], padding='SAME')

with tf.name_scope('fc1'):
W_fc1 = weight_variable([64*7*7, 1024])
b_fc1 = bias_variable([1024])
l_pool2_flat = tf.reshape(l_pool2, [-1, 64*7*7])
l_fc1 = tf.nn.relu(tf.matmul(l_pool2_flat, W_fc1) + b_fc1)
keep_prob = tf.placeholder(tf.float32)
l_fc1_drop = tf.nn.dropout(l_fc1, keep_prob)

with tf.name_scope('fc2'):
W_fc2 = weight_variable([1024, 10])
b_fc2 = bias_variable([10])
y_conv = tf.matmul(l_fc1_drop, W_fc2) + b_fc2

with tf.Session(graph=myGraph) as sess:
sess.run(tf.global_variables_initializer())
saver = tf.train.Saver()

saver.restore(sess,'./model/mnistmodel-1') # restore参数

array = imageprepare('./1.png') # 读一张包含数字的图片

prediction = tf.argmax(y_conv, 1) # 预测
prediction = prediction.eval(feed_dict={x_raw:[array],keep_prob:1.0},session=sess)
print('The digits in this image is:%d'%prediction[0])


总结

识别引擎效果还是不错的,其核心就是卷积神经网络。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐