本文目的

在介绍estimator分布式的时候,官方文档由于版本更新导致与接口不一致。具体是:在estimator分布式当中,使用dataset作为数据输入,在1.12版本中,数据训练只是dataset的数据,就是所有设备加起来,跑一遍数据。

而在2.0版本中,训练数据是dataset的数据乘以分

布式的设备数。也就是说,在每个设备当中都会完整地跑一遍dataset的所有数据。

1.12版本读取

1. 在主线程当中创建图

下面这段代码中,在client中调用了input function,得到迭代器。这是属于estimator distribute train调用的代码

with ops.Graph().as_default() as g:
# We want to create the iterations variable outside the distribution scope
# as that is just stored on the host and mainly used to drive the loop
# and doesn't need to be a Mirrored/Device variable.
if is_tpu_strategy:
steps_per_run_variable = training.get_or_create_steps_per_run_variable()
with self._train_distribution.scope():
random_seed.set_random_seed(self._config.tf_random_seed)
iterator, input_hooks = self._get_iterator_from_input_fn(
input_fn, model_fn_lib.ModeKeys.TRAIN, self._train_distribution)
  • _get_iterator_from_input_fn * 这个函数会生成迭代器供后续训练读取数据。
  def _get_iterator_from_input_fn(self, input_fn, mode, distribution=None):
if distribution is not None:
result = distribution.distribute_dataset(
lambda: self._call_input_fn(input_fn, mode))
else:
result = self._call_input_fn(input_fn, mode) iterator = result.make_initializable_iterator()
input_hooks = [estimator_util._DatasetInitializerHook(iterator)] # pylint: disable=protected-access
return iterator, input_hooks

这里会调用distribute_dataset生成dataset。

再点进去看以后可看到会创建这样一个PerDeviceDataset

class PerDeviceDataset(object):
"""Like `tf.data.Dataset` split devices, producing `PerDevice` data.""" def __init__(self, dataset, devices, prefetch_on_device=None):
self._devices = devices # Default to using prefetching in graph mode, unless specified.
# TODO(priyag): Enable prefetching in eager mode.
self._prefetch_on_device = prefetch_on_device
if self._prefetch_on_device is None:
self._prefetch_on_device = not context.executing_eagerly()
assert not (self._prefetch_on_device and context.executing_eagerly()), (
"Prefetching is only supported in graph mode currently") if self._prefetch_on_device:
self._dataset = dataset.apply(
prefetching_ops_v2.prefetch_to_devices(self._devices))
else:
# TODO(priyag): If dropping remainder is not appropriate, find another
# approach to distributing the dataset when not possible to divide evenly.
# Possibly not an issue when we start using PartitionedDataset.
self._dataset = dataset.batch(len(devices), drop_remainder=True)

最后一行代码可以看到,在原dataset上又封装了一层batch。将数据根据设备数切分。

后面创建迭代器也是封装为PerDeviceDataIterator,形成一个字典映射,不同设备不同数据,根据batch 的index切分。

分布式训练

在1.12版本中的训练比较简单。对于MirroredStrategy来说,会给每个一个device创建一个线程,

有一个缺点就是,每一次run都会创建线程,在todo里看到,后续会优化掉应该。

下面是在client中从迭代器获取数据,传递给每个device去运算的代码,

self._train_distribution.call_for_each_tower

features, labels = estimator_util.parse_iterator_result(
iterator.get_next())
grouped_estimator_spec = self._train_distribution.call_for_each_tower(
self._call_model_fn,
features,
labels, # although this will be None it seems
model_fn_lib.ModeKeys.TRAIN,
self.config)
loss = self._train_distribution.unwrap(
self._train_distribution.reduce(
distribute_lib.get_loss_reduction(),
grouped_estimator_spec.loss,
destinations='/device:CPU:0'))[0]
distributed_train_op = grouped_estimator_spec.train_op

call_for_each_tower是每个设备训练的接口

