Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
rebuild model, simplify model export way
  • Loading branch information
Piasy committed May 29, 2017
commit 4b7ae9a33c6d0b7db4054f880c6703013a869662
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
tensorflow_model/logs/
tensorflow_model/MNIST_data/
tensorflow_model/out/

Binary file removed MnistAndroid/app/src/main/assets/expert-graph.pb
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ static public Classifier create(AssetManager assetManager, String modelPath, Str
public Classification recognize(final float[] pixels) {

tfHelper.feed(inputName, pixels, 1, inputSize, inputSize, 1);
tfHelper.feed("keep_prob", new float[] {1.0f});
tfHelper.run(outputNames);

tfHelper.fetch(outputName, output);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public class MainActivity extends Activity implements View.OnClickListener, View
private static final int INPUT_SIZE = 28;
private static final String INPUT_NAME = "input";
private static final String OUTPUT_NAME = "output";
private static final String MODEL_FILE = "expert-graph.pb";
private static final String MODEL_FILE = "optimized_mnist_convnet.pb";
private static final String LABEL_FILE = "labels.txt";
private static final int PIXEL_WIDTH = 28;

Expand Down
302 changes: 106 additions & 196 deletions tensorflow_model/convnet.py
Original file line number Diff line number Diff line change
@@ -1,205 +1,115 @@
# needed libraries
import tensorflow as tf
import os
import os.path as path
from tensorflow.python.tools import freeze_graph
from tensorflow.python.tools import optimize_for_inference_lib

from tensorflow.examples.tutorials.mnist import input_data

logs_path = '/tmp/tensorflow_logs/convnet'
logs_path = 'logs/'
if not path.exists('out'):
os.mkdir('out')
graph_save_path = 'out/mnist_convnet.graph.bin'
graph_ckp_path = 'out/mnist_convnet.ckpt'
frozen_graph_name = 'out/frozen_mnist_convnet.pb'
opt_graph_name = 'out/optimized_mnist_convnet.pb'

input_node_name = 'input'
keep_prob_node_name = 'keep_prob'
output_node_name = 'output'

# mnist.train = 55,000 input data
# mnist.test = 10,000 input data
# mnist.validate = 5,000 input data
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)

# Implementing Convnet with TF
def weight_variable(shape, name=None):
# break simmetry
if name:
w = tf.truncated_normal(shape, stddev=0.1, name=name)
else:
w = tf.truncated_normal(shape, stddev=0.1)

return tf.Variable(w)


def bias_variable(shape, name=None):
# avoid dead neurons
if name:
b = tf.constant(0.1, shape=shape, name=name)
else:
b = tf.constant(0.1, shape=shape)
return tf.Variable(b)


# pool
def max_pool_2x2(x):
return tf.nn.max_pool(x, ksize=[1, 2, 2, 1],
strides=[1, 2, 2, 1], padding='SAME')

def new_conv_layer(x, w):
return tf.nn.conv2d(x, w, strides=[1, 1, 1, 1], padding='SAME')

# our network!!!

g = tf.Graph()

with g.as_default():

# input data
x = tf.placeholder(tf.float32, shape=[None, 28*28], name='input_data')
x_image = tf.reshape(x, [-1, 28, 28, 1])
# correct labels
y_ = tf.placeholder(tf.float32, shape=[None, 10], name='correct_labels')

# fist conv layer
with tf.name_scope('convLayer1'):
w1 = weight_variable([5, 5, 1, 32])
b1 = bias_variable([32])
convlayer1 = tf.nn.relu(new_conv_layer(x_image, w1) + b1)
max_pool1 = max_pool_2x2(convlayer1)

# second conv layer
with tf.name_scope('convLayer2'):
w2 = weight_variable([5, 5, 32, 64])
b2 = bias_variable([64])
convlayer2 = tf.nn.relu(new_conv_layer(max_pool1, w2) + b2)
max_pool2 = max_pool_2x2(convlayer2)

# flat layer
with tf.name_scope('flattenLayer'):
flat_layer = tf.reshape(max_pool2, [-1, 7 * 7 * 64])

# fully connected layer
with tf.name_scope('FullyConnectedLayer'):
wfc1 = weight_variable([7 * 7 * 64, 1024])
bfc1 = bias_variable([1024])
fc1 = tf.nn.relu(tf.matmul(flat_layer, wfc1) + bfc1)

# DROPOUT
with tf.name_scope('Dropout'):
keep_prob = tf.placeholder(tf.float32)
drop_layer = tf.nn.dropout(fc1, keep_prob)

# final layer
with tf.name_scope('FinalLayer'):
w_f = weight_variable([1024, 10])
b_f = bias_variable([10])
y_f = tf.matmul(drop_layer, w_f) + b_f
y_f_softmax = tf.nn.softmax(y_f)

# loss
loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y_,
logits=y_f))

