首页 > 技术文章 > tf.contrib.slim的介绍

japyc180717 2018-08-04 17:09 原文

本文主要参考博客:博客连接

前言基础:

验证本地的tf.contrib.slim模块是否有效:

1 python -c  "import tensorflow.contrib.slim as slim;eval=slim.evaluation.evaluate_once"

 

下载models模块:

下载连接。下载后解压到你设定的文件夹,笔者解压到“E:\TENSORFLOW\models”

找到并且打开文件夹"E:\TENSORFLOW\models\research",找到slim文件夹,shift+右键点击slim文件夹,选择“在此处打开Powershell窗口”

输入命令:

1 python -c "from nets import cifarnet;mynet=cifarnet.cifarnet"

如图,如果没有报错,说明一切正常。

slim文件夹目录结构:

共包含5个文件夹,Datasets处理数据集相关代码,Deloyment通过创建clone方式实现跨机器的分布训练,可以在多CPU和GPU上实现运算的同步或者异步。

Nets放着各种网络模型,Preprocessing用于各个网络的图片处理函数。Scripts运行网路的一些脚本。

 

1.简介

slim是位于tf.contrib.slim位置,所以使用slim有两种方法

1 import tensorflow.contrib.slim as slim
2 
3 #或者
4 
5 slim=tf.contrib.slim

slim是一个使构建,训练,评估神经网络变得简单的库。它可以消除原生tensorflow里面很多重复的模板性的代码,让代码更紧凑,更具备可读性。

另外slim提供了很多计算机视觉方面的著名模型(VGG, AlexNet等),我们不仅可以直接使用,甚至能以各种方式进行扩展。

slim子模块介绍:

 1 arg_scope:
 2 除了基本的namescope,variabelscope外,又加了argscope,它是用来控制每一层的默认超参数的。
 3 
 4 layers:
 5 slim的核心和精髓,一些复杂层的定义
 6 
 7 learning: 
 8 一些训练规则
 9 
10 metrics: 
11 评估模型的度量标准
12 
13 nets:
14 非常重要,包含一些经典网络,VGG等。
15 
16 queues:
17 队列
18 
19 regularizers: 
20 包含一些正则规则
21 
22 variables:
23 slim管理变量的机制

2.slim定义模型

slim定义变量:

变量分为两类:模型变量和局部变量。局部变量是不作为模型参数保存的,而模型变量会再save的时候保存下来。这个玩过tensorflow的人都会明白,诸如global_step之类的就是局部变量。slim中可以写明变量存放的设备,正则和初始化规则。还有获取变量的函数也需要注意一下,get_variables是返回所有的变量。

 1 # Model Variables
 2 weights = slim.model_variable('weights',
 3                               shape=[10, 10, 3 , 3],
 4                               initializer=tf.truncated_normal_initializer(stddev=0.1),
 5                               regularizer=slim.l2_regularizer(0.05),
 6                               device='/CPU:0')
 7 model_variables = slim.get_model_variables()
 8  
 9 # Regular variables
10 my_var = slim.variable('my_var',
11                        shape=[20, 1],
12                        initializer=tf.zeros_initializer())
13 regular_variables_and_model_variables = slim.get_variables()

slim定义层:

1 input = ...
2 net = slim.conv2d(input, 128, [3, 3], scope='conv1_1')#分别对应输入,输出维度,卷积核,层的名字

更amazing...

如果像上面定义多个相同卷积层,比如:

1 net = ...
2 net = slim.conv2d(net, 256, [3, 3], scope='conv3_1')
3 net = slim.conv2d(net, 256, [3, 3], scope='conv3_2')
4 net = slim.conv2d(net, 256, [3, 3], scope='conv3_3')
5 net = slim.max_pool2d(net, [2, 2], scope='pool2')

我们可以通过使用slim.repeat()实现:

1 net = slim.repeat(net, 3, slim.conv2d, 256, [3, 3], scope='conv3')
2 net = slim.max_pool2d(net, [2, 2], scope='pool2')

而当卷积核不同时,可以使用slim.stack():

1 #原始重复定义
2 x = slim.fully_connected(x, 32, scope='fc/fc_1')
3 x = slim.fully_connected(x, 64, scope='fc/fc_2')
4 x = slim.fully_connected(x, 128, scope='fc/fc_3')
5 
6 #slim.srack简化:
7 slim.stack(x, slim.fully_connected, [32, 64, 128], scope='fc')

在卷积操作中,也可以同时改变卷积核和输出个数:

1 # 普通方法:
2 x = slim.conv2d(x, 32, [3, 3], scope='core/core_1')
3 x = slim.conv2d(x, 32, [1, 1], scope='core/core_2')
4 x = slim.conv2d(x, 64, [3, 3], scope='core/core_3')
5 x = slim.conv2d(x, 64, [1, 1], scope='core/core_4')
6  
7 # slim.stack()简化:
8 slim.stack(x, slim.conv2d, [(32, [3, 3]), (32, [1, 1]), (64, [3, 3]), (64, [1, 1])], scope='core')

slim管理大量参数:

slim.arg_scope()可以实现大量相同参数:

 1 #原始复杂大量相同参数:
 2 net = slim.conv2d(inputs, 64, [11, 11], 4, padding='SAME',
 3                   weights_initializer=tf.truncated_normal_initializer(stddev=0.01),
 4                   weights_regularizer=slim.l2_regularizer(0.0005), scope='conv1')
 5 net = slim.conv2d(net, 128, [11, 11], padding='VALID',
 6                   weights_initializer=tf.truncated_normal_initializer(stddev=0.01),
 7                   weights_regularizer=slim.l2_regularizer(0.0005), scope='conv2')
 8 net = slim.conv2d(net, 256, [11, 11], padding='SAME',
 9                   weights_initializer=tf.truncated_normal_initializer(stddev=0.01),
10                   weights_regularizer=slim.l2_regularizer(0.0005), scope='conv3')
11 
12 #使用slim.srg_scope()简化:
13 with slim.arg_scope([slim.conv2d], padding='SAME',
14                       weights_initializer=tf.truncated_normal_initializer(stddev=0.01)
15                       weights_regularizer=slim.l2_regularizer(0.0005)):
16     net = slim.conv2d(inputs, 64, [11, 11], scope='conv1')
17     net = slim.conv2d(net, 128, [11, 11], padding='VALID', scope='conv2')
18     net = slim.conv2d(net, 256, [11, 11], scope='conv3')

如果是多个层:

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')

 

推荐阅读