您的位置:首页 > 其它

学习Tensorflow,反卷积

2016-06-12 16:58 429 查看
       在深度学习网络结构中,各个层的类别可以分为这几种:卷积层,全连接层,relu层,pool层和反卷积层等。目前,在像素级估计和端对端学习问题中,全卷积网络展现了他的优势,里面有个很重要的层,将卷积后的feature map上采样(反卷积)到输入图像的尺寸空间,就是反卷积层。那么它在tensorflow里是怎么实现的呢?本篇博文讲介绍这方面的内容。

1. 反卷积函数介绍

tf.nn.conv2d_transpose(value, filter, output_shape, strides, padding='SAME', name=None)
这是tensorflow里实现反卷积的函数,value是上一层的feature map,filter是卷积核[kernel_size, kernel_size, output_channel, input_channel ],output_shape定义输出的尺寸[batch_size, height, width, channel],padding是边界打补丁的算法。

这里需要特别说明的是,output_shape和strides里的参数是相互耦合的,我们可以根据输入和输出确定strides参数(正整数),也可以根据输入和strides确定输出尺寸。

2. Alex net加反卷积层

# 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 \
third_party/tensorflow/models/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

from datetime import datetime
import math
import time

from six.moves import xrange  # pylint: disable=redefined-builtin
import tensorflow as tf

FLAGS = tf.app.flags.FLAGS

tf.app.flags.DEFINE_integer('batch_size', 1,
"""Batch size.""")
tf.app.flags.DEFINE_integer('num_batches', 100,
"""Number of batches to run.""")
tf.app.flags.DEFINE_integer('image_width', 345,
"""image width.""")
tf.app.flags.DEFINE_integer('image_height', 460,
"""image height.""")

def print_activations(t):
print(t.op.name, ' ', t.get_shape().as_list())

def inference(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 = []
# conv1
with 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]

# lrn1
# TODO(shlens, jiayq): Add a GPU version of local response normalization.

# pool1
pool1 = tf.nn.max_pool(conv1,
ksize=[1, 3, 3, 1],
strides=[1, 2, 2, 1],
padding='VALID',
name='pool1')
print_activations(pool1)

# conv2
with 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)

# pool2
pool2 = tf.nn.max_pool(conv2,
ksize=[1, 3, 3, 1],
strides=[1, 2, 2, 1],
padding='VALID',
name='pool2')
print_activations(pool2)

# conv3
with 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)

# conv4
with 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)

# conv5
with 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)

# pool5
pool5 = tf.nn.max_pool(conv5,
ksize=[1, 3, 3, 1],
strides=[1, 2, 2, 1],
padding='VALID',
name='pool5')
print_activations(pool5)

# conv6
with tf.name_scope('conv6') as scope:
kernel = tf.Variable(tf.truncated_normal([3, 3, 256, 1],
dtype=tf.float32,
stddev=1e-1), name='weights')
conv = tf.nn.conv2d(pool5, kernel, [1, 1, 1, 1], padding='SAME')
biases = tf.Variable(tf.constant(0.0, shape=[1], dtype=tf.float32),
trainable=True, name='biases')
bias = tf.nn.bias_add(conv, biases)
conv6 = tf.nn.relu(bias, name=scope)
parameters += [kernel, biases]
print_activations(conv6)

# deconv1
with tf.name_scope('deconv1') as scope:
wt = tf.Variable(tf.truncated_normal([11, 11, 1, 1]))
deconv1 = tf.nn.conv2d_transpose(conv6, wt, [FLAGS.batch_size, 130, 100, 1], [1, 10, 10, 1], 'SAME')
print_activations(deconv1)

# deconv2
with tf.name_scope('deconv2') as scope:
wt = tf.Variable(tf.truncated_normal([11, 11, 1, 1]))
deconv2 = tf.nn.conv2d_transpose(deconv1, wt, [FLAGS.batch_size, 260, 200, 1], [1, 2, 2, 1], 'SAME')
print_activations(deconv2)

return deconv2, parameters

def time_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 in xrange(FLAGS.num_batches + num_steps_burn_in):
start_time = time.time()
_ = session.run(target)
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():
"""Run the benchmark on AlexNet."""
with tf.Graph().as_default():
# Generate some dummy images.

# 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.
images = tf.Variable(tf.random_normal([FLAGS.batch_size,
460,
345, 3],
dtype=tf.float32,
stddev=1e-1))

# Build a Graph that computes the logits predictions from the
# inference model.
pool5, parameters = inference(images)

# Build an initialization operation.
init = tf.initialize_all_variables()

# Start running operations on the Graph.
config = tf.ConfigProto()
config.gpu_options.allocator_type = 'BFC'
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.
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")

def main(_):
run_benchmark()

if __name__ == '__main__':
tf.app.run()


三. 运行结果



reference url:

https://www.tensorflow.org/versions/r0.9/api_docs/python/nn.html#convolution

http://cvlab.postech.ac.kr/research/deconvnet/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息