TensorFlow (五): Slim

Slim 简介

Slim ( tf.contrib.slim ) 是一个轻量级的 TensorFlow 框架, 封装了 TensorFlow 的大量 API, 在之前学习过程中我自己明显可以感觉到 tf 的代码太啰嗦了, 想要写一个简单的 CNN 就需要写将近 50 行的辅助函数, 和 20 行的网络搭建, 之前使用 Keras 框架虽然同样可以简化代码, 但是 Keras 和 TensorFlow 的原生 API 彼此的兼容性较差, 而 Slim 则兼备了轻量开发和与 TensorFlow 兼容两大优点

代码对比

原生 TensorFlow

def new_weights(shape):
	return tf.Variable(tf.truncated_normal(shape, stddev=0.05))

def new_biases(length):
	return tf.Variable(tf.truncated_normal([length], stddev=0.05))

def new_conv_layer(input, nb_filter, nb_channel = 1, filter_size = 3):
	shape = [filter_size, filter_size, nb_channel, nb_filter]

	weights = new_weights(shape)
	biases = new_biases(nb_filter)

	layer = tf.nn.conv2d(input = input,
		 				 filter = weights,
		 				 strides = [1, 1, 1, 1],
		 				 padding = "SAME")

	layer += biases 

	layer = tf.nn.max_pool(value = layer, 
						   ksize = [1, 2, 2, 1], 
						   strides = [1, 2, 2, 1], 
						   padding = 'SAME')

	layer = tf.nn.relu(layer)

	return layer, weights
def flatten_layer(layer):
	layer_shape = layer.get_shape()

	num_features = layer_shape[1:4].num_elements()

	layer_flat = tf.reshape(layer, [-1, num_features])

	return layer_flat, num_features

def new_fc_layer(input, nb_input, nb_output, use_relu = True):
	weights = new_weights(shape = [nb_input, nb_output])
	biases = new_biases(nb_output)

	layer = tf.matmul(input, weights) + biases

	if use_relu:
		layer =  tf.nn.relu(layer)

	return layer
x = tf.placeholder(dtype = tf.float32, shape = [None, 28, 28, 1])
		y_ = tf.placeholder(dtype = tf.float32, shape = [None, nb_class])


layer_1, _ = new_conv_layer(input = x,
							nb_filter = 16)

layer_2, _ = new_conv_layer(input = layer_1,
							nb_channel = 16,
							nb_filter = 32)

layer_flat, fatures = flatten_layer(layer_2)

fc_1 = new_fc_layer(input = layer_flat,
					nb_input = fatures,
					nb_output = 64)

fc_2 = new_fc_layer(input = fc_1,
					nb_input = 64,
					nb_output = nb_class,
					use_relu = False)

y = tf.nn.softmax(fc_2)

Slim

x = tf.placeholder(dtype = tf.float32, shape = [None, 28, 28, 1])
y_ = tf.placeholder(dtype = tf.float32, shape = [None, nb_class])

layer_1 = slim.conv2d(x, 16, [3, 3])
layer_2 = slim.conv2d(layer1, 32, [3, 3])
layer_flat = slim.flatten(layer_2)
fc_1 = slim.fully_connected(layer_flat, 64)
fc_2 = slim.fully_connected(fc_1, nb_class, activation_fn = None)
y = tf.nn.softmax(fc_2)

由此可见, slim 框架相比于原生 TensorFlow 极大地减少了代码量, 同时 slim 还有以下功能

共享参数

有时候神经网络的层之间的某些参数是相同的, 如 VGG-16 中所有卷积层的卷积核都是 3 * 3, 如果每个层都写一遍会很啰嗦, slim 引入了 arg_scope 机制解决了这一问题


# 写法一

net = slim.conv2d(net, 32, [3, 3], weights_initializer = tf.truncated_normal_initializer(stddev = 0.01), scope = 'conv_1')
net = slim.conv2d(net, 64, [3, 3], weights_initializer = tf.truncated_normal_initializer(stddev = 0.01), scope = 'conv_2')
net = slim.conv2d(net, 128, [3, 3], weights_initializer = tf.truncated_normal_initializer(stddev = 0.01), scope = 'conv_3')

# 写法二

with slim.arg_scope([slim. conv2d], kernel_size = [3, 3], weights_initializer = tf.truncated_normal_initializer(stddev = 0.01)):
	net = slim.conv2d(net, 32, scope = 'conv_1')
	net = slim.conv2d(net, 64, scope = 'conv_2')
	net = slim.conv2d(net, 128, scope = 'conv_3')

猜你喜欢

转载自blog.csdn.net/vinceee__/article/details/88250220