Tensorflow-Slim简介
Slim简介
slim是一个使构建,训练,评估神经网络变得简单的库。它可以消除原生tensorflow里面很多重复的模板性的代码,让代码更紧凑,更具备可读性。另外slim提供了很多计算机视觉方面的著名模型(VGG, AlexNet等),我们不仅可以直接使用,甚至能以各种方式进行扩展。
- 导入Slim
1
import tensorflow.contrib.slim as slim
TF-Slim的优点
- 允许用户通过减少模板代码使得模型更加简洁。这个可以通过使用argument scoping和大量的高层layers、variables来实现
- 通过使用常用的正则化( regularizers)使得建立模型更加简单;
- 一些广泛使用的计算机视觉相关的模型(比如VGG,AlexNet)已经在slim中定义好了,用户可以很方便的使用;这些既可以当成黑盒使用,也可以被扩展使用,比如添加一些“multiple heads”到不同的内部的层;
- Slim使得扩展复杂模型变得容易,可以使用已经存在的模型的checkpoints来开始训练算法。
TF-Slim的主要组件
TF-Slim由几个独立存在的组件组成,主要包括以下几个:
arg_scope
提供一个新的作用域(scope),称为arg_scope,在该作用域(scope)中,用户可以定义一些默认的参 数,用于特定的操作;
如果你的网络中有大量的相同的参数:1
2
3
4
5
6
7
8
9net = slim.conv2d(inputs, 64, [11, 11], 4, padding='SAME',
weights_initializer=tf.truncated_normal_initializer(stddev=0.01),
weights_regularizer=slim.l2_regularizer(0.0005), scope='conv1')
net = slim.conv2d(net, 128, [11, 11], padding='VALID',
weights_initializer=tf.truncated_normal_initializer(stddev=0.01),
weights_regularizer=slim.l2_regularizer(0.0005), scope='conv2')
net = slim.conv2d(net, 256, [11, 11], padding='SAME',
weights_initializer=tf.truncated_normal_initializer(stddev=0.01),
weights_regularizer=slim.l2_regularizer(0.0005), scope='conv3')用arg_scope处理一下:
1
2
3
4
5
6with slim.arg_scope([slim.conv2d], padding='SAME',
weights_initializer=tf.truncated_normal_initializer(stddev=0.01)
weights_regularizer=slim.l2_regularizer(0.0005)):
net = slim.conv2d(inputs, 64, [11, 11], scope='conv1')
net = slim.conv2d(net, 128, [11, 11], padding='VALID', scope='conv2')
net = slim.conv2d(net, 256, [11, 11], scope='conv3')arg_scope在作用范围内定义了指定层的默认参数,若想特别指定某些层的参数,可以重新赋值(相当于重写)
data
包含TF-Slim的dataset定义,data providers,parallel_reader,和 decoding utilities;- evaluation
包含用于模型评估的常规函数; layers
包含用于建立模型的高级layers;
比如分别用TensorFlow和Slim实现一个卷积层的案例:1
2
3
4
5
6
7
8
9
10
11
12
13#tensorflow实现卷积层
with tf.name_scope('conv1_1') as scope:
kernel = tf.Variable(tf.truncated_normal([3, 3, 64, 128], dtype=tf.float32,
stddev=1e-1), name='weights')
conv = tf.nn.conv2d(input, kernel, [1, 1, 1, 1], padding='SAME')
biases = tf.Variable(tf.constant(0.0, shape=[128], dtype=tf.float32),
trainable=True, name='biases')
bias = tf.nn.bias_add(conv, biases)
conv1 = tf.nn.relu(bias, name=scope)
#slim实现卷积层
net = slim.conv2d(input, 128, [3, 3], scope='conv1_1')另外,比较吸引人的是slim中的repeat和stack操作,假设定义三个相同的卷积层,
1
2
3
4net = slim.conv2d(net, 256, [3, 3], scope='conv3_1')
net = slim.conv2d(net, 256, [3, 3], scope='conv3_2')
net = slim.conv2d(net, 256, [3, 3], scope='conv3_3')
net = slim.max_pool2d(net, [2, 2], scope='pool2')在slim中的repeat操作可减少代码量:
1
2net = slim.repeat(net, 3, slim.conv2d, 256, [3, 3], scope='conv3')
net = slim.max_pool2d(net, [2, 2], scope='pool2')stack是处理卷积核或者输出不一样的情况:假设定义三层FC:
1
2
3
4# Verbose way:
x = slim.fully_connected(x, 32, scope='fc/fc_1')
x = slim.fully_connected(x, 64, scope='fc/fc_2')
x = slim.fully_connected(x, 128, scope='fc/fc_3')使用stack操作:
1
slim.stack(x, slim.fully_connected, [32, 64, 128], scope='fc')
卷积层使用stack操作:
1
2
3
4
5
6
7
8# 普通方法:
x = slim.conv2d(x, 32, [3, 3], scope='core/core_1')
x = slim.conv2d(x, 32, [1, 1], scope='core/core_2')
x = slim.conv2d(x, 64, [3, 3], scope='core/core_3')
x = slim.conv2d(x, 64, [1, 1], scope='core/core_4')
# 简便方法:
slim.stack(x, slim.conv2d, [(32, [3, 3]), (32, [1, 1]), (64, [3, 3]), (64, [1, 1])], scope='core')learning
包含一些用于训练模型的常规函数;- losses
包含一些用于loss function的函数; - metrics
包含一些热门的评价标准; - nets
包含一些热门的网络定义,如VGG,AlexNet等模型; - queues
提供一个内容管理者,使得可以很容易、很安全地启动和关闭QueueRunners; - regularizers
包含权重正则化; - variables
提供一个方便的封装,用于变量创建和使用。
变量分为两类:模型变量和局部变量。局部变量是不作为模型参数保存的,而模型变量会再save的时候保存下来。诸如global_step之类的就是局部变量。slim中可以写明变量存放的设备,正则和初始化规则。还有获取变量的函数也需要注意一下,get_variables是返回所有的变量。
slim中定义一个变量的实例:1
2
3
4
5
6
7
8
9
10
11
12
13# Model Variables
weights = slim.model_variable('weights',
shape=[10, 10, 3 , 3],
initializer=tf.truncated_normal_initializer(stddev=0.1),
regularizer=slim.l2_regularizer(0.05),
device='/CPU:0')
model_variables = slim.get_model_variables()
# Regular variables
my_var = slim.variable('my_var',
shape=[20, 1],
initializer=tf.zeros_initializer())
regular_variables_and_model_variables = slim.get_variables()