TF-Slim的优势:slim作为一种轻量级的tensorflow库,使得模型的构建,训练,测试都变得更加简单。

1. 使用方法:

import tensorflow.contrib.slim as slim

2. 组成部分:

arg_scope: 使得用户可以在同一个arg_scope中使用默认的参数

data,evaluation,layers,learning,losses,metrics,nets,queues,regularizers,variables

3. 定义模型

在slim中,组合使用variables, layers和scopes可以简洁的定义模型。

(1)variables: 定义于variables.py。生成一个weight变量, 用truncated normal初始化它, 并使用l2正则化,并将其放置于CPU上, 只需下面的代码即可:

weights = slim.variable('weights', shape=[10, 10, 3 , 3],

initializer=tf.truncated_normal_initializer(stddev=0.1),

regularizer=slim.l2_regularizer(0.05),

device='/CPU:0')

原生tensorflow包含两类变量:普通变量和局部变量。大部分变量都是普通变量,它们一旦生成就可以通过食用saver存入硬盘,局部变量只在session中存在,不会保存。

slim进一步的区分了变量类型,定义了model variables,这种变量代表了模型的参数。模型变量通过训练活着微调而得到学习,活着在评测或前传中可以从checkpoint文件中载入。

非模型参数在实际前传中不需要的参数,比如global_step。同样的,移动平均反应了模型参数,但它本身不是模型参数。例子见下:

  # 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()
  # model_variables包含weights
  # Regular variables
  my_var = slim.variable('my_var',
   shape=[20, 1],
  initializer=tf.zeros_initializer())
  regular_variables_and_model_variables = slim.get_variables()
  #get_variables()得到模型参数和常规参数 当我们通过slim的layers或着直接使用slim.model_variable创建变量时,tf会将此变量加入tf.GraphKeys.MODEL_VARIABLES这个集合中,当你需要构建自己的变量时,可以通过以下代码
将其加入模型参数。
  my_model_variable = CreateViaCustomCode()

  # Letting TF-Slim know about the additional variable.
  slim.add_model_variable(my_model_variable)
(2)layers:抽象并封装了常用的层,并且提供了repeat和stack操作,使得定义网络更加方便。
下面的代码利用repeat实现了三个卷积层的堆叠
  net = slim.repeat(net, 3, slim.conv2d, 256, [3, 3], scope='conv3')
repeat不仅只实现了相同操作相同参数的重复,它还将scope进行了展开,例子中的scope被展开为 'conv3/conv3_1', 'conv3/conv3_2' and 'conv3/conv3_3'。
slim.stack 操作使得我们可以重复的讲同一个操作以不同参数一次作用于一些层,这些层的输入输出时串联起来的。比如:
  slim.stack(x, slim.fully_connected, [32, 64, 128], scope='fc')
  slim.stack(x, slim.conv2d, [(32, [3, 3]), (32, [1, 1]), (64, [3, 3]), (64, [1, 1])], scope='core')
(3)scopes:除了tensorflow中的name_scope和variable_scope, tf.slim新增了arg_scope操作,这一操作符可以让定义在这一scope中的操作共享参数,即如不制定参数的话,则使用默认参数。且参数可以被局部覆盖。使得代码更加简洁,如下:
  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')
