实现如下:
import tensorflow as tf
filter_initializer = tf.contrib.layers.xavier_initializer()
# 定义卷积操作
def conv_op(input_op, name, kh, kw, n_out, dh, dw, relu='leaky', normal=True, train=True):
n_in = input_op.get_shape()[-1].value # 获取输入图像的通道channel数
with tf.variable_scope(name) as scope: # 命名空间
kernel = tf.get_variable("w",
shape = [kh, kw, n_in, n_out],
dtype = tf.float32,
initializer = tf.truncated_normal_initializer(stddev=0.1, dtype=tf.float32)) #定义卷积核以及初始化方法
biases = tf.get_variable('bases',
shape=[n_out],
dtype=tf.float32,
initializer=tf.constant_initializer(0.1))
conv = tf.nn.conv2d(input_op, kernel, strides=[1, dh, dw, 1], padding='SAME')
conv = tf.nn.bias_add(conv, biases)
if normal:
conv = tf.layers.batch_normalization(inputs=conv, momentum=0.99, epsilon=1e-3, training=train,
name=name+'_normal')
if relu == 'leaky':
conv = tf.nn.leaky_relu(conv, alpha = 0.1, name=name+relu)
elif relu == 'lrn':
tf.nn.lrn(conv, depth_radius=4, bias=1.0, alpha=0.01 / 9.0, beta=0.75, name=name+relu)
elif relu == 'relu':
conv = tf.nn.relu(conv, name=name+relu)
else:
pass
return conv
#定义池化层
def mpool_op(input_op, name, kh, kw, dh, dw):
pool = tf.nn.max_pool(input_op, ksize=[1, kh, kw, 1], strides=[1, dh, dw, 1], padding='SAME', name= name)
return pool
#定义池化层
def avgpool_op(input_op, name, kh, kw, dh, dw, padding='SAME'):
pool = tf.nn.avg_pool(input_op, ksize=[1, kh, kw, 1], strides=[1, dh, dw, 1], padding=padding, name=name)
return pool
def unmaxpool_op(input_op, name, k):
shape = input_op.get_shape()
unpool = tf.image.resize_nearest_neighbor(input_op, [k * shape[1], k * shape[2]], name=name)
return unpool
def side_branch(inputs, filters, upsample_factor):
# 反置卷积
kernel_size = [2 * upsample_factor, 2 * upsample_factor]
outputs = tf.layers.conv2d_transpose(inputs,
filters,
kernel_size,
strides=(upsample_factor, upsample_factor),
padding='same',
activation=None,
use_bias=True,
kernel_initializer=filter_initializer,
kernel_regularizer=None)
return outputs
#定义normlization层
def batch_normalization_layer(input_layer, name = None, training = True, norm_decay = 0.99, norm_epsilon = 1e-3):
'''
Introduction
------------
对卷积层提取的feature map使用batch normalization
Parameters
----------
input_layer: 输入的四维tensor
name: batchnorm层的名字
trainging: 是否为训练过程
norm_decay: 在预测时计算moving average时的衰减率
norm_epsilon: 方差加上极小的数,防止除以0的情况
Returns
-------
bn_layer: batch normalization处理之后的feature map
'''
bn_layer = tf.layers.batch_normalization(inputs=input_layer,
momentum=norm_decay, epsilon = norm_epsilon, center=True,
scale=True, training=training, name=name)
return tf.nn.leaky_relu(bn_layer, alpha = 0.1)
#定义全连接操作
def fc_op(input_op, name, n_out):
dim = input_op.get_shape()[-1].value
with tf.variable_scope(name) as scope:
weights = tf.get_variable('weights',
shape=[dim, n_out],
dtype=tf.float32,
initializer=tf.truncated_normal_initializer(stddev=0.1, dtype=tf.float32))
biases = tf.get_variable('bases',
shape=[n_out],
dtype=tf.float32,
initializer=tf.constant_initializer(0.1))
fc = tf.nn.leaky_relu(tf.matmul(input_op, weights) + biases, alpha=0.1, name='fc')
return fc
def params_usage():
"""统计参数数量"""
total = 0
for v in tf.trainable_variables():
shape = v.get_shape()
cnt = 1
for dim in shape:
cnt *= dim.value
total += cnt
return total
def shortcut(input, filters, name='shortcut', action='relu', BN=True, istraining=True):
with tf.variable_scope(name) as scope:
input_filters = input.get_shape()[-1].value
_layer = conv_op(input, name='conv1', kh=1, kw=1, n_out=filters, dh=1, dw=1, relu=action, normal=BN,
train=istraining)
_layer = conv_op(_layer, name='conv2', kh=3, kw=3, n_out=filters, dh=1, dw=1, relu=action, normal=BN,
train=istraining)
_layer = conv_op(_layer, name='conv3', kh=1, kw=1, n_out=input_filters, dh=1, dw=1, relu='', normal=BN,
train=istraining)
_out = input + _layer
return _out
def resnet152(input, filters, action='relu', BN=True, istraining=True):
endpoints = {}
conv1 = conv_op(input, name='conv1', kh=7, kw=7, n_out=filters*4, dh=2, dw=2, relu=action, normal=BN, train=istraining)
endpoints['C1'] = conv1
conv = mpool_op(conv1, name='pool1', kh=3, kw=3, dh=2, dw=2)
with tf.variable_scope('block_1') as scope:
conv = conv_op(conv, name='conv1', kh=1, kw=1, n_out=filters*4, dh=1, dw=1, relu='', normal=BN, train=istraining)
for i in range(3):
conv = shortcut(conv, filters, name='shortcut_%d'%i, action=action, BN=BN, istraining=istraining)
endpoints['C2'] = conv
with tf.variable_scope('block_2') as scope:
conv = mpool_op(conv, name='pool', kh=2, kw=2, dh=2, dw=2)
conv = conv_op(conv, name='conv1', kh=1, kw=1, n_out=filters * 8, dh=1, dw=1, relu='', normal=BN, train=istraining)
for i in range(6):
conv = shortcut(conv, filters*2, name='shortcut_%d'%i, action=action, BN=BN, istraining=istraining)
endpoints['C3'] = conv
with tf.variable_scope('block_3') as scope:
conv = mpool_op(conv, name='pool', kh=2, kw=2, dh=2, dw=2)
conv = conv_op(conv, name='conv1', kh=1, kw=1, n_out=filters * 16, dh=1, dw=1, relu='', normal=BN, train=istraining)
for i in range(12):
conv = shortcut(conv, filters*4, name='shortcut_%d'%i, action=action, BN=BN, istraining=istraining)
endpoints['C4'] = conv
with tf.variable_scope('block_4') as scope:
conv = mpool_op(conv, name='pool', kh=2, kw=2, dh=2, dw=2)
conv = conv_op(conv, name='conv1', kh=1, kw=1, n_out=filters * 16, dh=1, dw=1, relu='', normal=BN, train=istraining)
for i in range(3):
conv = shortcut(conv, filters*8, name='shortcut_%d' % i, action=action, BN=BN, istraining=istraining)
endpoints['C5'] = conv
return endpoints