Slim的github地址:https://github.com/tensorflow/tensorflow/tree/master/tensorflow/contrib/slim
参考:https://blog.csdn.net/guvcolie/article/details/77686555
#1、Slim详解
#####Slim函数介绍
名称 | 使用介绍 |
---|---|
arg_scope | 与variable_scope类似,可以设置指定网络层的参数,比如stride、padding等 |
data | 在Slim中用于数据的输入,包括数据集定义、数据输入、队列读取以及数据解码等 |
evaluatiom | 用于评估模型的引用库 |
layers | 构建TensorFlow模型所使用的高级内容 |
learning | 用于训练模型的引用库 |
losses | 常用的损失函数库 |
metrics | 各种最新的评价指标,例如IOU等 |
nets | 最新的深度学习模型定义,例如VGG、AlexNet、ResNet |
queues | 提供了一个队列管理器,方便对TensorFlow中数据队列的开关进行管理 |
regularizers | 多种正则表达式 |
variables | 多种包装好的供TensorFlow直接使用的参数 |
#2、Slim使用方法介绍
使用Slim可以非常方便地定义相关模型,模型又可以简洁地定义使用已有的Slim变量、层次和范围。
##2.1、 Slim中变量使用方法介绍
在TensorFlow 中,变量定义分为两种,“普通变量”和“模型变量”。大多数的变量是普通变量,可以创建并且再整个程序运行周期内传送,在需要的情况下可以存储到硬盘上。而模型变量由于Python本身的“lazy”模式,只有在运行时才会被使用,使用完毕后即刻销毁而不会产生保存等问题。
下面举个例子说明模型变量和普通变量的区别:
模型变量:
weights = slim.model_variable('weights',
shape=[1, 217, 217, 3],
initializer=tf.truncated_normal_initializer(stddev=0.1),
regularizer=slim.l2_regularizer(0.05))
程序段中通过函数的定义设计了使用模型变量的定义,之后对其参数进行设置,定义了创建的数据维度、初始化方法以及正则化的规则。
再看程序:
import tensorflow.contrib.slim as slim
import tensorflow as tf
weight1 = slim.model_variable('weight1',
shape=[2, 3],
initializer=tf.truncated_normal_initializer(stddev=0.1),
regularizer=slim.l2_regularizer(0.05))
weight2 = slim.model_variable('weight2',
shape=[2, 3],
initializer=tf.truncated_normal_initializer(stddev=0.1),
regularizer=slim.l2_regularizer(0.05))
model_variables = slim.get_model_variables()
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
print(sess.run(weight1))
print("--------------------")
print(sess.run(weight2))
print("--------------------")
print(sess.run(model_variables))
print("--------------------")
print(sess.run(slim.get_variables_by_suffix("weight1")))
print("--------------------")
print(sess.run(slim.get_variables_by_suffix("weight2")))
定义了2个变量,分别是模型变量weight1和weight2,之后对其大小的设定和初始化定义,使用L2对数据进行正则化处理。
slim.get_model_variables()获取全部模型数据的函数,用户在定义完需要的模型变量值后,Slim类自动将获取到的模型变量添加到整体模型变量中。
打印结果如下:
[[ 0.00139582 -0.19977763 0.02281767]
[ 0.16938822 -0.11474594 0.03209985]]
--------------------
[[-0.0710931 -0.04360203 0.06652158]
[ 0.04989719 -0.06063947 -0.04058321]]
--------------------
[array([[ 0.00139582, -0.19977763, 0.02281767],
[ 0.16938822, -0.11474594, 0.03209985]], dtype=float32), array([[-0.0710931 , -0.04360203, 0.06652158],
[ 0.04989719, -0.06063947, -0.04058321]], dtype=float32)]
--------------------
[array([[ 0.00139582, -0.19977763, 0.02281767],
[ 0.16938822, -0.11474594, 0.03209985]], dtype=float32)]
--------------------
[array([[-0.0710931 , -0.04360203, 0.06652158],
[ 0.04989719, -0.06063947, -0.04058321]], dtype=float32)]
普通变量:
使用方法如下:
my_var = slim.variable('my_var',
shape=[20, 1],
initializer=tf.zeros_initializer())
regular_variables = slim.get_variables()
程序:
import tensorflow.contrib.slim as slim
import tensorflow as tf
weight1 = slim.variable('weight1',
shape=[2, 3],
initializer=tf.truncated_normal_initializer(stddev=0.1),
regularizer=slim.l2_regularizer(0.05))
weight2 = slim.variable('weight2',
shape=[2, 3],
initializer=tf.truncated_normal_initializer(stddev=0.1),
regularizer=slim.l2_regularizer(0.05))
variables = slim.get_variables()
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
print(sess.run(weight1))
print("--------------------")
print(sess.run(weight2))
print("--------------------")
print(sess.run(variables))
打印:
[[ 0.02926148 -0.05376805 -0.07609295]
[-0.02069373 -0.02604404 -0.08523823]]
--------------------
[[-0.00405583 0.09445325 -0.12710099]
[ 0.04769271 -0.06928015 -0.11333165]]
--------------------
[array([[ 0.02926148, -0.05376805, -0.07609295],
[-0.02069373, -0.02604404, -0.08523823]], dtype=float32),
array([[-0.00405583, 0.09445325, -0.12710099],
[ 0.04769271, -0.06928015, -0.11333165]], dtype=float32)]
##2.2、Slim中层的使用方法
与标准的TensorFlow类似,Slim也提供了所需要的方法执行不同的工作。
层名称 | TF-Slim |
---|---|
BiasAdd | slim.bias_add |
BatchNorm | slim.batch_norm |
Conv2d | slim.conv2d |
Conv2dInPlane | slim.conv2d_in_plane |
Conv2dTranspose (Deconv) | slim.conv2d_transpose |
FullyConnected | slim.fully_connected |
AvgPool2D | slim.avg_pool2d |
Dropout | slim.dropout |
Flatten | slim.flatten |
MaxPool2D | slim.max_pool2d |
OneHotEncoding | slim.one_hot_encoding |
SeparableConv2 | slim.separable_conv2d |
UnitNorm | slim.unit_norm |
使用这些Slim提供的简单的函数,可以很容易地构建出任何一个神经元模型,也可以通过这些函数。
##2.3、Slim中参数空间使用方法介绍
在TensorFlow中已经有可对于相关变量的命名方法,例如使用name_scope 、variable_scope等;而Slim中又提供了一种新的命名方式-参数空间arg_scope,这种新的命名参数空间方法允许用户将制定的一个或者多个操作和一组参数传递给arg_scope中定义的每个操作。
一个较为保守的系列卷积层的定义为:
net = slim.conv2d(inputs, 32, [3, 3], 4, padding='SAME',
weights_initializer=tf.truncated_normal_initializer(stddev=0.01),
weights_regularizer=slim.l2_regularizer(0.0005),
scope='conv1_1')
net = slim.conv2d(inputs, 64, [5, 5], padding='VALID',
weights_initializer=tf.truncated_normal_initializer(stddev=0.01),
weights_regularizer=slim.l2_regularizer(0.0005),
scope='conv1_2')
net = slim.conv2d(inputs, 128, [7, 7], padding='SAME',
weights_initializer=tf.truncated_normal_initializer(stddev=0.01),
weights_regularizer=slim.l2_regularizer(0.0005),
scope='conv1_3')
上面代码中包含了太多冗余的参数,各个卷积层中的初始化方法、正则化方式以及padding的方式都是相同,而过多的相同使得代码的读取难度增加,因此Slim增加了一个新的解决方法,使得具有相同的参数统一进行管理。
with 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中定义的每个操作。在其中的各个层可以不用显式地对这些参数进行定义,而只需要调用参数空间中的定义即可。
对于参数空间中所定义的默认参数值,是可以被空间所定义的各个层中的参数进行二次覆写:
with slim.arg_scope([slim.conv2d, slim.fully_connected],
activation_fn=tf.nn.relu,
weights_initializer=tf.truncated_normal_initializer(stddev=0.01),
weights_regularizer=slim.l2_regularizer(0.0005)):
with slim.arg_scope([slim.conv2d], stride=1, padding='SAME'):
net = slim.conv2d(inputs, 64, [11, 11], 4, padding='VALID', scope='conv1')
net = slim.conv2d(net, 256, [5, 5],
weights_initializer=tf.truncated_normal_initializer(stddev=0.03),
scope='conv2')
net = slim.fully_connected(net, 1000, activation_fn=None, scope='fc')
上面代码中,使用了2层参数空间对其中的层进行定义,第一层中定义了激活函数和权重的初始化方法以及正则化表达的方法,在第二层中定义了步进大小和padding方式。