Skip to content

Commit f23f32c

Browse files
Routine for decoding fer2013 binary file format
1 parent 4475d8b commit f23f32c

File tree

1 file changed

+216
-0
lines changed

1 file changed

+216
-0
lines changed

fer2013_input.py

Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
1+
"""Routine for decoding the FER2013 binary file format."""
2+
3+
from __future__ import absolute_import
4+
from __future__ import division
5+
from __future__ import print_function
6+
7+
import os
8+
9+
from six.moves import xrange # pylint: disable=redefined-builtin
10+
import tensorflow as tf
11+
12+
# Process images of this size. Original FER2013 image size is 48 x 48.
13+
IMAGE_SIZE = 32
14+
15+
# Global constants describing the FER2013 data set.
16+
NUM_CLASSES = 7
17+
NUM_EXAMPLES_PER_EPOCH_FOR_TRAIN = 28709 # The training set #50000
18+
NUM_EXAMPLES_PER_EPOCH_FOR_EVAL = 3589 # The public test set #10000
19+
20+
21+
def read_fer2013(filename_queue):
22+
"""Reads and parses examples from FER2013 data files.
23+
24+
Recommendation: if you want N-way read parallelism, call this function
25+
N times. This will give you N independent Readers reading different
26+
files & positions within those files, which will give better mixing of
27+
examples.
28+
29+
Args:
30+
filename_queue: A queue of strings with the filenames to read from.
31+
32+
Returns:
33+
An object representing a single example, with the following fields:
34+
height: number of rows in the result (48)
35+
width: number of columns in the result (348)
36+
depth: number of color channels in the result (1)
37+
key: a scalar string Tensor describing the filename & record number
38+
for this example.
39+
label: an int32 Tensor with the label in the range 0..7.
40+
uint8image: a [height, width, depth] uint8 Tensor with the image data
41+
"""
42+
43+
class FER2013Record(object):
44+
pass
45+
result = FER2013Record()
46+
47+
label_bytes = 1
48+
result.height = 48
49+
result.width = 48
50+
result.depth = 1 # 3 for RGB
51+
image_bytes = result.height * result.width * result.depth
52+
53+
# Every record consists of a label followed by the image, with a
54+
# fixed number of bytes for each.
55+
record_bytes = label_bytes + image_bytes
56+
57+
# Read a record, getting filenames from the filename_queue. No
58+
# header or footer in the FER2013 format, so we leave header_bytes
59+
# and footer_bytes at their default of 0.
60+
reader = tf.FixedLengthRecordReader(record_bytes=record_bytes)
61+
result.key, value = reader.read(filename_queue)
62+
63+
# Convert from a string to a vector of uint8 that is record_bytes long.
64+
record_bytes = tf.decode_raw(value, tf.uint8)
65+
66+
# The first bytes represent the label, which we convert from uint8->int32.
67+
result.label = tf.cast(
68+
tf.slice(record_bytes, [0], [label_bytes]), tf.int32)
69+
70+
# The remaining bytes after the label represent the image, which we reshape
71+
# from [depth * height * width] to [depth, height, width].
72+
depth_major = tf.reshape(tf.slice(record_bytes, [label_bytes], [image_bytes]),
73+
[result.depth, result.height, result.width])
74+
# Convert from [depth, height, width] to [height, width, depth].
75+
result.uint8image = tf.transpose(depth_major, [1, 2, 0])
76+
77+
return result
78+
79+
80+
def _generate_image_and_label_batch(image, label, min_queue_examples,
81+
batch_size):
82+
"""Construct a queued batch of images and labels.
83+
84+
Args:
85+
image: 3-D Tensor of [height, width, 1] of type.float32.
86+
label: 1-D Tensor of type.int32
87+
min_queue_examples: int32, minimum number of samples to retain
88+
in the queue that provides of batches of examples.
89+
batch_size: Number of images per batch.
90+
91+
Returns:
92+
images: Images. 4D tensor of [batch_size, height, width, 1] size.
93+
labels: Labels. 1D tensor of [batch_size] size.
94+
"""
95+
# Create a queue that shuffles the examples, and then
96+
# read 'batch_size' images + labels from the example queue.
97+
num_preprocess_threads = 16
98+
images, label_batch = tf.train.shuffle_batch(
99+
[image, label],
100+
batch_size=batch_size,
101+
num_threads=num_preprocess_threads,
102+
capacity=min_queue_examples + 3 * batch_size,
103+
min_after_dequeue=min_queue_examples)
104+
105+
# Display the training images in the visualizer.
106+
tf.image_summary('images', images)
107+
108+
return images, tf.reshape(label_batch, [batch_size])
109+
110+
111+
def distorted_inputs(data_dir, batch_size):
112+
"""Construct distorted input for FER2013 training using the Reader ops.
113+
114+
Args:
115+
data_dir: Path to the FER2013 data directory.
116+
batch_size: Number of images per batch.
117+
118+
Returns:
119+
images: Images. 4D tensor of [batch_size, IMAGE_SIZE, IMAGE_SIZE, 3] size.
120+
labels: Labels. 1D tensor of [batch_size] size.
121+
"""
122+
123+
filenames = [os.path.join(data_dir, 'fer2013.bin')]
124+
125+
for f in filenames:
126+
if not tf.gfile.Exists(f):
127+
raise ValueError('Failed to find file: ' + f)
128+
129+
# Create a queue that produces the filenames to read.
130+
filename_queue = tf.train.string_input_producer(filenames)
131+
132+
# Read examples from files in the filename queue.
133+
read_input = read_fer2013(filename_queue)
134+
reshaped_image = tf.cast(read_input.uint8image, tf.float32)
135+
136+
height = IMAGE_SIZE
137+
width = IMAGE_SIZE
138+
139+
# 32 x 32 cropping.
140+
# Resizes an image to a target width and height by either centrally cropping the image
141+
# or padding it evenly with zeros.
142+
143+
# distorted_image = tf.image.crop_to_bounding_box(reshaped_image, 12, 12, 24, 24)
144+
distorted_image = tf.image.resize_image_with_crop_or_pad(reshaped_image, width, height)
145+
146+
# Because these operations are not commutative, consider randomizing
147+
# randomize the order their operation.
148+
distorted_image = tf.image.random_brightness(distorted_image, max_delta=63)
149+
distorted_image = tf.image.random_contrast(distorted_image, lower=0.2, upper=1.8)
150+
151+
# Subtract off the mean and divide by the variance of the pixels.
152+
float_image = tf.image.per_image_whitening(distorted_image)
153+
154+
# Ensure that the random shuffling has good mixing properties.
155+
min_fraction_of_examples_in_queue = 0.4
156+
min_queue_examples = int(NUM_EXAMPLES_PER_EPOCH_FOR_TRAIN *
157+
min_fraction_of_examples_in_queue)
158+
print ('Filling queue with %d FER2013 images before starting to train. '
159+
'This might take a few minutes.' % min_queue_examples)
160+
161+
# Generate a batch of images and labels by building up a queue of examples.
162+
return _generate_image_and_label_batch(float_image, read_input.label,
163+
min_queue_examples, batch_size)
164+
165+
166+
def inputs(eval_data, data_dir, batch_size):
167+
"""Construct input for FER2013 evaluation using the Reader ops.
168+
169+
Args:
170+
eval_data: bool, indicating if one should use the train or eval data set.
171+
data_dir: Path to the FER2013 data directory.
172+
batch_size: Number of images per batch.
173+
174+
Returns:
175+
images: Images. 4D tensor of [batch_size, IMAGE_SIZE, IMAGE_SIZE, 3] size.
176+
labels: Labels. 1D tensor of [batch_size] size.
177+
"""
178+
if not eval_data:
179+
filenames = [os.path.join(data_dir, 'fer2013.bin')]
180+
num_examples_per_epoch = NUM_EXAMPLES_PER_EPOCH_FOR_TRAIN
181+
else:
182+
filenames = [os.path.join(data_dir, 'test_batch.bin')]
183+
num_examples_per_epoch = NUM_EXAMPLES_PER_EPOCH_FOR_EVAL
184+
185+
print("Reading file:",filenames)
186+
187+
for f in filenames:
188+
if not tf.gfile.Exists(f):
189+
raise ValueError('Failed to find file: ' + f)
190+
191+
# Create a queue that produces the filenames to read.
192+
filename_queue = tf.train.string_input_producer(filenames)
193+
194+
# Read examples from files in the filename queue.
195+
read_input = read_fer2013(filename_queue)
196+
reshaped_image = tf.cast(read_input.uint8image, tf.float32)
197+
198+
height = IMAGE_SIZE
199+
width = IMAGE_SIZE
200+
201+
# Image processing for evaluation.
202+
# Crop the central [height, width] of the image.
203+
resized_image = tf.image.resize_image_with_crop_or_pad(reshaped_image,
204+
width, height)
205+
206+
# Subtract off the mean and divide by the variance of the pixels.
207+
float_image = tf.image.per_image_whitening(resized_image)
208+
209+
# Ensure that the random shuffling has good mixing properties.
210+
min_fraction_of_examples_in_queue = 0.4
211+
min_queue_examples = int(num_examples_per_epoch *
212+
min_fraction_of_examples_in_queue)
213+
214+
# Generate a batch of images and labels by building up a queue of examples.
215+
return _generate_image_and_label_batch(float_image, read_input.label,
216+
min_queue_examples, batch_size)

0 commit comments

Comments
 (0)