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实现批量更换指定目录下文件扩展名的方法
Sep 19 Python
Django模板变量如何传递给外部js调用的方法小结
Jul 24 Python
python实现多线程行情抓取工具的方法
Feb 28 Python
使用 Python 实现简单的 switch/case 语句的方法
Sep 17 Python
浅谈python中str字符串和unicode对象字符串的拼接问题
Dec 04 Python
python抖音表白程序源代码
Apr 07 Python
使用coverage统计python web项目代码覆盖率的方法详解
Aug 05 Python
Python实现Singleton模式的方式详解
Aug 08 Python
python数组循环处理方法
Aug 26 Python
Python GUI自动化实现绕过验证码登录
Jan 10 Python
python实现不同数据库间数据同步功能
Feb 25 Python
pytorch 中autograd.grad()函数的用法说明
May 12 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
php数据库连接
2006/10/09 PHP
解析web文件操作常见安全漏洞(目录、文件名检测漏洞)
2013/06/29 PHP
ThinkPHP的Widget扩展实例
2014/06/19 PHP
Laravel5.1 框架控制器基础用法实例分析
2020/01/04 PHP
JavaScript语法着色引擎(demo及打包文件下载)
2007/06/13 Javascript
利用onresize使得div可以随着屏幕大小而自适应的代码
2010/01/15 Javascript
利用Javascript判断操作系统的类型实现不同操作系统下的兼容性
2013/01/29 Javascript
jquery如何判断某元素是否具备指定的样式
2013/11/05 Javascript
JavaScript组合模式学习要点
2016/08/26 Javascript
nodejs个人博客开发第七步 后台登陆
2017/04/12 NodeJs
Vue学习之路之登录注册实例代码
2017/07/06 Javascript
React-Native 组件之 Modal的使用详解
2017/08/08 Javascript
Vue2.0 实现单选互斥的方法
2018/04/13 Javascript
JavaScript设计模式之工厂模式和抽象工厂模式定义与用法分析
2018/07/26 Javascript
vue生命周期实例小结
2018/08/15 Javascript
深入理解移动前端开发之viewport
2018/10/19 Javascript
微信小程序时间轴实现方法示例
2019/01/14 Javascript
Django+vue跨域问题解决的详细步骤
2019/01/20 Javascript
Python多进程编程技术实例分析
2014/09/16 Python
在Python 3中实现类型检查器的简单方法
2015/07/03 Python
python 内置函数filter
2017/06/01 Python
Python使用微信SDK实现的微信支付功能示例
2017/06/30 Python
用python实现的线程池实例代码
2018/01/06 Python
python内置数据类型之列表操作
2018/11/12 Python
Python计算库numpy进行方差/标准方差/样本标准方差/协方差的计算
2018/12/28 Python
详解Python3序列赋值、序列解包
2019/05/14 Python
pyQT5 实现窗体之间传值的示例
2019/06/20 Python
python使用writerows写csv文件产生多余空行的处理方法
2019/08/01 Python
python+requests接口自动化框架的实现
2020/08/31 Python
加拿大当代时尚服饰、配饰和鞋类专业零售商和制造商:LE CHÂTEAU
2017/10/06 全球购物
网上书店创业计划书
2014/01/12 职场文书
报纸媒体创意广告词
2014/03/17 职场文书
幼师大班个人总结
2015/02/13 职场文书
前台接待岗位职责范本
2015/04/03 职场文书
Docker官方工具docker-registry案例演示
2022/04/13 Servers
Spring Boot 实现 WebSocket
2022/04/30 Java/Android