在此例子中,第一个arg_scope将weights_initializer和
def vgg16(inputs):
with slim.arg_scope([slim.conv2d, slim.fully_connected],
activation_fn=tf.nn.relu,
weights_initializer=tf.truncated_normal_initializer(0.0, 0.01),
weights_regularizer=slim.l2_regularizer(0.0005)):
net = slim.repeat(inputs, 2, slim.conv2d, 64, [3, 3], scope='conv1')
net = slim.max_pool2d(net, [2, 2], scope='pool1')
net = slim.repeat(net, 2, slim.conv2d, 128, [3, 3], scope='conv2')
net = slim.max_pool2d(net, [2, 2], scope='pool2')
net = slim.repeat(net, 3, slim.conv2d, 256, [3, 3], scope='conv3')
net = slim.max_pool2d(net, [2, 2], scope='pool3')
net = slim.repeat(net, 3, slim.conv2d, 512, [3, 3], scope='conv4')
net = slim.max_pool2d(net, [2, 2], scope='pool4')
net = slim.repeat(net, 3, slim.conv2d, 512, [3, 3], scope='conv5')
net = slim.max_pool2d(net, [2, 2], scope='pool5')
net = slim.fully_connected(net, 4096, scope='fc6')
net = slim.dropout(net, 0.5, scope='dropout6')
net = slim.fully_connected(net, 4096, scope='fc7')
net = slim.dropout(net, 0.5, scope='dropout7')
net = slim.fully_connected(net, 1000, activation_fn=None, scope='fc8')
return net
4. 训练模型
Tensorflow的模型训练需要模型,损失函数,梯度计算,以及根据loss的梯度迭代更新参数。
(1)losses
使用现有的loss:
loss = slim.losses.softmax_cross_entropy(predictions, labels)
对于多任务学习的loss,可以使用:
# Define the loss functions and get the total loss.
classification_loss = slim.losses.softmax_cross_entropy(scene_predictions, scene_labels)
sum_of_squares_loss = slim.losses.sum_of_squares(depth_predictions, depth_labels) # The following two lines have the same effect:
total_loss = classification_loss + sum_of_squares_loss
total_loss = slim.losses.get_total_loss(add_regularization_losses=False)
如果使用了自己定义的loss,而又想使用slim的loss管理机制,可以使用:
pose_loss = MyCustomLossFunction(pose_predictions, pose_labels)
slim.losses.add_loss(pose_loss)
total_loss = slim.losses.get_total_loss()
#total_loss中包涵了pose_loss
(2) 训练循环
slim在learning.py中提供了一个简单而有用的训练模型的工具。我们只需调用slim.learning.create_train_op 和slim.learning.train就可以完成优化过程。
g = tf.Graph()

# Create the model and specify the losses...
... total_loss = slim.losses.get_total_loss()
optimizer = tf.train.GradientDescentOptimizer(learning_rate) # create_train_op ensures that each time we ask for the loss, the update_ops
# are run and the gradients being computed are applied too.
train_op = slim.learning.create_train_op(total_loss, optimizer)
logdir = ... # Where checkpoints are stored. slim.learning.train(
train_op,
logdir,
number_of_steps=1000,#迭代次数
save_summaries_secs=300,#存summary间隔秒数
save_interval_secs=600)#存模型建个秒数
(3)训练的例子:
import tensorflow as tf

