# Copyright 2015 The TensorFlow Authors. All Rights Reserved.## Licensed under the Apache License, Version 2.0 (the "License");# you may not use this file except in compliance with the License.# You may obtain a copy of the License at## http://www.apache.org/licenses/LICENSE-2.0## Unless required by applicable law or agreed to in writing, software# distributed under the License is distributed on an "AS IS" BASIS,# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.# See the License for the specific language governing permissions and# limitations under the License.# =============================================================================="""Timing benchmark for AlexNet inference.
To run, use:
bazel run -c opt --config=cuda \
models/tutorials/image/alexnet:alexnet_benchmark
Across 100 steps on batch size = 128.
Forward pass:
Run on Tesla K40c: 145 +/- 1.5 ms / batch
Run on Titan X: 70 +/- 0.1 ms / batch
Forward-backward pass:
Run on Tesla K40c: 480 +/- 48 ms / batch
Run on Titan X: 244 +/- 30 ms / batch
"""from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import argparse
from datetime import datetime
import math
import sys
import time
from six.moves importxrange# pylint: disable=redefined-builtinimport tensorflow as tf
FLAGS =None#显示网络每层结构defprint_activations(t):print(t.op.name,' ', t.get_shape().as_list())#构建卷积神经网络结构#定义inference函数,输入参数为image,返回值为最后一层pool(也就是pool5)以及其他参数definference(images):"""Build the AlexNet model.
Args:
images: Images Tensor
Returns:
pool5: the last Tensor in the convolutional component of AlexNet.
parameters: a list of Tensors corresponding to the weights and biases of the
AlexNet model.
"""
parameters =[]#第1个卷积层 conv1with tf.name_scope('conv1')as scope:
kernel = tf.Variable(tf.truncated_normal([11,11,3,64], dtype=tf.float32,
stddev=1e-1), name='weights')
conv = tf.nn.conv2d(images, kernel,[1,4,4,1], padding='SAME')
biases = tf.Variable(tf.constant(0.0, shape=[64], dtype=tf.float32),
trainable=True, name='biases')
bias = tf.nn.bias_add(conv, biases)
conv1 = tf.nn.relu(bias, name=scope)
print_activations(conv1)
parameters +=[kernel, biases]# 添加LRN层 lrn1with tf.name_scope('lrn1')as scope:
lrn1 = tf.nn.local_response_normalization(conv1,
alpha=1e-4,
beta=0.75,
depth_radius=2,
bias=2.0)#第1个最大池化层 pool1
pool1 = tf.nn.max_pool(lrn1,
ksize=[1,3,3,1],
strides=[1,2,2,1],
padding='VALID',
name='pool1')
print_activations(pool1)#第2个卷积 conv2with tf.name_scope('conv2')as scope:
kernel = tf.Variable(tf.truncated_normal([5,5,64,192], dtype=tf.float32,
stddev=1e-1), name='weights')
conv = tf.nn.conv2d(pool1, kernel,[1,1,1,1], padding='SAME')
biases = tf.Variable(tf.constant(0.0, shape=[192], dtype=tf.float32),
trainable=True, name='biases')
bias = tf.nn.bias_add(conv, biases)
conv2 = tf.nn.relu(bias, name=scope)
parameters +=[kernel, biases]
print_activations(conv2)# 添加第2个LRN层 lrn2with tf.name_scope('lrn2')as scope:
lrn2 = tf.nn.local_response_normalization(conv2,
alpha=1e-4,
beta=0.75,
depth_radius=2,
bias=2.0)#第2个最大池化层 pool2
pool2 = tf.nn.max_pool(lrn2,
ksize=[1,3,3,1],
strides=[1,2,2,1],
padding='VALID',
name='pool2')
print_activations(pool2)#第3个卷积层 conv3with tf.name_scope('conv3')as scope:
kernel = tf.Variable(tf.truncated_normal([3,3,192,384],
dtype=tf.float32,
stddev=1e-1), name='weights')
conv = tf.nn.conv2d(pool2, kernel,[1,1,1,1], padding='SAME')
biases = tf.Variable(tf.constant(0.0, shape=[384], dtype=tf.float32),
trainable=True, name='biases')
bias = tf.nn.bias_add(conv, biases)
conv3 = tf.nn.relu(bias, name=scope)
parameters +=[kernel, biases]
print_activations(conv3)#第4个卷积层 conv4with tf.name_scope('conv4')as scope:
kernel = tf.Variable(tf.truncated_normal([3,3,384,256],
dtype=tf.float32,
stddev=1e-1), name='weights')
conv = tf.nn.conv2d(conv3, kernel,[1,1,1,1], padding='SAME')
biases = tf.Variable(tf.constant(0.0, shape=[256], dtype=tf.float32),
trainable=True, name='biases')
bias = tf.nn.bias_add(conv, biases)
conv4 = tf.nn.relu(bias, name=scope)
parameters +=[kernel, biases]
print_activations(conv4)#第5个卷积层 conv5with tf.name_scope('conv5')as scope:
kernel = tf.Variable(tf.truncated_normal([3,3,256,256],
dtype=tf.float32,
stddev=1e-1), name='weights')
conv = tf.nn.conv2d(conv4, kernel,[1,1,1,1], padding='SAME')
biases = tf.Variable(tf.constant(0.0, shape=[256], dtype=tf.float32),
trainable=True, name='biases')
bias = tf.nn.bias_add(conv, biases)
conv5 = tf.nn.relu(bias, name=scope)
parameters +=[kernel, biases]
print_activations(conv5)#第5个最大池化层 pool5
pool5 = tf.nn.max_pool(conv5,
ksize=[1,3,3,1],
strides=[1,2,2,1],
padding='VALID',
name='pool5')
print_activations(pool5)return pool5, parameters
#评估AlexNet每轮计算时间函数deftime_tensorflow_run(session, target, info_string):"""Run the computation to obtain the target tensor and print timing stats.
Args:
session: the TensorFlow session to run the computation under.
target: the target Tensor that is passed to the session's run() function.
info_string: a string summarizing this run, to be printed with the stats.
Returns:
None
"""
num_steps_burn_in =10#定义预热轮数
total_duration =0.0#总时间
total_duration_squared =0.0#平方和for i inxrange(FLAGS.num_batches + num_steps_burn_in):#迭代num_batches + num_steps_burn_in次
start_time = time.time()#开始时间
_ = session.run(target)
duration = time.time()- start_time
#每10轮迭代显示当前迭代时间。每轮total_duration、total_duration_squared累加。if i >= num_steps_burn_in:ifnot 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))defrun_benchmark():"""Run the benchmark on AlexNet.”""
#定义默认Graphwith tf.Graph().as_default():# Generate some dummy images.
image_size =224# Note that our padding definition is slightly different the cuda-convnet.# In order to force the model to start with the same activations sizes,# we add 3 to the image_size and employ VALID padding above.#tf.random_nomal函数构造正态分步(标准差 0.1)随机tensor,第一维度batch_size,每轮迭代样本数,第二、三维度图片尺寸image_size 224,第四维度图片颜色通道数
images = tf.Variable(tf.random_normal([FLAGS.batch_size,
image_size,
image_size,3],
dtype=tf.float32,
stddev=1e-1))# Build a Graph that computes the logits predictions from the# inference model.# inference函数构建整个AlexNet网络,最后池化层输出pool5,训练参数集合parameters
pool5, parameters = inference(images)# Build an initialization operation.#tf.global_variables_initializer()初始化所有参数。
init = tf.global_variables_initializer()# Start running operations on the Graph.
config = tf.ConfigProto()
config.gpu_options.allocator_type = ‘BFC'
#tf.Session()创建新Session
sess = tf.Session(config=config)
sess.run(init)# Run the forward benchmark.
time_tensorflow_run(sess, pool5,"Forward")# Add a simple objective so we can calculate the backward pass.#最后输出pool5设置优化目标损失函数
objective = tf.nn.l2_loss(pool5)# 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")defmain(_):
run_benchmark()if __name__ =='__main__':
parser = argparse.ArgumentParser()#每个batch_size大小为128
parser.add_argument('--batch_size',type=int,
default=128,help='Batch size.')#batch测试数目为100个
parser.add_argument('--num_batches',type=int,
default=100,help='Number of batches to run.')
FLAGS, unparsed = parser.parse_known_args()
tf.app.run(main=main, argv=[sys.argv[0]]+ unparsed)