Skip to content

Commit 7594891

Browse files
committed
update TFRecord, preprocess data with Queue and Thread/ add cifar-10 example using TFRecord
1 parent f7ffc41 commit 7594891

File tree

6 files changed

+456
-17
lines changed

6 files changed

+456
-17
lines changed

docs/user/example.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ Computer Vision
1616
- Denoising Autoencoder (MNIST). A multi-layer perceptron implementation for MNIST classification task, see ``tutorial_mnist.py`` on `GitHub`_.
1717
- Stacked Denoising Autoencoder and Fine-Tuning (MNIST). A multi-layer perceptron implementation for MNIST classification task, see ``tutorial_mnist.py`` on `GitHub`_.
1818
- Convolutional Network (MNIST). A Convolutional neural network implementation for classifying MNIST dataset, see ``tutorial_mnist.py`` on `GitHub`_.
19-
- Convolutional Network (CIFAR-10). A Convolutional neural network implementation for classifying CIFAR-10 dataset, see ``tutorial_cifar10.py`` on `GitHub`_.
19+
- Convolutional Network (CIFAR-10). A Convolutional neural network implementation for classifying CIFAR-10 dataset, see ``tutorial_cifar10.py`` and ``tutorial_cifar10_tfrecord.py``on `GitHub`_.
2020
- VGG 16 (ImageNet). A Convolutional neural network implementation for classifying ImageNet dataset, see ``tutorial_vgg16.py`` on `GitHub`_.
2121
- VGG 19 (ImageNet). A Convolutional neural network implementation for classifying ImageNet dataset, see ``tutorial_vgg19.py`` on `GitHub`_.
2222

@@ -35,6 +35,7 @@ Reinforcement Learning
3535

3636
- Deep Reinforcement Learning - Pong Game. Teach a machine to play Pong games, see ``tutorial_atari_pong.py`` on `GitHub`_.
3737

38+
3839
..
3940
Applications
4041
=============

tensorlayer/ops.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ def disable_print():
118118
sys.stderr = os.devnull
119119

120120
def enable_print():
121-
"""Enable console output.
121+
"""Enable console output.
122122
123123
Example
124124
--------
@@ -152,7 +152,13 @@ def __exit__(self, type, value, traceback):
152152

153153

154154

155-
155+
def get_site_packages_directory():
156+
"""Print and return the site-packages directory?
157+
"""
158+
import site
159+
loc = site.getsitepackages()
160+
print(loc)
161+
return loc
156162

157163

158164

tutorial_cifar10.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,12 @@
88
import numpy as np
99
import time
1010

11-
"""Example of CNN
11+
"""Example of CNN, CIFAR-10
1212
13+
main_test_cnn_naive : No distorted image / Low accuracy
14+
main_test_cnn_advanced : Uses distorted image / High accurcy but Slow
15+
tutorial_cifar10_tfrecord : Preparing distorted image with Queue and Thread
16+
/ High accurcy and Fast
1317
"""
1418

1519

@@ -187,8 +191,9 @@ def main_test_cnn_advanced():
187191
.. Randomly distort the image brightness.
188192
.. Randomly distort the image contrast.
189193
190-
To do
191-
------
194+
Speed Up
195+
---------
196+
see `tutorial_cifar10_tfrecord.py`
192197
Reading images from disk and distorting them can use a non-trivial amount
193198
of processing time. To prevent these operations from slowing down training,
194199
we run them inside 16 separate threads which continuously fill a TensorFlow queue.

tutorial_cifar10_tfrecord.py

Lines changed: 308 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,308 @@
1+
#! /usr/bin/python
2+
# -*- coding: utf8 -*-
3+
4+
5+
import tensorflow as tf
6+
import tensorlayer as tl
7+
from tensorlayer.layers import set_keep
8+
import numpy as np
9+
import time
10+
from PIL import Image
11+
import os
12+
import io
13+
14+
"""Reimplementation of the TensorFlow official CIFAR-10 CNN tutorials:
15+
16+
This model has 1,068,298 paramters, after few hours of training with GPU,
17+
accurcy of 86% was found.
18+
19+
Hint : Set different num_threads according to your machine.
20+
21+
Links
22+
-------
23+
.. https://www.tensorflow.org/versions/r0.9/tutorials/deep_cnn/index.html
24+
.. https://github.com/tensorflow/tensorflow/tree/r0.9/tensorflow/models/image/cifar10
25+
26+
Note
27+
------
28+
The optimizers between official code and this code are different.
29+
30+
Description
31+
-----------
32+
The images are processed as follows:
33+
.. They are cropped to 24 x 24 pixels, centrally for evaluation or randomly for training.
34+
.. They are approximately whitened to make the model insensitive to dynamic range.
35+
36+
For training, we additionally apply a series of random distortions to
37+
artificially increase the data set size:
38+
.. Randomly flip the image from left to right.
39+
.. Randomly distort the image brightness.
40+
.. Randomly distort the image contrast.
41+
42+
Speed Up
43+
--------
44+
Reading images from disk and distorting them can use a non-trivial amount
45+
of processing time. To prevent these operations from slowing down training,
46+
we run them inside 16 separate threads which continuously fill a TensorFlow queue.
47+
"""
48+
model_file_name = "model_cifar10_tfrecord.ckpt"
49+
resume = False # load model, resume from previous checkpoint?
50+
51+
## Download data, and convert to TFRecord format, see ```tutorial_tfrecord.py```
52+
X_train, y_train, X_test, y_test = tl.files.load_cifar10_dataset(
53+
shape=(-1, 32, 32, 3), plotable=False)
54+
55+
X_train = np.asarray(X_train, dtype=np.float32)
56+
y_train = np.asarray(y_train, dtype=np.int64)
57+
X_test = np.asarray(X_test, dtype=np.float32)
58+
y_test = np.asarray(y_test, dtype=np.int64)
59+
60+
print('X_train.shape', X_train.shape) # (50000, 32, 32, 3)
61+
print('y_train.shape', y_train.shape) # (50000,)
62+
print('X_test.shape', X_test.shape) # (10000, 32, 32, 3)
63+
print('y_test.shape', y_test.shape) # (10000,)
64+
print('X %s y %s' % (X_test.dtype, y_test.dtype))
65+
66+
def data_to_tfrecord(images, labels, filename):
67+
""" Save data into TFRecord """
68+
print("Converting data into %s ..." % filename)
69+
cwd = os.getcwd()
70+
writer = tf.python_io.TFRecordWriter(filename)
71+
for index, img in enumerate(images):
72+
img_raw = img.tobytes()
73+
## Visualize a image
74+
# tl.visualize.frame(np.asarray(img, dtype=np.uint8), second=1, saveable=False, name='frame', fig_idx=1236)
75+
label = int(labels[index])
76+
# print(label)
77+
## Convert the bytes back to image as follow:
78+
# image = Image.frombytes('RGB', (32, 32), img_raw)
79+
# image = np.fromstring(img_raw, np.float32)
80+
# image = image.reshape([32, 32, 3])
81+
# tl.visualize.frame(np.asarray(image, dtype=np.uint8), second=1, saveable=False, name='frame', fig_idx=1236)
82+
example = tf.train.Example(features=tf.train.Features(feature={
83+
"label": tf.train.Feature(int64_list=tf.train.Int64List(value=[label])),
84+
'img_raw': tf.train.Feature(bytes_list=tf.train.BytesList(value=[img_raw])),
85+
}))
86+
writer.write(example.SerializeToString()) # Serialize To String
87+
writer.close()
88+
89+
def read_and_decode(filename, is_train=None):
90+
""" Return tensor to read from TFRecord """
91+
filename_queue = tf.train.string_input_producer([filename])
92+
reader = tf.TFRecordReader()
93+
_, serialized_example = reader.read(filename_queue)
94+
features = tf.parse_single_example(serialized_example,
95+
features={
96+
'label': tf.FixedLenFeature([], tf.int64),
97+
'img_raw' : tf.FixedLenFeature([], tf.string),
98+
})
99+
# You can do more image distortion here for training data
100+
img = tf.decode_raw(features['img_raw'], tf.float32)
101+
img = tf.reshape(img, [32, 32, 3])
102+
# img = tf.cast(img, tf.float32) #* (1. / 255) - 0.5
103+
if is_train == True:
104+
# 1. Randomly crop a [height, width] section of the image.
105+
img = tf.random_crop(img, [24, 24, 3])
106+
# 2. Randomly flip the image horizontally.
107+
img = tf.image.random_flip_left_right(img)
108+
# 3. Randomly change brightness.
109+
img = tf.image.random_brightness(img, max_delta=63)
110+
# 4. Randomly change contrast.
111+
img = tf.image.random_contrast(img, lower=0.2, upper=1.8)
112+
# 5. Subtract off the mean and divide by the variance of the pixels.
113+
img = tf.image.per_image_whitening(img)
114+
elif is_train == False:
115+
# 1. Crop the central [height, width] of the image.
116+
img = tf.image.resize_image_with_crop_or_pad(img, 24, 24)
117+
# 2. Subtract off the mean and divide by the variance of the pixels.
118+
img = tf.image.per_image_whitening(img)
119+
elif is_train == None:
120+
img = img
121+
122+
label = tf.cast(features['label'], tf.int32)
123+
return img, label
124+
125+
data_to_tfrecord(images=X_train, labels=y_train, filename="train.cifar10")
126+
data_to_tfrecord(images=X_test, labels=y_test, filename="test.cifar10")
127+
128+
## Example to visualize data
129+
# img, label = read_and_decode("train.cifar10", None)
130+
# img_batch, label_batch = tf.train.shuffle_batch([img, label],
131+
# batch_size=4,
132+
# capacity=50000,
133+
# min_after_dequeue=10000,
134+
# num_threads=1)
135+
# print("img_batch : %s" % img_batch._shape)
136+
# print("label_batch : %s" % label_batch._shape)
137+
#
138+
# init = tf.initialize_all_variables()
139+
# with tf.Session() as sess:
140+
# sess.run(init)
141+
# coord = tf.train.Coordinator()
142+
# threads = tf.train.start_queue_runners(sess=sess, coord=coord)
143+
#
144+
# for i in range(3): # number of mini-batch (step)
145+
# print("Step %d" % i)
146+
# val, l = sess.run([img_batch, label_batch])
147+
# # exit()
148+
# print(val.shape, l)
149+
# tl.visualize.images2d(val, second=1, saveable=False, name='batch'+str(i), dtype=np.uint8, fig_idx=2020121)
150+
#
151+
# coord.request_stop()
152+
# coord.join(threads)
153+
# sess.close()
154+
155+
# with tf.device('/gpu:1'):
156+
157+
sess = tf.InteractiveSession()
158+
159+
batch_size = 128
160+
model_file_name = "model_cifar10_advanced.ckpt"
161+
resume = False # load model, resume from previous checkpoint?
162+
163+
x_train_, y_train_ = read_and_decode("train.cifar10", True)
164+
x_test_, y_test_ = read_and_decode("test.cifar10", False)
165+
166+
x_train_batch, y_train_batch = tf.train.shuffle_batch([x_train_, y_train_],
167+
batch_size=batch_size,
168+
capacity=2000,
169+
min_after_dequeue=1000,
170+
num_threads=32) # set the number of threads here
171+
# for testing, uses batch instead of shuffle_batch
172+
x_test_batch, y_test_batch = tf.train.batch([x_test_, y_test_],
173+
batch_size=batch_size,
174+
capacity=50000,
175+
num_threads=32)
176+
177+
def inference(x_crop, y_, reuse):
178+
with tf.variable_scope("model", reuse=reuse):
179+
tl.layers.set_name_reuse(reuse)
180+
network = tl.layers.InputLayer(x_crop, name='input_layer')
181+
network = tl.layers.Conv2dLayer(network,
182+
act = tf.nn.relu,
183+
shape = [5, 5, 3, 64], # 64 features for each 5x5x3 patch
184+
strides=[1, 1, 1, 1],
185+
padding='SAME',
186+
W_init=tf.truncated_normal_initializer(stddev=5e-2),
187+
b_init=tf.constant_initializer(value=0.0),
188+
name ='cnn_layer1') # output: (batch_size, 24, 24, 64)
189+
network = tl.layers.PoolLayer(network,
190+
ksize=[1, 3, 3, 1],
191+
strides=[1, 2, 2, 1],
192+
padding='SAME',
193+
pool = tf.nn.max_pool,
194+
name ='pool_layer1',) # output: (batch_size, 12, 12, 64)
195+
network.outputs = tf.nn.lrn(network.outputs, 4, bias=1.0, alpha=0.001 / 9.0,
196+
beta=0.75, name='norm1')
197+
network = tl.layers.Conv2dLayer(network,
198+
act = tf.nn.relu,
199+
shape = [5, 5, 64, 64], # 64 features for each 5x5 patch
200+
strides=[1, 1, 1, 1],
201+
padding='SAME',
202+
W_init=tf.truncated_normal_initializer(stddev=5e-2),
203+
b_init=tf.constant_initializer(value=0.1),
204+
name ='cnn_layer2') # output: (batch_size, 12, 12, 64)
205+
network.outputs = tf.nn.lrn(network.outputs, 4, bias=1.0, alpha=0.001 / 9.0,
206+
beta=0.75, name='norm2')
207+
network = tl.layers.PoolLayer(network,
208+
ksize=[1, 3, 3, 1],
209+
strides=[1, 2, 2, 1],
210+
padding='SAME',
211+
pool = tf.nn.max_pool,
212+
name ='pool_layer2') # output: (batch_size, 6, 6, 64)
213+
network = tl.layers.FlattenLayer(network, name='flatten_layer') # output: (batch_size, 2304)
214+
network = tl.layers.DenseLayer(network, n_units=384, act = tf.nn.relu,
215+
W_init=tf.truncated_normal_initializer(stddev=0.04),
216+
b_init=tf.constant_initializer(value=0.1),
217+
name='relu1') # output: (batch_size, 384)
218+
network = tl.layers.DenseLayer(network, n_units=192, act = tf.nn.relu,
219+
W_init=tf.truncated_normal_initializer(stddev=0.04),
220+
b_init=tf.constant_initializer(value=0.1),
221+
name='relu2') # output: (batch_size, 192)
222+
network = tl.layers.DenseLayer(network, n_units=10, act = tf.identity,
223+
W_init=tf.truncated_normal_initializer(stddev=1/192.0),
224+
b_init = tf.constant_initializer(value=0.0),
225+
name='output_layer') # output: (batch_size, 10)
226+
y = network.outputs
227+
228+
ce = tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits(y, y_))
229+
# L2 for the MLP, without this, the accuracy will be reduced by 15%.
230+
L2 = tf.contrib.layers.l2_regularizer(0.004)(network.all_params[4]) + \
231+
tf.contrib.layers.l2_regularizer(0.004)(network.all_params[6])
232+
cost = ce + L2
233+
234+
# correct_prediction = tf.equal(tf.argmax(tf.nn.softmax(y), 1), y_)
235+
correct_prediction = tf.equal(tf.cast(tf.argmax(y, 1), tf.int32), y_)
236+
acc = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
237+
238+
return cost, acc, network
239+
240+
## You can also use placeholder to feed_dict in data after using
241+
## val, l = sess.run([x_train_batch, y_train_batch]) to get the data
242+
# x_crop = tf.placeholder(tf.float32, shape=[batch_size, 24, 24, 3])
243+
# y_ = tf.placeholder(tf.int32, shape=[batch_size,])
244+
# cost, acc, network = inference(x_crop, y_, None)
245+
246+
cost, acc, network = inference(x_train_batch, y_train_batch, None)
247+
cost_test, acc_test, _ = inference(x_test_batch, y_test_batch, True)
248+
249+
## train
250+
n_epoch = 50000
251+
learning_rate = 0.0001
252+
print_freq = 5
253+
n_step_epoch = int(len(y_train)/batch_size)
254+
n_step = n_epoch * n_step_epoch
255+
256+
train_params = network.all_params
257+
train_op = tf.train.AdamOptimizer(learning_rate, beta1=0.9, beta2=0.999,
258+
epsilon=1e-08, use_locking=False).minimize(cost)#, var_list=train_params)
259+
260+
sess.run(tf.initialize_all_variables())
261+
if resume:
262+
print("Load existing model " + "!"*10)
263+
saver = tf.train.Saver()
264+
saver.restore(sess, model_file_name)
265+
266+
network.print_params()
267+
network.print_layers()
268+
269+
print(' learning_rate: %f' % learning_rate)
270+
print(' batch_size: %d' % batch_size)
271+
print(' n_epoch: %d, step in an epoch: %d, total n_step: %d' % (n_epoch, n_step_epoch, n_step))
272+
273+
coord = tf.train.Coordinator()
274+
threads = tf.train.start_queue_runners(sess=sess, coord=coord)
275+
# for step in range(n_step):
276+
step = 1
277+
for epoch in range(n_epoch):
278+
start_time = time.time()
279+
train_loss, train_acc, n_batch = 0, 0, 0
280+
for s in range(n_step_epoch):
281+
## You can also use placeholder to feed_dict in data after using
282+
# val, l = sess.run([x_train_batch, y_train_batch])
283+
# tl.visualize.images2d(val, second=3, saveable=False, name='batch', dtype=np.uint8, fig_idx=2020121)
284+
# err, ac, _ = sess.run([cost, acc, train_op], feed_dict={x_crop: val, y_: l})
285+
err, ac, _ = sess.run([cost, acc, train_op])
286+
step += 1
287+
train_loss += err; train_acc += ac; n_batch += 1
288+
289+
if epoch + 1 == 1 or (epoch + 1) % print_freq == 0:
290+
print("Epoch %d : Step %d-%d of %d took %fs" % (epoch, step, step + n_step_epoch, n_step, time.time() - start_time))
291+
print(" train loss: %f" % (train_loss/ n_batch))
292+
print(" train acc: %f" % (train_acc/ n_batch))
293+
294+
test_loss, test_acc, n_batch = 0, 0, 0
295+
for _ in range(int(len(y_test)/batch_size)):
296+
err, ac = sess.run([cost_test, acc_test])
297+
test_loss += err; test_acc += ac; n_batch += 1
298+
print(" test loss: %f" % (test_loss/ n_batch))
299+
print(" test acc: %f" % (test_acc/ n_batch))
300+
301+
if (epoch + 1) % (print_freq * 10) == 0:
302+
print("Save model " + "!"*10)
303+
saver = tf.train.Saver()
304+
save_path = saver.save(sess, model_file_name)
305+
306+
coord.request_stop()
307+
coord.join(threads)
308+
sess.close()

0 commit comments

Comments
 (0)