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每隔N秒运行指定函数的方法
Mar 16 Python
python实现从ftp服务器下载文件的方法
Apr 30 Python
浅谈flask截获所有访问及before/after_request修饰器
Jan 18 Python
PyTorch线性回归和逻辑回归实战示例
May 22 Python
Python3+django2.0+apache2+ubuntu14部署网站上线的方法
Jul 07 Python
Python paramiko 模块浅谈与SSH主要功能模拟解析
Feb 29 Python
Python求两个字符串最长公共子序列代码实例
Mar 05 Python
Python基于gevent实现高并发代码实例
May 15 Python
Python操控mysql批量插入数据的实现方法
Oct 27 Python
django如何自定义manage.py管理命令
Apr 27 Python
python 经纬度求两点距离、三点面积操作
Jun 03 Python
Python Pandas读取Excel日期数据的异常处理方法
Feb 28 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/12/05 PHP
php获取操作系统语言代码
2013/11/04 PHP
ThinkPHP实现批量删除数据的代码实例
2014/07/02 PHP
php通过array_unshift函数添加多个变量到数组前端的方法
2015/03/18 PHP
PHP中大括号'{}'用法实例总结
2017/02/08 PHP
PHP7如何开启Opcode打造强悍性能详解
2018/05/11 PHP
Display SQL Server Login Mode
2007/06/21 Javascript
Bootstrap打造一个左侧折叠菜单的系统模板(一)
2016/05/17 Javascript
jQuery插件实现文件上传功能(支持拖拽)
2020/08/27 Javascript
jQuery+css实现非常漂亮的水平导航菜单效果
2016/07/27 Javascript
浅谈JS使用[ ]来访问对象属性
2016/09/21 Javascript
关于js二维数组和多维数组的定义声明(详解)
2016/10/02 Javascript
JS实现用户注册时获取短信验证码和倒计时功能
2016/10/27 Javascript
实例浅析js的this
2016/12/11 Javascript
JS高级运动实例分析
2016/12/20 Javascript
BootStrap中的Fontawesome 图标
2017/05/25 Javascript
对angularJs中自定义指令replace的属性详解
2018/10/09 Javascript
JS面试题大坑之隐式类型转换实例代码
2018/10/14 Javascript
[25:59]Newbee vs TNC 2018国际邀请赛小组赛BO2 第二场 8.16
2018/08/17 DOTA
Python实现模拟时钟代码推荐
2015/11/08 Python
老生常谈python之鸭子类和多态
2017/06/13 Python
vscode 远程调试python的方法
2017/12/01 Python
django ModelForm修改显示缩略图 imagefield类型的实例
2019/07/28 Python
python实现美团订单推送到测试环境,提供便利操作示例
2019/08/09 Python
Python实现朴素贝叶斯的学习与分类过程解析
2019/08/24 Python
python使用opencv resize图像不进行插值的操作
2020/07/05 Python
Django配置跨域并开发测试接口
2020/11/04 Python
精致的手工皮鞋:Shoe Embassy
2019/11/08 全球购物
Yahoo-PHP面试题2
2014/12/06 面试题
大学生的四年学习自我评价
2013/12/13 职场文书
小学防溺水制度
2014/01/29 职场文书
建筑安全生产目标责任书
2014/07/23 职场文书
投资意向书
2014/07/30 职场文书
2014最新房贷收入证明范本
2014/09/12 职场文书
亮剑精神观后感
2015/06/05 职场文书
JAVA API 实用类 String详解
2021/10/05 Java/Android