Last active
August 10, 2016 18:07
-
-
Save mmmikael/d9745e14860c607c9be416a77fa155a8 to your computer and use it in GitHub Desktop.
Soumith's tensorflow benchmark with Keras API
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from datetime import datetime | |
import math | |
import time | |
import tensorflow.python.platform | |
import tensorflow as tf | |
FLAGS = tf.app.flags.FLAGS | |
# TODO: why is batch size 64 going OOM? | |
tf.app.flags.DEFINE_integer('batch_size', 64, | |
"""Batch size.""") | |
tf.app.flags.DEFINE_integer('num_batches', 100, | |
"""Number of batches to run.""") | |
tf.app.flags.DEFINE_boolean('forward_only', False, | |
"""Only run the forward pass.""") | |
tf.app.flags.DEFINE_boolean('forward_backward_only', False, | |
"""Only run the forward-forward pass.""") | |
tf.app.flags.DEFINE_string('data_format', 'NCHW', | |
"""The data format for Convnet operations. | |
Can be either NHWC or NCHW. | |
""") | |
parameters = [] | |
conv_counter = 1 | |
pool_counter = 1 | |
affine_counter = 1 | |
def _conv(inpOp, nIn, nOut, kH, kW, dH, dW, padType): | |
global conv_counter | |
global parameters | |
name = 'conv' + str(conv_counter) | |
conv_counter += 1 | |
with tf.name_scope(name) as scope: | |
kernel = tf.Variable(tf.truncated_normal([kH, kW, nIn, nOut], | |
dtype=tf.float32, | |
stddev=1e-1), name='weights') | |
if FLAGS.data_format == 'NCHW': | |
strides = [1, 1, dH, dW] | |
else: | |
strides = [1, dH, dW, 1] | |
conv = tf.nn.conv2d(inpOp, kernel, strides, padding=padType, | |
data_format=FLAGS.data_format) | |
biases = tf.Variable(tf.constant(0.0, shape=[nOut], dtype=tf.float32), | |
trainable=True, name='biases') | |
bias = tf.reshape(tf.nn.bias_add(conv, biases, | |
data_format=FLAGS.data_format), | |
conv.get_shape()) | |
conv1 = tf.nn.relu(bias, name=scope) | |
parameters += [kernel, biases] | |
return conv1 | |
def _affine(inpOp, nIn, nOut): | |
global affine_counter | |
global parameters | |
name = 'affine' + str(affine_counter) | |
affine_counter += 1 | |
with tf.name_scope(name) as scope: | |
kernel = tf.Variable(tf.truncated_normal([nIn, nOut], | |
dtype=tf.float32, | |
stddev=1e-1), name='weights') | |
biases = tf.Variable(tf.constant(0.0, shape=[nOut], dtype=tf.float32), | |
trainable=True, name='biases') | |
affine1 = tf.nn.relu_layer(inpOp, kernel, biases, name=name) | |
parameters += [kernel, biases] | |
return affine1 | |
def _mpool(inpOp, kH, kW, dH, dW): | |
global pool_counter | |
global parameters | |
name = 'pool' + str(pool_counter) | |
pool_counter += 1 | |
if FLAGS.data_format == 'NCHW': | |
ksize = [1, 1, kH, kW] | |
strides = [1, 1, dH, dW] | |
else: | |
ksize = [1, kH, kW, 1] | |
strides = [1, dH, dW, 1] | |
return tf.nn.max_pool(inpOp, | |
ksize=ksize, | |
strides=strides, | |
padding='VALID', | |
data_format=FLAGS.data_format, | |
name=name) | |
def loss(logits, labels): | |
batch_size = tf.size(labels) | |
labels = tf.expand_dims(labels, 1) | |
indices = tf.expand_dims(tf.range(0, batch_size, 1), 1) | |
concated = tf.concat(1, [indices, labels]) | |
onehot_labels = tf.sparse_to_dense( | |
concated, tf.pack([batch_size, 1000]), 1.0, 0.0) | |
cross_entropy = tf.nn.softmax_cross_entropy_with_logits(logits, | |
onehot_labels, | |
name='xentropy') | |
loss = tf.reduce_mean(cross_entropy, name='xentropy_mean') | |
return loss | |
def inference(images): | |
from keras.layers.core import Dense, Flatten | |
from keras.layers.convolutional import Convolution2D, MaxPooling2D | |
conv1 = Convolution2D(64, 3, 3, activation='relu', border_mode='same')(images) | |
pool1 = MaxPooling2D((2, 2), (2, 2))(conv1) | |
conv2 = Convolution2D(128, 3, 3, activation='relu', border_mode='same')(pool1) | |
pool2 = MaxPooling2D((2, 2), (2, 2))(conv2) | |
conv3 = Convolution2D(256, 3, 3, activation='relu', border_mode='same')(pool2) | |
conv4 = Convolution2D(256, 3, 3, activation='relu', border_mode='same')(conv3) | |
pool4 = MaxPooling2D((2, 2), (2, 2))(conv4) | |
conv5 = Convolution2D(512, 3, 3, activation='relu', border_mode='same')(pool4) | |
conv6 = Convolution2D(512, 3, 3, activation='relu', border_mode='same')(conv5) | |
pool6 = MaxPooling2D((2, 2), (2, 2))(conv6) | |
conv7 = Convolution2D(512, 3, 3, activation='relu', border_mode='same')(pool6) | |
conv8 = Convolution2D(512, 3, 3, activation='relu', border_mode='same')(conv7) | |
pool8 = MaxPooling2D((2, 2), (2, 2))(conv8) | |
resh1 = Flatten()(pool8) | |
affn1 = Dense(4096)(resh1) | |
affn2 = Dense(4096)(affn1) | |
affn3 = Dense(1000)(affn2) | |
return affn3 | |
def time_tensorflow_run(session, target, info_string): | |
num_steps_burn_in = 10 | |
total_duration = 0.0 | |
total_duration_squared = 0.0 | |
if not isinstance(target, list): | |
target = [target] | |
target_op = tf.group(*target) | |
for i in xrange(FLAGS.num_batches + num_steps_burn_in): | |
start_time = time.time() | |
_ = session.run(target_op) | |
duration = time.time() - start_time | |
if i > num_steps_burn_in: | |
if not i % 10: | |
print ('%s: step %d, duration = %.3f' % | |
(datetime.now(), i - num_steps_burn_in, duration)) | |
total_duration += duration | |
total_duration_squared += duration * duration | |
mn = total_duration / FLAGS.num_batches | |
vr = total_duration_squared / FLAGS.num_batches - mn * mn | |
sd = math.sqrt(vr) | |
print ('%s: %s across %d steps, %.3f +/- %.3f sec / batch' % | |
(datetime.now(), info_string, FLAGS.num_batches, mn, sd)) | |
def run_benchmark(): | |
global parameters | |
with tf.Graph().as_default(): | |
# Generate some dummy images. | |
image_size = 224 | |
if FLAGS.data_format == 'NCHW': | |
image_shape = [FLAGS.batch_size, 3, image_size, image_size] | |
else: | |
image_shape = [FLAGS.batch_size, image_size, image_size, 3] | |
images = tf.Variable(tf.ones(image_shape, dtype=tf.float32)) | |
labels = tf.Variable(tf.ones([FLAGS.batch_size], | |
dtype=tf.int32)) | |
# Build a Graph that computes the logits predictions from the | |
# inference model. | |
last_layer = inference(images) | |
# Build an initialization operation. | |
init = tf.initialize_all_variables() | |
# Start running operations on the Graph. | |
sess = tf.Session('') | |
sess.run(init) | |
run_forward = True | |
run_forward_backward = True | |
if FLAGS.forward_only and FLAGS.forward_backward_only: | |
raise ValueError("Cannot specify --forward_only and " | |
"--forward_backward_only at the same time.") | |
if FLAGS.forward_only: | |
run_forward_backward = False | |
elif FLAGS.forward_backward_only: | |
run_forward = False | |
if run_forward: | |
# Run the forward benchmark. | |
time_tensorflow_run(sess, last_layer, "Forward") | |
if run_forward_backward: | |
# Add a simple objective so we can calculate the backward pass. | |
objective = loss(last_layer, labels) | |
# Compute the gradient with respect to all the parameters. | |
grad = tf.gradients(objective, parameters) | |
# Run the backward benchmark. | |
time_tensorflow_run(sess, grad, "Forward-backward") | |
def main(_): | |
run_benchmark() | |
if __name__ == '__main__': | |
tf.app.run() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment