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 fabric实现远程部署
Jan 05 Python
Python 详解基本语法_函数_返回值
Jan 22 Python
利用Python实现Windows下的鼠标键盘模拟的实例代码
Jul 13 Python
python版简单工厂模式
Oct 16 Python
解决Mac下首次安装pycharm无project interpreter的问题
Oct 29 Python
总结python中pass的作用
Feb 27 Python
Python 监测文件是否更新的方法
Jun 10 Python
python3 map函数和filter函数详解
Aug 26 Python
Python+numpy实现矩阵的行列扩展方式
Nov 29 Python
python中return的返回和执行实例
Dec 24 Python
在Python IDLE 下调用anaconda中的库教程
Mar 09 Python
python3通过udp实现组播数据的发送和接收操作
May 05 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
php5数字型字符串加解密代码
2008/04/24 PHP
PHP单链表的实现代码
2016/07/05 PHP
详谈phpAdmin修改密码后拒绝访问的问题
2017/04/03 PHP
jQuery中(function(){})()执行顺序的理解
2013/03/05 Javascript
jQuery用unbind方法去掉hover事件及其他方法介绍
2013/03/18 Javascript
jquery提取元素里的纯文本不包含span等里的内容
2013/09/30 Javascript
javascript日期格式化示例分享
2014/03/05 Javascript
JavaScript代码因逗号不规范导致IE不兼容的问题
2016/02/25 Javascript
AngularJS中一般函数参数传递用法分析
2016/11/22 Javascript
Bootstrap选项卡动态切换效果
2016/11/28 Javascript
在JS中a标签加入单击事件屏蔽href跳转页面
2016/12/16 Javascript
微信小程序中用WebStorm使用LESS
2017/03/08 Javascript
js实现一个简单的数字时钟效果
2017/03/29 Javascript
Angular2环境搭建具体操作步骤(推荐)
2017/08/04 Javascript
浅谈js基础数据类型和引用类型,深浅拷贝问题,以及内存分配问题
2017/09/02 Javascript
用React实现一个完整的TodoList的示例代码
2017/10/30 Javascript
web前端vue之CSS过渡效果示例
2018/01/10 Javascript
angular实现页面打印局部功能的思考与方法
2018/04/13 Javascript
jQuery pager.js 插件动态分页功能实例分析
2019/08/02 jQuery
解决Vue调用springboot接口403跨域问题
2019/09/02 Javascript
修改vue源码实现动态路由缓存的方法
2020/01/21 Javascript
Python实现Windows上气泡提醒效果的方法
2015/06/03 Python
Django rest framework jwt的使用方法详解
2019/08/08 Python
Python telnet登陆功能实现代码
2020/04/16 Python
Python图像处理二值化方法实例汇总
2020/07/24 Python
Django集成MongoDB实现过程解析
2020/12/01 Python
Python+Opencv实现把图片、视频互转的示例
2020/12/17 Python
纯css3实现宠物小鸡实例代码
2018/10/08 HTML / CSS
中专生求职自荐信范文
2013/12/22 职场文书
个人三严三实对照检查材料思想汇报
2014/09/22 职场文书
学生偷窃检讨书
2014/09/25 职场文书
财务部岗位职责范本
2015/04/14 职场文书
担保公司2015年终工作总结
2015/10/14 职场文书
利用Python网络爬虫爬取各大音乐评论的代码
2021/04/13 Python
MySQL 百万级数据的4种查询优化方式
2021/06/07 MySQL
Hive日期格式转换方法总结
2022/06/25 数据库