def _call_for_each_tower(distribution, fn, *args, **kwargs):
"""Run `fn` in separate threads, once per tower/worker device.
run_concurrently = kwargs.pop("run_concurrently", True)
if not context.executing_eagerly():
# Lots of TF library code isn't thread-safe in graph mode, and
# there is little to be gained by turning on multithreading when
# constructing a graph.
run_concurrently = False
# Needed for per-thread device, etc. contexts in graph mode.
ops.get_default_graph().switch_to_thread_local()
elif run_concurrently is None:
run_concurrently = True coord = coordinator.Coordinator(clean_stop_exception_types=(_RequestedStop,)) shared_variable_store = {} # TODO(isaprykin): Create these threads once instead of during every run()
# call.
threads = []
for index, d in enumerate(distribution.worker_devices):
variable_creator_fn = shared_variable_creator.make_fn(
shared_variable_store, index)
t = MirroredStrategy._MirroredTowerThread( # pylint: disable=protected-access
distribution, coord, d, variable_creator_fn, fn,
*values.select_device(d, args), **values.select_device(d, kwargs))
threads.append(t) for t in threads:
t.start()

其中,select_device就是取对应设备key对应的值。完成整个分布式训练。

TensorFlow Distribution(分布式中的数据读取和训练)的更多相关文章

  1. DataTable to Excel(使用NPOI、EPPlus将数据表中的数据读取到excel格式内存中)

    /// <summary> /// DataTable to Excel(将数据表中的数据读取到excel格式内存中) /// </summary> /// <param ...

  2. TensorFlow走过的坑之---数据读取和tf中batch的使用方法

    首先介绍数据读取问题,现在TensorFlow官方推荐的数据读取方法是使用tf.data.Dataset,具体的细节不在这里赘述,看官方文档更清楚,这里主要记录一下官方文档没有提到的坑,以示" ...

  3. oracle中的数据读取与查找

    数据读取 首先数据块读入到Buffer Cache中,并将其放在LRU(Last Recently Used)链表的MRU(Most Recently Used)端,当需要再次访问该块时可以直接从bu ...

  4. c#中使用数据读取器读取查询结果

    今天有时间了. 在看<c#数据库入门经典> ,总结数据读取器查询结果. 针对单个结果集使用读取器,有3中方法: String connString =..; String sql =@&q ...

  5. 如何在ADO中使用数据读取器(DataReader)读取数据

    DbDataReader类型(实现IDataReader接口)是从数据源获取信息最简单也最快速的方法. 数据读取器是只读向前的效据流.井且一次返回一条记录.因此.只有当你向数据源提交 Select 查 ...

  6. 《TensorFlow实战》中AlexNet卷积神经网络的训练中

    TensorFlow实战中AlexNet卷积神经网络的训练 01 出错 TypeError: as_default() missing 1 required positional argument: ...

  7. Android中Json数据读取与创建

    一:  Json的特性和在数据交互中的地位就不用说了,直接看案例. 首先在android studio中创建assets文件目录,用于存放Json数据文件,android studio 1.3 默认项 ...

  8. Android中Json数据读取与创建的方法

    转自:http://www.jb51.net/article/70875.htm 首先介绍下JSON的定义,JSON是JavaScript Object Notation的缩写. 一种轻量级的数据交换 ...

  9. TensorFlow实践笔记(一):数据读取

    本文整理了TensorFlow中的数据读取方法,在TensorFlow中主要有三种方法读取数据: Feeding:由Python提供数据. Preloaded data:预加载数据. Reading ...

随机推荐

  1. Java编程思想,初学者推荐看看

    这是一本介绍Java编程思想,如何从面向过程的编程思想转换为面向对象的编程思想.我个人是比较建议新手看一下的,思想掌握了,学起来自然也就会方便很多的,我还有一些Java基础的数,有需要的可以找我要,都 ...

  2. 【WPF】 InkCanvas 书写毛笔效果

    首先贴出本文参考学习的文章吧. https://www.cnblogs.com/LCHL/p/9055642.html#4206298 感谢这位懒羊羊的代码和讲解(下简称羊博主),我在此基础上稍微加了 ...

  3. poj2909 欧拉素数筛选

    刚刚学了一种新的素数筛选法,效率比原先的要高一些,据说当n趋近于无穷大时这个的时间复杂度趋近O(n).本人水平有限,无法证明. 这是道水题,贴代码出来重点是欧拉筛选法.我把原来普通的筛选法贴出来. / ...

  4. logback使用配置

    一:logback.xml配置内容如下 <?xml version="1.0" encoding="UTF-8"?> <!-- Copyrig ...

  5. 分布式ID系列(3)——数据库自增ID机制适合做分布式ID吗

    数据库自增ID机制原理介绍 在分布式里面,数据库的自增ID机制的主要原理是:数据库自增ID和mysql数据库的replace_into()函数实现的.这里的replace数据库自增ID和mysql数据 ...

  6. LR有的JMeter也有之一“参数化”

    酝酿了几天,一直想写点JMeter的东西,算是对学习东西的一个整理.:) 恩,一直觉得自己领悟能力不强,别人写的东西总要看老半天也不懂.好吧!一惯的傻瓜的方式(大量的截图+参数说明)嘻嘻. 参数化:简 ...

  7. java并发编程(二十二)----(JUC集合)ConcurrentHashMap介绍

    这一节我们来看一下并发的Map,ConcurrentHashMap和ConcurrentSkipListMap.ConcurrentHashMap通常只被看做并发效率更高的Map,用来替换其他线程安全 ...

  8. 一文了解:Redis的AOF持久化

    Redis的AOF持久化 每当Redis-Server接收到写数据时,就把命令以文本形式追加到AOF文件里,当重启Redis服务时,AOF文件里的命令会被重新执行一次,重新恢复数据.当AOF过大时将重 ...

  9. 体验使用MUI上手练习app页面开发

    因为公司安排需要先学习一点app开发,而安排学习的框架就是MUI,上手两天体验还算可以(来自后端人员的懵逼),靠着MUI的快捷键可以快速的完成自己想要的样式模板,更多的交互性的内容则需要使用js来完成 ...

  10. redis高可用之DNS篇

    1.  背景 例如,存在一套redis主从(主从节点在不同的主机上),应用程序通过主库的ip进行读写操作. 但是,主库一旦出现故障,虽然有从库,且从库提升为主库,但是应用程序如果想使用从库则必须修改配 ...