Tensorflow实现多GPU并行方式


Posted in Python onFebruary 03, 2020

Tebsorflow开源实现多GPU训练cifar10数据集:cifar10_multi_gpu_train.py

Tensorflow开源实现cifar10神经网络:cifar10.py

Tensorflow中的并行分为模型并行和数据并行。模型并行需要根据不同模型设计不同的并行方式,其主要原理是将模型中不同计算节点放在不同硬件资源上运算。比较通用且能简便地实现大规模并行的方式是数据并行,同时使用多个硬件资源来计算不同batch的数据梯度,然后汇总梯度进行全局更新。

数据并行几乎适用于所有深度学习模型,总是可以利用多块GPU同时训练多个batch数据,运行在每块GPU上的模型都基于同一个神经网络,网络结构一样,并且共享模型参数。

import os
import re
import time
import numpy as np
import tensorflow as tf
import cifar10_input
import cifar10

batch_size = 128
max_steps = 1000
num_gpus = 1 # gpu数量


# 在scope下生成神经网络并返回scope下的loss
def tower_loss(scope):
 # 数据集的路径可以在cifar10.py中的tf.app.flags.DEFINE_string中定义
 images, labels = cifar10.distorted_inputs()
 logits = cifar10.inference(images) # 生成神经网络
 _ = cifar10.loss(logits, labels) # 不直接返回loss而是放到collection
 losses = tf.get_collection('losses', scope) # 获取当前GPU上的loss(通过scope限定范围)
 total_loss = tf.add_n(losses, name='total_loss')
 return total_loss


'''
外层是不同GPU计算的梯度,内层是某个GPU对应的不同var的值
tower_grads = 
[[(grad0_gpu0, var0_gpu0), (grad1_gpu0, var1_gpu0),...],
 [(grad0_gpu1, var0_gpu1), (grad1_gpu1, var1_gpu1),...]]
zip(*tower_grads)= 相当于转置了
[[(grad0_gpu0, var0_gpu0), (grad0_gpu1, var0, gpu1),...],
 [(grad1_gpu0, var1_gpu0), (grad1_gpu1, var1_gpu1),...]]
'''


def average_gradients(tower_grads):
 average_grads = []
 for grad_and_vars in zip(*tower_grads):
  grads = [tf.expand_dims(g, 0) for g, _ in grad_and_vars]
  grads = tf.concat(grads, 0)
  grad = tf.reduce_mean(grads, 0)
  grad_and_var = (grad, grad_and_vars[0][1])
  # [(grad0, var0),(grad1, var1),...]
  average_grads.append(grad_and_var)
 return average_grads


def train():
 # 默认的计算设备为CPU
 with tf.Graph().as_default(), tf.device('/cpu:0'):
  # []表示没有维度,为一个数
  # trainable=False,不会加入GraphKeys.TRAINABLE_VARIABLES参与训练
  global_step = tf.get_variable('global_step', [],
          initializer=tf.constant_initializer(0),
          trainable=False)
  num_batches_per_epoch = cifar10.NUM_EXAMPLES_PER_EPOCH_FOR_TRAIN / batch_size
  decay_steps = int(num_batches_per_epoch * cifar10.NUM_EPOCHS_PER_DECAY)
  # https://tensorflow.google.cn/api_docs/python/tf/train/exponential_decay
  # decayed_learning_rate = learning_rate * decay_rate ^ (global_step / decay_steps)
  # staircase is True, then global_step / decay_steps is an integer division
  lr = tf.train.exponential_decay(cifar10.INITIAL_LEARNING_RATE,
          global_step,
          decay_steps,
          cifar10.LEARNING_RATE_DECAY_FACTOR,
          staircase=True)
  opt = tf.train.GradientDescentOptimizer(lr)

  tower_grads = []
  for i in range(num_gpus):
   with tf.device('/gpu:%d' % i):
    with tf.name_scope('%s_%d' % (cifar10.TOWER_NAME, i)) as scope:
     loss = tower_loss(scope)
     # 让神经网络的变量可以重用,所有GPU使用完全相同的参数
     # 让下一个tower重用参数
     tf.get_variable_scope().reuse_variables()
     grads = opt.compute_gradients(loss)
     tower_grads.append(grads)
  grads = average_gradients(tower_grads)
  apply_gradient_op = opt.apply_gradients(grads, global_step=global_step)

  init = tf.global_variables_initializer()
  # True会自动选择一个存在并且支持的设备来运行
  sess = tf.Session(config=tf.ConfigProto(allow_soft_placement=True))
  sess.run(init)
  tf.train.start_queue_runners(sess=sess)

  for step in range(max_steps):
   start_time = time.time()
   _, loss_value = sess.run([apply_gradient_op, loss])
   duration = time.time() - start_time

   if step % 10 == 0:
    num_examples_per_step = batch_size * num_gpus
    examples_per_sec = num_examples_per_step / duration
    sec_per_batch = duration / num_gpus

    print('step %d, loss=%.2f(%.1f examples/sec;%.3f sec/batch)'
      % (step, loss_value, examples_per_sec, sec_per_batch))



