tensorflow input pipline 学习笔记

参考资料:

tf_doc_Reading data

TENSORFLOW INPUT PIPELINE EXAMPLE

tensorflow:理解tensorflow中的输入管道

第二个参考资料是第一个的翻译版本,翻译的水平一般,建议看原文,不是很长。

下面是我挑了文章中重点的部分+自己的理解。

TL;DR;

一个适用于不是很大的数据集的pipline input 的例子。

Load Data in Tensorflow

input pipline 可以理解称一种load data的方式。 一般有两种方式load data,一种是比较传统的,使用feed 的方式。如果数据集比较大,这种方式就不适用了,因为这种方式需要将数据全部导入到memory中。因此tf提供了pipline input的读入数据的方式。

input pipline 会处理 csv file,解码文件格式,重构数据结构,打乱数据顺序,做数据扩充或者其他预处理,然后使用线程(threads)将数据导进batch.

Load the Label Data

确保使用正确的dataset,csv文件路径。

然后处理 得到train和test 的label

由于我们只是读数据而没有真的打算训练,所以没有使用one-hot的编码方式,而是直接将(本来也是由数字字符组成的)字符串,转化成int.

Do Some Optional Processing on Our String Lists

Start Building the Pipeline

确保tensor的 dtype和list中的数据的type相匹配。

Lets Partition the Data

这是一个可选的步骤。可能由于我们的数据集比较大,我们先把它分成train set 和 test set

A visualization of the dynamic partition function in tensorflow.

 

Build the Input Queues and Define How to Load Images

 

使用slice_input_producer 切分 tensor,得到一个个的实例(?),然后使用线程 queue them up.

shuffle表示是否打乱数据,此处我们不打乱。

Group Samples into Batches

单个sample训练效率会很低,通常的做法是将若干个samples合成一个batch一起训练。每个batch中samples的个数就是所谓的batch_size

到目前为止我们只是描述了pipline大致的样子,但是tensorflow还不知道我们image数据的shape.  在使用tf.train_batch将samples合成若干个batch之前,我们需要首先定义image

tensor 的 shape

Run the Queue Runners and Start a Session

 

到目前为止我们已经构建好了input pipline.但是为了将pipline 启动,我们还需要使用线程,线程将加载queue,将数据导入tensorflow objects.

 

如下面的输出所示,tensorflow 不会关心epoch(全部数据过了一遍叫一个epoch)的数值,所以需要你自己手动统计。

Complete Code for this example

 

 

 

tensorflow 合并模型

在这里存个备份,还有些问题没有解决。

raise ValueError(“GraphDef cannot be larger than 2GB.”)

记录一些思路好了。现在是没有生成.meta文件,爆掉应该是因为所有的变量都加载到了默认图里。

也就是说我处理完checkpoint 0 之后开始处理checkpoint1,但是checkpoint0的那些变量还是存在的…所以越来越多?

目前有两个想法,第一个想法是是受TensorFlow极简教程:创建、保存和恢复机器学习模型  中启发,用多个saver,每个saver指定要搞的图(但是这样好像要每个checkpoint都是不同的saver才有意义?)