slim = tf.contrib.slim
vgg = tf.contrib.slim.nets.vgg ... train_log_dir = ...
if not tf.gfile.Exists(train_log_dir):
tf.gfile.MakeDirs(train_log_dir) with tf.Graph().as_default():
# Set up the data loading:
images, labels = ... # Define the model:
predictions = vgg.vgg16(images, is_training=True) # Specify the loss function:
slim.losses.softmax_cross_entropy(predictions, labels) total_loss = slim.losses.get_total_loss()
tf.summary.scalar('losses/total_loss', total_loss) # Specify the optimization scheme:
optimizer = tf.train.GradientDescentOptimizer(learning_rate=.001) # create_train_op that ensures that when we evaluate it to get the loss,
# the update_ops are done and the gradient updates are computed.
train_tensor = slim.learning.create_train_op(total_loss, optimizer) # Actually runs training.
slim.learning.train(train_tensor, train_log_dir)
5. 根据已有模型进行微调
(1)利用tf.train.Saver()从checkpoint恢复模型
# Create some variables.
v1 = tf.Variable(..., name="v1")
v2 = tf.Variable(..., name="v2")
...
# Add ops to restore all the variables.
restorer = tf.train.Saver() # Add ops to restore some variables.
restorer = tf.train.Saver([v1, v2]) # Later, launch the model, use the saver to restore variables from disk, and
# do some work with the model.
with tf.Session() as sess:
# Restore variables from disk.
restorer.restore(sess, "/tmp/model.ckpt")
print("Model restored.")
# Do some work with the model
...
(2)部分恢复模型参数
# Create some variables.
v1 = slim.variable(name="v1", ...)
v2 = slim.variable(name="nested/v2", ...)
... # Get list of variables to restore (which contains only 'v2'). These are all
# equivalent methods:
variables_to_restore = slim.get_variables_by_name("v2")
# or
variables_to_restore = slim.get_variables_by_suffix("2")
# or
variables_to_restore = slim.get_variables(scope="nested")
# or
variables_to_restore = slim.get_variables_to_restore(include=["nested"])
# or
variables_to_restore = slim.get_variables_to_restore(exclude=["v1"]) # Create the saver which will be used to restore the variables.
restorer = tf.train.Saver(variables_to_restore) with tf.Session() as sess:
# Restore variables from disk.
restorer.restore(sess, "/tmp/model.ckpt")
print("Model restored.")
# Do some work with the model
...
(3)当图的变量名与checkpoint中的变量名不同时,恢复模型参数
当从checkpoint文件中恢复变量时,Saver在checkpoint文件中定位到变量名,并且把它们映射到当前图中的变量中。之前的例子中,我们创建了Saver,并为其提供了变量列表作为参数。这时,在checkpoint文件中定位的变量名,是隐含地从每个作为参数给出的变量的var.op.name而获得的。这一方式在图与checkpoint文件中变量名字相同时,可以很好的工作。而当名字不同时,必须给Saver提供一个将checkpoint文件中的变量名映射到图中的每个变量的字典,例子见下:
# Assuming that 'conv1/weights' should be restored from 'vgg16/conv1/weights'
def name_in_checkpoint(var):
return 'vgg16/' + var.op.name # Assuming that 'conv1/weights' and 'conv1/bias' should be restored from 'conv1/params1' and 'conv1/params2'
def name_in_checkpoint(var):
if "weights" in var.op.name:
return var.op.name.replace("weights", "params1")
if "bias" in var.op.name:
return var.op.name.replace("bias", "params2") variables_to_restore = slim.get_model_variables()
variables_to_restore = {name_in_checkpoint(var):var for var in variables_to_restore}
restorer = tf.train.Saver(variables_to_restore) with tf.Session() as sess:
# Restore variables from disk.
restorer.restore(sess, "/tmp/model.ckpt")
(4)在一个不同的任务上对网络进行微调
比如我们要将1000类的imagenet分类任务应用于20类的Pascal VOC分类任务中,我们只导入部分层,见下例:
image, label = MyPascalVocDataLoader(...)
images, labels = tf.train.batch([image, label], batch_size=32) # Create the model
predictions = vgg.vgg_16(images) train_op = slim.learning.create_train_op(...) # Specify where the Model, trained on ImageNet, was saved.
model_path = '/path/to/pre_trained_on_imagenet.checkpoint' # Specify where the new model will live:
log_dir = '/path/to/my_pascal_model_dir/' # Restore only the convolutional layers:
variables_to_restore = slim.get_variables_to_restore(exclude=['fc6', 'fc7', 'fc8'])
init_fn = assign_from_checkpoint_fn(model_path, variables_to_restore) # Start training.
slim.learning.train(train_op, log_dir, init_fn=init_fn) 