# train step
train_step = tf.train.AdamOptimizer(1e-4).minimize(loss)

# accuracy
correct_prediction = tf.equal(tf.argmax(y_f_softmax, 1), tf.argmax(y_, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))

# Create a summary to monitor loss tensor
tf.summary.scalar("loss", loss)
# Create a summary to monitor accuracy tensor
tf.summary.scalar("accuracy", accuracy)
# Merge all summaries into a single op
merged_summary_op = tf.summary.merge_all()

# init
init = tf.global_variables_initializer()

# Running the graph

num_steps = 3000
batch_size = 16
test_size = 10000
test_accuracy = 0.0

sess = tf.Session()

sess.run(init)
# op to write logs to Tensorboard
summary_writer = tf.summary.FileWriter(logs_path,
graph=tf.get_default_graph())

for step in range(num_steps):
batch = mnist.train.next_batch(batch_size)

ts, error, acc, summary = sess.run([train_step, loss, accuracy,
merged_summary_op],
feed_dict={x: batch[0],
y_: batch[1],
keep_prob: 0.5})
if step % 100 == 0:
train_accuracy = accuracy.eval({
x: batch[0], y_: batch[1], keep_prob: 1.0}, sess)
print('step %d, training accuracy %f' % (step, train_accuracy))
'''
print 'Done!'
print 'Evaluating...'
for i in xrange(test_size/50):
batch = mnist.test.next_batch(50)
acc = accuracy.eval({x: batch[0], y_: batch[1],
keep_prob: 1.0}, sess)
if i % 10 == 0:
print('%d: test accuracy %f' % (i, acc))
test_accuracy += acc
print 'avg test accuracy:', test_accuracy/(test_size/50.0)
'''

# copying variables as constants to export graph
_w1 = w1.eval(sess)
_b1 = b1.eval(sess)
_w2 = w2.eval(sess)
_b2 = b2.eval(sess)
_wfc1 = wfc1.eval(sess)
_bfc1 = bfc1.eval(sess)
_w_f = w_f.eval(sess)
_b_f = b_f.eval(sess)

sess.close()

g2 = tf.Graph()
with g2.as_default():

# input data
x2 = tf.placeholder(tf.float32, shape=[None, 28*28], name='input')
x2_image = tf.reshape(x2, [-1, 28, 28, 1])
# correct labels
y2_ = tf.placeholder(tf.float32, shape=[None, 10])

w1_2 = tf.constant(_w1)
b1_2 = tf.constant(_b1)
convlayer1_2 = tf.nn.relu(new_conv_layer(x2_image, w1_2) + b1_2)
max_pool1_2 = max_pool_2x2(convlayer1_2)

w2_2 = tf.constant(_w2)
b2_2 = tf.constant(_b2)
convlayer2_2 = tf.nn.relu(new_conv_layer(max_pool1_2, w2_2) + b2_2)
max_pool2_2 = max_pool_2x2(convlayer2_2)

# flat layer
flat_layer_2 = tf.reshape(max_pool2_2, [-1, 7 * 7 * 64])

# fully connected layer
wfc1_2 = tf.constant(_wfc1)
bfc1_2 = tf.constant(_bfc1)
fc1_2 = tf.nn.relu(tf.matmul(flat_layer_2, wfc1_2) + bfc1_2)

# no dropout layer