if __name__ == '__main__':
 train()

以上这篇Tensorflow实现多GPU并行方式就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python访问系统环境变量的方法
Apr 29 Python
python从入门到精通(DAY 1)
Dec 20 Python
全面了解python字符串和字典
Jul 07 Python
详解Python的collections模块中的deque双端队列结构
Jul 07 Python
flask使用session保存登录状态及拦截未登录请求代码
Jan 19 Python
Python OpenCV处理图像之图像直方图和反向投影
Jul 10 Python
Python自动化之数据驱动让你的脚本简洁10倍【推荐】
Jun 04 Python
pyinstaller还原python代码过程图解
Jan 08 Python
Python+PyQt5+MySQL实现天气管理系统
Jun 16 Python
python批量生成条形码的示例
Oct 10 Python
利用python查看数组中的所有元素是否相同
Jan 08 Python
Python进阶学习之带你探寻Python类的鼻祖-元类
May 08 Python
python如何通过twisted搭建socket服务
Feb 03 #Python
关于Tensorflow分布式并行策略
Feb 03 #Python
基于python修改srt字幕的时间轴
Feb 03 #Python
Python实现不规则图形填充的思路
Feb 02 #Python
Python ORM编程基础示例
Feb 02 #Python
Python 面向对象之类class和对象基本用法示例
Feb 02 #Python
flask 框架操作MySQL数据库简单示例
Feb 02 #Python
You might like
如何将数据从文本导入到mysql
2006/10/09 PHP
用PHP实现的四则运算表达式计算实现代码
2011/08/02 PHP
PHP imagegrabscreen和imagegrabwindow(截取网站缩略图)的实例代码
2013/11/07 PHP
php+mysqli使用面向对象方式更新数据库实例
2015/01/29 PHP
PHP+sqlite数据库操作示例(创建/打开/插入/检索)
2016/05/26 PHP
phpmailer简单发送邮件的方法(附phpmailer源码下载)
2016/06/13 PHP
tp5框架内使用tp3.2分页的方法分析
2019/05/05 PHP
PHP命名空间与自动加载机制的基础介绍
2019/08/25 PHP
PHP实现简单的协程任务调度demo示例
2020/02/01 PHP
php判断数组是否为空的实例方法
2020/05/10 PHP
基于jquery的Repeater实现代码
2010/07/17 Javascript
jquery选择器的选择使用及性能介绍
2013/01/16 Javascript
javascript中typeof操作符和constucor属性检测
2015/02/26 Javascript
JS中生成随机数的用法及相关函数
2016/01/09 Javascript
浅谈Javascript数组(推荐)
2016/05/17 Javascript
jQuery轮播图效果精简版完整示例
2016/09/04 Javascript
Bootstrap3 datetimepicker控件使用实例
2016/12/13 Javascript
图文详解Javascript中的上下文和作用域
2017/02/15 Javascript
微信小程序如何获知用户运行小程序的场景教程
2017/05/17 Javascript
详解Node.js利用node-git-server快速搭建git服务器
2017/09/27 Javascript
node.js基于express使用websocket的方法
2017/11/09 Javascript
微信小程序实现简单input正则表达式验证功能示例
2017/11/30 Javascript
浅谈Angular HttpClient简单入门
2018/05/04 Javascript
Node.js实现简单管理系统
2019/09/23 Javascript
jquery更改元素属性attr()方法操作示例
2020/05/22 jQuery
Python中给List添加元素的4种方法分享
2014/11/28 Python
Python 3.x 新特性及10大变化
2015/06/12 Python
CentOS6.5设置Django开发环境
2016/10/13 Python
关于pip的安装,更新,卸载模块以及使用方法(详解)
2017/05/19 Python
Python中elasticsearch插入和更新数据的实现方法
2018/04/01 Python
matplotlib绘制多个子图(subplot)的方法
2019/12/03 Python
基于python实现简单网页服务器代码实例
2020/09/14 Python
加拿大领先的时尚和体育零售商:Sporting Life
2019/12/15 全球购物
2014年五四青年节活动策划书
2014/04/22 职场文书
预备党员转正思想汇报
2014/09/26 职场文书
储备店长岗位职责
2015/04/14 职场文书