Tensorflow-slim 学习笔记(一)概述的更多相关文章

  1. Google TensorFlow深度学习笔记

    Google Deep Learning Notes Google 深度学习笔记 由于谷歌机器学习教程更新太慢,所以一边学习Deep Learning教程,经常总结是个好习惯,笔记目录奉上. Gith ...

  2. Struts2 学习笔记(概述)

    Struts2 学习笔记 2015年3月7日11:02:55 MVC思想 Strust2的MVC对应关系如下: 在MVC三个模块当中,struts2对应关系如下: Model: 负责封装应用的状态,并 ...

  3. μCos-ii学习笔记1_概述

    一.μCos-ii _概述 网上关于μCosii的文章多不胜数,本人学习的过程中也参考了很多人的理解和想法,看的是卢有亮老师的<嵌入式实时操作系统-μC/OS原理与实践>(第2版),同时也 ...

  4. TensorFlow深度学习笔记 循环神经网络实践

    转载请注明作者:梦里风林 Github工程地址:https://github.com/ahangchen/GDLnotes 欢迎star,有问题可以到Issue区讨论 官方教程地址 视频/字幕下载 加 ...

  5. TensorFlow 深度学习笔记 卷积神经网络

    Convolutional Networks 转载请注明作者:梦里风林 Github工程地址:https://github.com/ahangchen/GDLnotes 欢迎star,有问题可以到Is ...

  6. TensorFlow 深度学习笔记 TensorFlow实现与优化深度神经网络

    转载请注明作者:梦里风林 Github工程地址:https://github.com/ahangchen/GDLnotes 欢迎star,有问题可以到Issue区讨论 官方教程地址 视频/字幕下载 全 ...

  7. TensorFlow 深度学习笔记 逻辑回归 实践篇

    Practical Aspects of Learning 转载请注明作者:梦里风林 Github工程地址:https://github.com/ahangchen/GDLnotes 欢迎star,有 ...

  8. MyBatis学习笔记(一) 概述

    一.什么是MyBatis? MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过程以及高级映射.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBat ...

  9. Python学习笔记 - day1 - 概述及安装

    Python概述 Python是一种计算机程序设计语言.我们平时已经听说过很多种流行的编程语言,比如非常难学的C语言,非常流行的Java语言,适合网页编程的JavaScript语言等等. Python ...

  10. TensorFlow——深度学习笔记

    深度学习与传统机器学习的区别 传统机器学习输入的特征为人工提取的特征,例如人的身高.体重等,深度学习则不然,它接收的是基础特征,例如图片像素等,通过多层复杂特征提取获得. 深度学习.人工智能.机器学习 ...

随机推荐

  1. SESSION机制(转)

    转自:http://www.cnblogs.com/zyf-zhaoyafei/p/4477175.html 一:Session与Cookie Session:在服务器端创建并存放在服务器的内存中的, ...

  2. PHP自定义函数&数组

    <?php//生成随机数 和 时间函数//echo rand();//echo "<br>";//echo rand(0,10);//echo time();// ...

  3. CVE-2018-10945 mongoose越界访问

    Hello , I found a vulneratility in mg_handle_cgi function The function is in mongoose.c , line 8925  ...

  4. mysql 安装版

    安装 1.MySQL的安装类型选择: 在“Choose Setup Type”对话框有“Typical”默认安装类型:“complete"完全安装类型:Custom自定义安装类型. 我们选择 ...

  5. java 方法重写和属性重写

    重写,子类对父类方法不满意,重写,但这是重写,要与父类的方法一模一样.方法名相同:参数列表相同:返回值相同或子类的返回值是父类返回值的子类型,父类是long,子类是int也不可以,因为父类引用指向子类 ...

  6. 签署您的应用--手动签署 APK

    签署您的应用 本文内容 证书和密钥库 签署您的调试构建 调试证书的有效期 管理您的密钥 使用 Google Play 应用签名 自行管理您的密钥和密钥库 签署 APK 生成密钥和密钥库 手动签署 AP ...

  7. d3js layout 深入理解

    D3 layouts help you create more advanced visualisations such as treemaps: D3 layouts帮助您创造更加高级复杂的可视化图 ...

  8. [控件] LiveChangedImageView

    LiveChangedImageView 效果 说明 切换图片的时候自动根据图片的尺寸进行渐变式切换,效果很不错,使用非常容易. 源码 https://github.com/YouXianMing/U ...

  9. Mysql源码安装shell脚本

    #!/bin/bash#date:2019/1/20#by author zhangjia#install mysql#shell_name:mysql_auto_install.sh######## ...

  10. php面试题之一——php核心技术

    一.PHP核心技术 1.写出一个能创建多级目录的PHP函数(新浪网技术部) <?php /** * 创建多级目录 * @param $path string 要创建的目录 * @param $m ...