第二个想法是,每次save完变量之后,将图恢复成默认状态(可以把图中所有变量清空。。

 

想法二大失败:

会遇到if self.stack[-1] is not default: │
IndexError: list index out of range   的问题。。

根据 reset_default_graph awkwardly breaks graph nesting        

中提到了。。。reset_default_graph本身就不舍被设计成放在graph中清空变量用的。。。然后tf的代码也写得很不友好。。。没有 指明这个错误的原因。。。

For historical context,  tf.reset_default_graph() was never designed to be used with  with g.as_default(): context managers. I think the proper fix here is to make  tf.reset_default_graph() fail with an informative error message when used inside a  with g.as_default(): context. I think this could be done by checking that  ops._default_graph_stack is empty before resetting.

 

嘛。。先不管了。。。据数据那边说已经够用了。下面是最终版本,没有合并动量,因为对验证没有作用。

 

20170822update:去掉了卷基层的动量,添加了一些超参

 

tensorflow:tf.shape(a)和a.get_shape()区别

 

相同点:都可以得到tensor a的尺寸

不同点:tf.shape()中a 数据的类型可以是tensor, list, array

a.get_shape()中a的数据类型只能是tensor,且返回的是一个元组(tuple)

 

tensorflow checkpoint 学习笔记

参考资料:

What is the TensorFlow checkpoint meta file?

TensorFlow: Restoring variables from from multiple checkpoints

合并模型的时候发现.meta一直在累加,而其他数据文件没有改变。因此来探究一下checkpoint的几个文件的含义。

This file contains a serialized  MetaGraphDef protocol buffer. The  MetaGraphDef is designed as a serialization format that includes all of the information required to restore a training or inference process (including the  GraphDef that describes the dataflow, and additional annotations that describe the variables, input pipelines, and other relevant information). For example, the  MetaGraphDef is used by TensorFlow Serving to start an inference service based on your trained model. We are investigating other tools that could use the  MetaGraphDef for training.

Assuming that you still have the Python code for your model, you do not need the  MetaGraphDefto restore the model, because you can reconstruct all of the information in the  MetaGraphDef by re-executing the Python code that builds the model. To restore from a checkpoint, you only need the checkpoint files that contain the trained weights, which are written periodically to the same directory.

提到了.meta文件包含了恢复训练的所有信息。。。主要是为了其他工具可以快速恢复训练?

如果还是用python的话,恢复checkpoint没有必要使用.meta文件。

  • meta file: describes the saved graph structure, includes GraphDef, SaverDef, and so on; then apply  tf.train.import_meta_graph('/tmp/model.ckpt.meta'), will restore  Saver and  Graph.
  • index file: it is a string-string immutable table(tensorflow::table::Table). Each key is a name of a tensor and its value is a serialized BundleEntryProto. Each BundleEntryProto describes the metadata of a tensor: which of the “data” files contains the content of a tensor, the offset into that file, checksum, some auxiliary data, etc.
  • data file: it is TensorBundle collection, save the values of all variables.

 

Checkpoint

checkpoint文件可以理解成一个table,每次save之后会被更新,内容是最近一次的checkpoint文件名。

restore的时候,会先去checkpoint里看到最新的checkpoint文件是什么,然后只加载最新的。

 

tensorflow variable 学习笔记

参考资料:

programmers_guide/variables

tf/Variable

之前感觉对tensorflow 的variable的理解不是很深刻…跑个模型啥的倒不会有什么问题,但是涉及分布式,模型并行之类的,感觉有些地方还是要理解得仔细一点比较好。

OVERVIEW

variable的目的是将状态可持久化。

Unlike  tf.Tensor objects, a  tf.Variable exists outside the context of a single session.run call.

通俗地说就是,variable可以用来存储一个可持久化的tensor

一些op允许读取或者修改tensor的值,这些修改是跨session可见的,也就是说,对于用variable可持久化过的tensor,多个worker(多卡之间)之间可以看到相同的值

Creating a Variable

创建变量可以通过调用tf.get_variable function的方法实现。这个函数要求指明变量名称,这个名称会被作为标识该变量的key。

tf.get_variable也允许变量复用,意思是用之前创建过的有相同名字的变量,创建当前的变量。

Variable collections

由于在不同的部分创建了的变量可能有是够想一起访问,所以我们需要一个简单的能访问一个集合的变量的方法。tensorflow提供了collecetions,可以理解成python list,

是一个存储tensor,variable或者其他实例的容器。

默认情况下,tf.variable被收集到如下两个collcetions:

  • tf.GraphKeys.GLOBAL_VARIABLES:放置可以被多个设备共享的variable(从名字中的GLOBAL也可以看出来…)
  • tf.GraphKeys.TRAINABLE_VARIABLES:用来放置用来计算梯度的variable

如果不想训练某个variable,那么将它加入名字叫tf.GraphKeys.LOCAL_VARIABLES 的默认collection…

下面是一个将名字叫my_local的variable加入tf.GraphKeys.LOCAL_VARIABLES的例子

一个等价写法是,将trainable属性设置为False

当然自定义collcetion也是可以的,名字可以是任何字符串。

Device placement

variable和op一样,也可以放在指定的设备上。

在分布式tensorflow中,variable放在合适的设备上非常重要,如果不慎将variable 放在了 worker(GPU device)而不是PS(CPU device)上,将会严重减慢训练速度

基于这样的原因,我们提供replica_device_setter,来自动将variable放置在ps上…默认是轮盘转的放置策略

Initializing variables

在使用一个变量之前,必须先进行初始化。如果你用原生tensorflow,那初始化一般要手动显示完成。如果是使用slim,keras之类,variable的初始化一般是自动完成的。

Explicit initialization is otherwise useful because it allows you not to rerun potentially expensive initializers when reloading a model from a checkpoint as well as allowing determinism when randomly-initialized variables are shared in a distributed setting.

另一方面,明确地初始化可以保证你不会多次运行计算代价可能很昂贵的初始化操作,当你reload一个模型时。

一次性初始化所有变量可以使用tf.global_variables_initializer(),运行
session.run(tf.global_variables_initializer())
这个操作会把tf.GraphKeys.GLOBAL_VARIABLES 中的所有变量初始化。

也可以手动初始化特定变量,

还可以得到当前没有被初始化的变量有那些(这样就可以只初始化仍然没有初始化的变量,避免重复初始化,减小计算代价。

需要注意的是,tf.global_variables_initializer()初始化所有变量时并没有固定的顺序,所以如果你的某个variable的值依赖于另一个variable的值,那么就很可能出错。

Any time you use the value of a variable in a context in which not all variables are initialized (say, if you use a variable’s value while initializing another variable), it is best to use  variable.initialized_value() instead of  variable:

任何时候如果你处于一个不是所有变量都被初始化 的环境,最后使用myvar.initialized_value()来替代myvar

Using variables

variable可以直接看做tensor

对变量赋值可以使用assign,assign_add或者tf.variable class中的方法

Saving and Restoring

 

保存和恢复一个模型的最容易的方法就是使用tf.train.Saver object. 该object包含save和restore两个op,

使用save 或者 restore  op来保存或者恢复图中全部,或者指定的varibales

如果想在图外面恢复一个模型的checkpoint,必须先用tf.train.import_meta_graph将checkpoint中的metafile(以meta为后缀)的文件导入

这样会返回一个Saver object,然后才能执行resotre op

Checkpoint Files

 

tensorflow将variable存储为二进制文件的形式,通俗地说,就是map variable names to tensor values

当你创建了Saver object 之后,你可以选择为你保存进checkpoint files 文件的变量起一个名字。默认情况下,变量被使用tf.Variabel.name的名字。

如果想检查checkpoint 中的variable,可以使用inspect_checkpoint库,尤其是其中的print_tensors_in_checkpoint_file 函数。

Saving Variables

下面是一个如何使用Saver object 中的save操作来保存变量的例子

Restoring Variables

注意从checkpoint文件中恢复variables的时候没有必要初始化

下面是一个使用saver object 的restore op的例子:

Choosing which Variables to Save and Restore

如果tf.train.Saver()中不传入任何参数就会默认处理所有变量。

我们可以传入一些变量名,表示处理特定的变量。例子如下:

需要注意的是:

  • Saver object可以有任意多个,同一个变量也可以被任意多个Saver object save
  • restore的时候如果只是restore了一部分变量,其余的变量记得要初始化

Sharing variables

暂时用不上,有空补吧,困了orz

 

 

 

tensorflow Session 学习笔记

tensorflow-session官方文档

说下我自己的理解:

session中文一般叫会话,可以理解成op执行时候需要的一层虚拟化的封装。

op必须在session中才能执行。

tensor也是在tensor中才可以存在(tf.variable和tensor几乎是一回事,只是tf.variable的会话不要求session,也可以理解成tf.variable在session中就成了tensor.

需要注意的是session一般会占据资源,所以在使用完记得释放,或者写成with的形式(看到with总想叫成开域语句…感觉暴露年龄orz

下面这两种形式是等价的:

session本身有一些配置,我们使用configproto:

allow_soft_placement的作用是自动选择可用的设备(如果指定的设备不可用(?)),防止指定的设备不可用而挂掉的情况。

log_device_placement :To find out which devices your operations and tensors are assigned to.

 

 

 

 

 

使用tensorboard 生成 graph的方法

tf的文档真的是…其实就一句话啊orz

使用上还是多参考CS20SI比较好orz

CS20SI-slides2

Distributed Tensorflow : Cannot assign a device for operation save

是在使用分布式tensorflow遇到的一个错误

报错如下:

InvalidArgumentError (see above for traceback): Cannot assign a device for operation ‘save/Rest│| 2 GeForce GTX 1080 On | 0000:08:00.0 Off | N/A |
oreV2_888’: Operation was explicitly assigned to /job:worker/task:0/device:CPU:0 but available │| 24% 39C P8 12W / 180W | 0MiB / 8114MiB | 0% Default |
devices are [ /job:localhost/replica:0/task:0/cpu:0, /job:localhost/replica:0/task:0/gpu:0 ]. Make sure the device specification refers to a valid device.

其中看到Distributed Tensorflow : Cannot assign a device for operation. 中提到,可能的两个原因是:

I have mostly seen the “cannot assign a device for operation …” error in the case of people using GPU without specifying allow_soft_placement=True but in my case I am using just CPUs.

I have seen another instance of this error when users were not specifying server.target as the device of a session,thereby creating a local session but this is not the case in my code.

 

 

分布式tensorflow 设备分配 学习笔记

 

 

replica_device_setter_TF官网文档

由于看到这个函数很是激动。。。感觉这个东西也是蛮重要的。。之前完全手动分配累死辣。。。

所以单独写一篇,主要是翻译replica_device_setter的文档,之后和分布式 tensorflow 设备分配相关的内容也会放在这里

tf.train.replica_device_setter

函数原型

用法

device functions是用在tf.device(device_function) 中来自动向op objects 分配设备的。

设备的作用域优先级从内向外(类似变量的作用域

目前可以设置的域的关键字有(job, task, cpu/gpu)

如果cluster没有被定义,并且ps_tasks为0,那么该函数返回一个no-op(no-op应该就是operation界的null类型)

默认情况下,只有变量的op会被放在ps上,放置策略是在 所有ps tasks上用 Round-robin

该策略也可以自定义,参考GreedyLoadBalancingStrategy

例子

参数

  • ps_tasks: Number of tasks in the  ps job. Ignored if  cluster is provided.
  • ps_device: String. Device of the  ps job. If empty no  ps job is used. Defaults to  ps.
  • worker_device: String. Device of the  worker job. If empty no  worker job is used.
  • merge_devicesBoolean. If  True, merges or only sets a device if the device constraint is completely unset. merges device specification rather than overriding them.
  • clusterClusterDef proto or  ClusterSpec.
  • ps_ops: List of strings representing  Operation types that need to be placed on  ps devices. If  None, defaults to  ["Variable"].
  • ps_strategy: A callable invoked for every ps  Operation (i.e. matched by  ps_ops), that takes the  Operation and returns the ps task index to use. If  None, defaults to a round-robin strategy across all  ps devices.

 

 

 

其他

allow_soft_placement:session的一个属性,可以用来防止指定的设备不存在而导致无法运行的情况。设置为true会自动选择存在的设备。

 

 

分布式 tensorflow 学习笔记(非最终版)

感觉资料不是很多,先收集资料好了。

tf-distributed官网文档

SO-between-graph和in-graph的区别

inception.README.md

SyncReplicasOptimizer

SO_How does ps work in distribute Tensorflow?

 

update:在多个nodes(机)上跑。。。tf默认是异步更新的。。。同步的话。。大概需要syncreplicasoptimizer?

来直观感受下,不同task的之间并不同步

创建一个cluster

每一个task唯一对应一个server,server中有一个master,还有若干个worker

cluster是task的集合

cluster是在处理分布式问题时抽象出的概念,类似缩点。

cluster也可以划分成一个或者多个job,每个job包含一个或者多个task.

所以task,job,cluster的关系,从集合的角度考虑:

task的集合中的元素,job是task的(不相交?)子集,cluster是task的全集。

似乎要求所有job的交为空,所有job的补为全集,也就是似乎不能越过job直接到taks(?)

如下图:

A TensorFlow “cluster” is a set of “tasks” that participate in the distributed execution of a TensorFlow graph. Each task is associated with a TensorFlow “server”, which contains a “master” that can be used to create sessions, and a “worker” that executes operations in the graph. A cluster can also be divided into one or more “jobs”, where each job contains one or more tasks.

 

通常不同的task运行在不同的machine上,不过也可以运行在同一个machine的不同device上(比如一个机器的多个gpu)

 

为了创建一个cluster,要做如下步骤:

创建 一个  tf.train.ClusterSpec 来描述cluster中的全部tasks

cluster通过一个dictionary将job(task) map到网络地址,我们将这个地址传递给 tf.train.ClusterSpec 构造器,看如下例子:

我们观察到,task的id是0-base,按照dictionary中的key的顺序自动递增编号的。

在每一个task中创建一个 tf.train.Server的实例

tf.train.server包含一些local devices,以及他们和tf.train.clusterspec中描述的其他tasks的connections,还有一个tf.session来实现分布式计算(的交互)

cluster的每个server可以和该cluster中的任意其他server通信

在你的模型中指定分布式设备

还是用tf.device(),直接看代码:

 

In the above example, the variables are created on two tasks in the  ps job, and the compute-intensive part of the model is created in the  worker job. TensorFlow will insert the appropriate data transfers between the jobs (from  ps to  worker for the forward pass, and from  worker to  ps for applying gradients).

 在上面的代码中,变量被创建在了ps 上的两个task,模型的计算密集不问被创建在了worker上 。

tensorflow会插入合适的传输(组件)来(自动地)保证ps和worker的通信(fordward pass时从ps到worker,apply gradients时从worker到ps)

大概就是下面这个图的过程:

Partitioned Graph

 

 

 

上面SO的链接中提到了:

Anyway, both “worker” and “ps” are tasks (or jobs rather, which are just groups of tasks), so they’re really no different. The difference is what they’re supposed to be used for. The idea is that state (e.g.  tf.Variable) should be on the parameter servers, while operations for calculating state should be on the workers. Instead of achieving this by calling  tf.device manually everywhere, a helper function named  tf.train.replica_device_setter is used that sets a  tf.Variable’s device to a parameter server, and the other operations to a worker.

server.join() just means that parameter servers will wait on the workers, instead of terminating their client processes immediately.

和我之前的理解基本一致,不过重点是里面提到了名字叫 tf.train.replica_device_setter 的函数,推荐使用这个函数去指定分布式设备,而不是手动指定。

 

 

Replicated training

 

一种常见的训练方式叫做“数据并行”,涉及到在一个worker中的多个tasks在不同的mini-batch数据上训练同一个模型,然后更新存放在ps中的共享参数。在tensorflow中完成这样的结构有很多方法,我们构建了一些库去简化replicated trainning的操作,可能的方法如下:

 

  • In-graph replication. In this approach, the client builds a single  tf.Graph that contains one set of parameters (in  tf.Variable nodes pinned to  /job:ps); and multiple copies of the compute-intensive part of the model, each pinned to a different task in  /job:worker.
  • Between-graph replication. In this approach, there is a separate client for each  /job:worker task, typically in the same process as the worker task. Each client builds a similar graph containing the parameters (pinned to  /job:ps as before using  tf.train.replica_device_setter to map them deterministically to the same tasks); and a single copy of the compute-intensive part of the model, pinned to the local task in  /job:worker.
  • Asynchronous training. In this approach, each replica of the graph has an independent training loop that executes without coordination. It is compatible with both forms of replication above.
  • Synchronous training. In this approach, all of the replicas read the same values for the current parameters, compute gradients in parallel, and then apply them together. It is compatible with in-graph replication (e.g. using gradient averaging as in the CIFAR-10 multi-GPU trainer), and between-graph replication (e.g. using the  tf.train.SyncReplicasOptimizer).

 

 

 

tensorflow Supervisor 学习笔记

update:supervisor的缺点是遇到问题只会抛异常,所以现在有一个better的管理工具,MonitoredSession

master,chief worker,Supervisor 这几个概念有点搞不清(我最菜.jpg  因此来学习一下。

概述

原生的tensorflow 是各种东西都需要自己手动,如果是小规模的训练问题倒是不大,但是如果是训练的数据量比较大,可能需要训练几天或者几个月。。。

那原生的tensorflow的健壮性可能就比较堪忧。。。

万一断电了之类。。。

这时候我们就可以使用supervisor

其主要提供下面三个功能,以增强训练的健壮性:

  • Handles shutdowns and crashes cleanly.
  • Can be resumed after a shutdown or a crash.
  • Can be monitored through TensorBoard.

supervisor可以看做一个工具,或者说是对原生tensorflow的一层封装,目的主要是通过定期save的方法增强训练健壮性,

就算程序挂掉了也可以从上一次save的checkpoint恢复,而不是从头再来(虽然这些也可以手动实现(?)

同时也可以简化代码量

除了supervisor,还有tf.learn库,里面提供对原生tensorflow更高层的封装,也提供更丰富的功能。

 

实例

来举个具体的例子好了:

在不使用supervisor的时候,我们的训练代码如下:

如果使用supervisor,代码如下:

 

结论

从上面代码可以看出, Supervisor帮助我们处理一些事情
(1)自动去checkpoint加载数据或初始化数据
(2)自身有一个 Saver,可以用来保存checkpoint
(3)有一个 summary_computed用来保存 Summary
所以,我们就不需要:
(1)手动初始化或从 checkpoint中加载数据
(2)不需要创建 Saver,使用 sv内部的就可以
(3)不需要创建 summary writer

 

 

参考资料:

tensorflow学习笔记(二十二):Supervisor

Supervisor: Training Helper for Days-Long Trainings.

 

TensorFlow Architecture 学习笔记(二)Adding a New Op

Adding a New Op

Implement the kernel for the op

需要注意的是,你定义的运算的kernel可能被并行地访问,所以要求 Compute method 一定是线程安全的。

可以通过添加互斥锁(c++11?)或者完全就不要通过类成员来共享状态。

可以使用  ResourceMgr 来追踪运算的状态。

 

Multi-threaded CPU kernels

要实现多线程cpu版本的kernel,可以参考  work_sharder.h

GPU kernels

—–先忙手头工作了,有时间再更orz

 

TensorFlow Architecture 学习笔记(一)

这篇文章不会涉及tensorflow的具体使用,而是专注于介绍tensorflow的架构,目的是让开发者能够对tensorflow现有框架进行自定义的扩展。

tensorflow被设计用来处理大规模分布式训练,但是也足够灵活去处理新的machine learning模型或是系统层面的优化。

Overview

tensorflow的结构图如下:

TensorFlow Layers

从下往上大致上抽象程度越来越高。

其中C API那一层将tensorflow底层的runtime core 封装成不同语言(python,cpp,etc)的用户层代码,并提供相应的接口

这篇文章主要侧重如下layer:

  • Client:
  • 将计算定义为数据流图.
  • 使用 session(会话)启动图 的执行
  • Distributed Master
  • 通过Session.run()中参数的定义,修改图中特定的子图
  • 将子图分成多个pieces,使之运行在不同的进程和设备中)
  • 将得到的pieces分发到 worker services上
  • 由worker services 启动graph pieces
  • Worker Services (one for each task)
  • Schedule the execution of graph operations using kernel implementations appropriate to the available hardware (CPUs, GPUs, etc).
  • 使用kernel中对于特定硬件设备(cpu,gpu,etc)合适的实现去安全图中操作的执行。
  • 从其他worker service 处发送或接收运算结果
  • Kernel Implementations
  • 完成各个操作的计算

 

client,master,worker的关系如下

TensorFlow Architecture Diagram

“/job:worker/task:0” 和”/job:ps/task:0″都是运行在worker service上的tasks

其中ps是“parameter server”的缩写,也就是参数服务器。

PS负责模型参数的存储和更新,其他task在优化模型的参数的时候,会将更新传给ps

ps的命名是按照使用来定义的,也就是哪个(些)worker services 用来承担了 parmmeter server 的task,那么其就被称之为ps

需要注意的是maaster和worker service是分布式tensorflow框架才有的概念。

Client

client就是和用户直接接触的那一层。用户通过Client program完成图的定义。

clinet program 中的operation可以是自己定义的,也可以直接调用现成的一些库

之后client 创建 一个session,session将刚刚定义好的图传到master节点,当client想要计算图中某个节点时,就会触发对master节点的调用从而开始计算。

下面为运算 S+=w*x+b 所建的图:

TensorFlow Architecture Diagram: Client

Distributed master

  • 对graph进行修剪以获得 完成client要求的运算所需要的子图。
  • 划分graph,得到为每一个设备准备的graph pieces
  • 将这些graph pieces 缓存起来,以期在接下来的步骤中复用。

由于master节点可以看到计算的全局步骤,因此在master节点处可以进行一些常见的编译优化。

比如Common_subexpression_elimination 和Constant folding

所谓common_subexpression_elimination,指的就是对于同一个表达式的重复运算,我们在第一次运算后将其存起来,下次直接调用,以空间换时间

比如下面这个例子

核心思想就是添加记忆化,尽力不做重复计算

而所谓constant folding,其实就是在编译期间,将可以化简的常数先计算出来。通常在编译的中间代码生成阶段完成。

在进行完这些优化后,master将优化过的子图的执行分配到不同的task上(此时只是设定分配方案

TensorFlow Architecture Diagram: Master

 

下图是一个图的可能的划分(partition)

 

Partitioned Graph

由于划分成了不同的task,在不同的卡上运行,因此出现了通信的问题。

因此在被划分的位置,添加recv和send节点来在不同的task之间传递信息,如下图:

Partitioned Graph

 

然后master节点按照之前的分配,将graph pieces 传送给不同的task

Partitioned Graph

 

 

 

Worker Service

  • 处理来自master节点的请求
  • 安排构成子图的运算的核心程序(kernels)
  • 协调task之间的通信任务

简单说明下对于不同的设备,Send和Recv操作:

  • cpu和gpu之间的通信使用 cudaMemcpyAsync() API
  • gpu之间的通信直接使用端到端的DMA,避免了经过cpu通信的昂贵代价。a

对于task之间的通信,tensorflow使用了多种协议,包括:

  • gRPC over TCP.
  • RDMA over Converged Ethernet.

除此之外,对于多个gpu之间的通信,我们也已经开始准备支持NVIDIA’s NCCL library.

Partitioned Graph

 

Kernel Implementations

runtime本身包含200+个标准运算,对于有些通过标准运算难以构成的图,用户可以注册额外的kernel来实现自定义的运算。

这个过程需要编写cpp代码实现。

其中 XLA Compiler 提出了一些实验性的解决方法,可以参考。

XLA是一个google专门为tensorflow设计的,用来加速线性代数运算的编译器。

关于XLA的内容,见________(我还没有写orz

 

 

 

 

 

how to copy & modify nets model on tensorflow slim

想要修改tensorflow-slim 中 nets中的某个model,例如明明为kk_v2.py

观察到train_image_classifier.py中调用模型的部分

调用了nets_factory.get_network_fn,get_network如下:

 

我们看到model name 是通过 networks_map映射到func的

因此需要添加对于我们新的model,kk_v2的映射

由于train_image_classifier.py中有如下参数,

因此还需要修改预处理的映射表

还要修改arg_scopes_map,添加kk_v2的key