tensorflow高级API:Slim使用入门
终于想起来我的csdn密码了(好吧其实是懒)
————————分割线——————————
今天开始进入tensorflow的高级阶段——Slim。
Slim是Tensorflow在0.10版中新加入的一个用于定义、训练和评估较为复杂模型的轻量级开发类库,能大量地减少程序重复性的模板性程序代码的编写,让代码更加简洁。这主要得益于其在实际程序设计时使用了大量的“命名空间”(argument scoping)和不同层的变量。
此外,Slim提供了大量常用的简化模型可以直接调用,比如前面用到的AlexNet和VGG。
大纲:
- Slim中变量的使用
- Slim中层的使用
- Slim中参数空间的使用
Slim中变量的使用
在经典的tensorflow程序中,变量分为“普通变量”和“模型变量”。大多数的变量是普通变量,可以被创建并且在整个程序运行周期内传送,在需要的情况下可以被存储到硬盘上。使用方法如下:
import tensorflow.contrib.slim as slim
import tensorflow as tf
#Regular variables
my_var = slim.variable('my_var',
shape=[20, 1],
initializer=tf.zeros_initializer())
variables = slim.get_variables()
with tf. Session() as sess:
sess.run(tf.global_variables_initializer())
print(sess.run(my_var))
print("-------------")
print(sess.run(variables))
结果请自行打印.
而模型变量在发挥其作用之后会立刻被销毁,比如global_step、bn层中用到的均值与方差等。
其使用方法如下:
import tensorflow.contrib.slim as slim
import tensorflow as tf
#model variables
weight = slim.model_variable("weight", 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(weight))
print("-----------")
print(sess.run(model_variables))
print("-----------")
print(sess.run(slim.get_variables_by_suffix("weight")))
结果:
若想把用户自己定义的变量变为Slim变量,可以通过以下语句:
weight = tf.Variable(tf.ones([2, 3]))
slim.add_model_variable(weight)
Slim中层的使用
在tensorflow中,神经网络模型是由一层层的“层”所构成,例如卷积层、全连接层等。而在Slim当中,每一层可以简单的用一条语句来表示。例如卷积层:
conv = slim.conv2d(input, 128, [3, 3], scope='conv1_1')
而且,若要反复的执行一个层,可以这样写:
net = slim.repeat(inputs, 3, slim.conv2d, 128, [3, 3], scope="conv2")
参数分别为输入值, 循环次数, 层次类别, 输出通道数, 卷积核大小, 命名空间。
Slim中参数空间的使用
在先前的tensorflow学习中,我们已经知道如何对一个变量进行命名,而在Slim中提供了一种新的命名方式——参数空间arg_scope。
这种命名方式能够极大的简化代码的编写,并提高程序的可读性。
话不多说,直接上例子:
在之前的学习中,我们一般对一段卷积层这样定义:
import tensorflow.contrib.slim as slim
import tensorflow as tf
inputs = slim.variable("input", [32, 32])
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(net, 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')
可以看到,该代码存在太多的重复参数,使得代码长且难读,而在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, 32, [3, 3], scope='conv1')
net = slim.conv2d(net, 64, [5, 5], scope='conv2')
net = slim.conv2d(net, 128, [7, 7], scope='conv3')
并且,对于参数空间中定义的默认值,可以在层中通过二次复写来覆盖。
结语
hiahiahia以后随缘更新~~~~