# final layer
w_f_2 = tf.constant(_w_f)
b_f_2 = tf.constant(_b_f)
y_f_2 = tf.matmul(fc1_2, w_f_2) + b_f_2
y_f_softmax_2 = tf.nn.softmax(y_f_2, name='output')

# init
init_2 = tf.global_variables_initializer()

sess_2 = tf.Session()
init_2 = tf.initialize_all_variables()
sess_2.run(init_2)

graph_def = g2.as_graph_def()
tf.train.write_graph(graph_def, '', 'graph.pb', as_text=False)
print("training start...")

# input data
x = tf.placeholder(tf.float32, shape=[None, 28*28], name=input_node_name)
x_image = tf.reshape(x, [-1, 28, 28, 1])
# 28*28*1
# correct labels
y_ = tf.placeholder(tf.float32, shape=[None, 10])

conv1 = tf.layers.conv2d(x_image, 64, 3, 1, 'same', activation=tf.nn.relu)
# 28*28*64
pool1 = tf.layers.max_pooling2d(conv1, 2, 2, 'same')
# 14*14*64

conv2 = tf.layers.conv2d(pool1, 128, 3, 1, 'same', activation=tf.nn.relu)
# 14*14*128
pool2 = tf.layers.max_pooling2d(conv2, 2, 2, 'same')
# 7*7*128

conv3 = tf.layers.conv2d(pool2, 256, 3, 1, 'same', activation=tf.nn.relu)
# 7*7*256
pool3 = tf.layers.max_pooling2d(conv3, 2, 2, 'same')
# 4*4*256

flatten = tf.reshape(pool3, [-1, 4*4*256])
fc = tf.layers.dense(flatten, 1024, activation=tf.nn.relu)
keep_prob = tf.placeholder(tf.float32, name=keep_prob_node_name)
dropout = tf.nn.dropout(fc, keep_prob)
logits = tf.layers.dense(dropout, 10)
outputs = tf.nn.softmax(logits, name=output_node_name)

# loss
loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y_, logits=logits))

# train step
train_step = tf.train.AdamOptimizer(0.0001).minimize(loss)

# accuracy
correct_prediction = tf.equal(tf.argmax(outputs, 1), tf.argmax(y_, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))

tf.summary.scalar("loss", loss)
tf.summary.scalar("accuracy", accuracy)
merged_summary_op = tf.summary.merge_all()

saver = tf.train.Saver()
init_op = tf.global_variables_initializer()

with tf.Session() as sess:
sess.run(init_op)

tf.train.write_graph(sess.graph_def, '.', graph_save_path + '.txt')
tf.train.write_graph(sess.graph_def, '.', graph_save_path, False)

# Running the graph
num_steps = 3000
batch_size = 16

# op to write logs to Tensorboard
summary_writer = tf.summary.FileWriter(logs_path, graph=tf.get_default_graph())

for step in range(num_steps):
batch = mnist.train.next_batch(batch_size)

ts, error, acc, summary = sess.run([train_step, loss, accuracy, merged_summary_op],
feed_dict={x: batch[0],
y_: batch[1],
keep_prob: 0.5})
summary_writer.add_summary(summary, step)
if step % 100 == 0:
print('step %d, training accuracy %f' % (step, acc))

saver.save(sess, graph_ckp_path)

print("training finished!")

freeze_graph.freeze_graph(graph_save_path, None, True, graph_ckp_path, \
output_node_name, "save/restore_all", "save/Const:0", \
frozen_graph_name, True, "")

input_graph_def = tf.GraphDef()
with tf.gfile.Open(frozen_graph_name, "rb") as f:
input_graph_def.ParseFromString(f.read())

output_graph_def = optimize_for_inference_lib.optimize_for_inference(
input_graph_def, [input_node_name, keep_prob_node_name], [output_node_name],
tf.float32.as_datatype_enum)

f = tf.gfile.FastGFile(opt_graph_name, "wb")
f.write(output_graph_def.SerializeToString())

print("graph saved!")
Binary file removed tensorflow_model/graph.pb
Binary file not shown.